C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

H.S. Idée pour créer une sorte de "pont" entre deux interfac

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Stephane Wirtel
Guest





PostPosted: Tue Jan 17, 2006 1:20 pm    Post subject: H.S. Idée pour créer une sorte de "pont" entre deux interfac Reply with quote



Bonjour,

J'ai une idée afin de pouvoir me simplifier un peu la vie avec Borland C++
Builder.

Pour ceux qui emploit cet outil, il y a une TList qui fait office de list
d'éléments.
Le soucis est qu'elle ne possède pas une interface qui me permettrait de
l'utiliser
avec les algorithmes de la STL.

Donc en gros, comment pourrais-je rajouter les iterator à une TList ?

Voici ce que cela me permettrait de faire.

TList *list (new TList ());

std::copy (
list->begin (),
list->end (),
std::ostream_iterator< SUPER_TYPE > (std::cout, " "));


Merci,

Stéphane
Back to top
kanze
Guest





PostPosted: Tue Jan 17, 2006 4:23 pm    Post subject: Re: H.S. Idée pour créer une sorte de "pont" entre deux inte Reply with quote



Stephane Wirtel wrote:

Quote:
J'ai une idée afin de pouvoir me simplifier un peu la vie avec
Borland C++ Builder.

Ou n'importe quelle bibliothèque un peu ancienne. (J'ai
rencontré un problème semblable avec XViews.)

Quote:
Pour ceux qui emploit cet outil, il y a une TList qui fait
office de list d'éléments. Le soucis est qu'elle ne possède
pas une interface qui me permettrait de l'utiliser avec les
algorithmes de la STL.

Donc en gros, comment pourrais-je rajouter les iterator à une
TList ?

Le modèle fassade. Je ne connais pas TList, mais j'imagine qu'il
offre un itérateur classique. Je connais deux solutions
possible : une fassade sur la classe même (qui peut être utile
dans certains cas) et une fassade sur son itérateur.

Pour la fassade sur l'itérateur, boost::iterator doit aider
beaucoup. En fait, ce que je fais sur l'itérateur, ce n'est pas
une vraie fassade, parce que les itérateurs doivent avoir une
sémantique de valeur, ce qui n'est pas le cas d'une vraie
fassade. Mais il revient à peu près au même : mon itérateur STL
contient l'itératuer du TList. (Attention quand même : si
l'itérateur classique n'a pas une sémantique de valeur, il va
falloir que tu lui force une copie profonde.)

Quote:
Voici ce que cela me permettrait de faire.

TList *list (new TList ());

std::copy (
list->begin (),
list->end (),
std::ostream_iterator< SUPER_TYPE > (std::cout, " "));

Ça serait :

std::copy( TListIterator( list ),
TListIterator(),
std::ostream_iterator< ... >( std::cout, " " ) ) ;

Voir Boost::iterator.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Back to top
Stephane Wirtel
Guest





PostPosted: Wed Jan 18, 2006 8:16 am    Post subject: Re: H.S. Idée pour créer une sorte de "pont" entre deux inte Reply with quote



kanze said the following on 17/01/2006 17:23:
Quote:
Pour ceux qui emploit cet outil, il y a une TList qui fait
office de list d'éléments. Le soucis est qu'elle ne possède
pas une interface qui me permettrait de l'utiliser avec les
algorithmes de la STL.

Donc en gros, comment pourrais-je rajouter les iterator à une
TList ?

Le modèle fassade. Je ne connais pas TList, mais j'imagine qu'il
offre un itérateur classique. Je connais deux solutions
possible : une fassade sur la classe même (qui peut être utile
dans certains cas) et une fassade sur son itérateur.
Non, elle ne propose pas d'interface permettant d'utiliser directement un

itérateur classique.

Elle contient une méthode First() et Last(), par contre la collection
qui est encapsulée dans cette classe contient une surcharge de l'opérateur[]
pour avoir un 'pseudo' accès direct.

Quote:
Pour la fassade sur l'itérateur, boost::iterator doit aider
beaucoup. En fait, ce que je fais sur l'itérateur, ce n'est pas
une vraie fassade, parce que les itérateurs doivent avoir une
sémantique de valeur, ce qui n'est pas le cas d'une vraie
fassade. Mais il revient à peu près au même : mon itérateur STL
contient l'itératuer du TList. (Attention quand même : si
l'itérateur classique n'a pas une sémantique de valeur, il va
falloir que tu lui force une copie profonde.)

Voici ce que cela me permettrait de faire.

TList *list (new TList ());

std::copy (
list->begin (),
list->end (),
std::ostream_iterator< SUPER_TYPE > (std::cout, " "));

Ça serait :

std::copy( TListIterator( list ),
TListIterator(),
std::ostream_iterator< ... >( std::cout, " " ) ) ;

De quelle manière std::copy saurait-il que le second argument
'TListIterator()' représente end () ?

Quote:
Voir Boost::iterator.
Merci, je vais aller regarder tout de suite.


En fait d'après les tests d'un collègue, celui-ci a constaté que
l'implémentation TList
de Borland était presque 6 fois plus lente que l'implémentation de la STL.

Le pattern Façade semble intéressant après discuter avec mon collègue.

Encore Merci,

Stéphane

Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Jan 18, 2006 9:48 am    Post subject: Re: H.S. Idée pour créer une sorte de "pont" entre deux inte Reply with quote

On Wed, 18 Jan 2006 09:16:04 +0100, Stephane Wirtel
<com.descasoft (AT) wirtel (DOT) stephane>:

Quote:
celui-ci a constaté que
l'implémentation TList
de Borland était presque 6 fois plus lente que l'implémentation de la STL.

Si elle offre un opérateur [], c'est normal : un [] rapide est
incompatible avec une liste chaînée.


Back to top
loic.actarus.joly@numeric
Guest





PostPosted: Wed Jan 18, 2006 8:35 pm    Post subject: Re: H.S. Idée pour créer une sorte de "pont" entre deux inte Reply with quote


kanze a écrit :

Quote:
Ça serait :

std::copy( TListIterator( list ),
TListIterator(),
std::ostream_iterator< ... >( std::cout, " " ) ) ;

Tu utilises là une syntaxe proche des stream_iterator. Une autre
syntaxe me semble possible, semblable à ce qui peut être fait pour
des tableaux natifs :

std::copy( begin( list ),
end(list),
std::ostream_iterator< ... >( std::cout, " " ) ) ;

--
Loïc


Back to top
Stephane Wirtel
Guest





PostPosted: Thu Jan 19, 2006 8:09 am    Post subject: Re: H.S. Idée pour créer une sorte de "pont" entre deux inte Reply with quote

Fabien LE LEZ said the following on 18/01/2006 10:48:
Quote:
On Wed, 18 Jan 2006 09:16:04 +0100, Stephane Wirtel
[email]com.descasoft (AT) wirtel (DOT) step[/email]hane>:

celui-ci a constaté que
l'implémentation TList
de Borland était presque 6 fois plus lente que l'implémentation de la STL.

Si elle offre un opérateur [], c'est normal : un [] rapide est
incompatible avec une liste chaînée.

Justement, c'est pour cela que j'aimerais régler le problème.


A la fin, j'ai créé une classe qui hérite de std::deque et qui encapsule une
TList
et qui fait une copie du pointeur dans un std::deque.

De cette manière, je profite d'une collection de la STL.

En gros, le code donne ceci.

struct NotOwner {
template< typename T> void operator () (T ptr) {
}
};

struct Owner {
template< typename T > void operator () (T ptr) {
delete ptr;
ptr = 0;
}
};

template <
typename ParamType,
typename Policy = NotOwner >
class DsList :
public std::deque< ParamType >
{
public:
DsList (TList *pList = 0);
TList *transformToTList () throw (Exception, std::exception);
virtual void clear ();
virtual ~DsList ();

private:
template< typename Param_FirstType, typename Param_SecondType > static
bool Compare () {
return (typeid (Param_FirstType) == typeid (Param_SecondType));
};

TList *mList;
};


template< typename ParamType, typename Policy >
DsList< ParamType, Policy >::DsList (TList *pList)
: mList (pList)
{
if (pList != 0) {
for (unsigned long int i = 0, count = pList->Count; i < count; ++i) {
this->push_back (static_cast< ParamType > (pList->Items[i]));
}
}
}

template< typename ParamType, typename Policy >
TList * DsList< ParamType, Policy >::transformToTList ()
throw (Exception, std::exception)
{
std::auto_ptr< TList > tlist (new TList ());
for (DsList< ParamType > :: const_iterator it = this->begin (); it !=
this->end (); ++it) {
tlist->Add (*it);
}
return tlist.release ();
}

/**
* Efface le contenu de la std::deque.
* Si la policy concernant le propriétaire du contenu est 'Owner',
* libération des ressources mémoires complètes.
*/
template< typename ParamType, typename Policy >
void DsList<ParamType, Policy>::clear ()
{
if (Compare<Policy, Owner> () == true) {
std::for_each (this->begin (), this->end (), Policy ());
mList->Clear ();
}
std::deque< ParamType >::clear ();
}

/**
* Destructeur de DsList.
*/
template< typename ParamType, typename Policy >
DsList<ParamType, Policy>::~DsList ()
{
if (Compare<Policy, Owner> () == true) {
std::for_each (this->begin (), this->end (), Policy ());
mList->Clear ();
}
}


Et son utilisation se fait de cette manière.
struct StructForTest {
AnsiString first_field;
int second_field;
StructForTest (AnsiString pFirstField = "", int pSecondField = 0) throw
(Exception)
: first_field (pFirstField), second_field (pSecondField)
{
}
friend std::ostream & operator << (std::ostream &outStream, const
StructForTest &pTest);
};

std::ostream & operator << (std::ostream &outStream, const StructForTest &pTest) {
outStream
<< "First Field : " << pTest.first_field.c_str () << std::endl
<< "Second Field : " << pTest.second_field << std::endl;
return outStream;
}

int main(int argc, char* argv[])
{
std::auto_ptr< TList > borlandList;
try {
borlandList.reset (new TList ());
borlandList->Add (new StructForTest ("Toto", 0));
borlandList->Add (new StructForTest ("Stef", 1));
std::cout << borlandList->Count << std::endl;

{
/// ce bloc a été créé pouvoir si la destruction de la DsList
/// libérait bien la mémoire de la TList.

DsList< StructForTest *, Owner > list (borlandList.get ());
DsList< StructForTest *, Owner > :: const_iterator it;
for ( it = list.begin (); it != list.end (); ++it) {
std::cout << **it << std::endl;
}
}
std::cout << borlandList->Count << std::endl;

}
catch (const Exception &pException) {
std::cerr << "Exception : " << pException.Message << std::endl;
}
catch (const std::exception &pException) {
std::cerr << "Exception : " << pException.what () << std::endl;
}
catch (...) {
std::cerr << "Exception : Inconnue" << std::endl;
}
std::cin.get ();
return 0;
}



Qu'en pensez-vous ?
Je suis à l'écoute de toutes remarques et conseils, ceci afin de m'améliorer.

Merci de votre aide,

Stéphane

Back to top
kanze
Guest





PostPosted: Thu Jan 19, 2006 9:11 am    Post subject: Re: H.S. Idée pour créer une sorte de "pont" entre deux inte Reply with quote

[email]loic.actarus.joly (AT) numericable (DOT) fr[/email] wrote:
Quote:
kanze a écrit :

Ça serait :

std::copy( TListIterator( list ),
TListIterator(),
std::ostream_iterator< ... >( std::cout, " " ) ) ;

Tu utilises là une syntaxe proche des stream_iterator.

Ce n'est pas une question de syntaxe, mais de semantique.

Quote:
Une autre syntaxe me semble possible, semblable à ce qui peut
être fait pour des tableaux natifs :

std::copy( begin( list ),
end(list),
std::ostream_iterator< ... >( std::cout, " " ) ) ;

Le problème, c'est, donné un itérateur classique, comment
implémenter le == dont la STL a besoin.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Back to top
Loïc Joly
Guest





PostPosted: Thu Jan 19, 2006 8:08 pm    Post subject: Re: H.S. Idée pour créer une sorte de "pont" entre deux inte Reply with quote

kanze a écrit :
Quote:
loic.actarus.joly (AT) numericable (DOT) fr wrote:

Une autre syntaxe me semble possible, semblable à ce qui peut
être fait pour des tableaux natifs :


std::copy( begin( list ),
end(list),
std::ostream_iterator< ... >( std::cout, " " ) ) ;


Le problème, c'est, donné un itérateur classique, comment
implémenter le == dont la STL a besoin.

Excuse moi, je ne vois pas trop de quoi tu parles. Tu peux expliciter ?

--
Loïc

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.