IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

h�ritage, template et g�n�rateur de code.


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Expert �minent

    Femme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    D�tails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par d�faut h�ritage, template et g�n�rateur de code.
    Boujour � tous

    Je me retrouve avec un probl�me quelque peu tordu.
    Dans mon �quipe, nous avons un g�n�rateur de code, qui prend une description de format de fichiers CSV en entr�e.

    L'id�e, c'est d'abbr�ger fortement le temps d'�criture des validations des donn�es, tout en offrant assez de souplesse � l'usage.
    L'une de mes contraintes, c'est que ni C++11 ni Boost ne sont autoris�s (j'ai d� r�cup�rer optional lite pour avoir un optional correct)

    Le code g�n�r� devrait ressembler � ceci:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    class Bidule {
    public:
       typedef types::string::value_type champ1_type;
       typedef types::optional_integer::value_type champ2_type;
    private:
       champ1_type champ1;
       champ2_type champ2;
    public:
       Bidule(champ1_type const& champ1, champ2_type const& champ2) : 
          champ1(champ1),
          champ2(champ2)
       {}
     
       champ1_type const& getChamp1() const {return champ1;}
       champ1_type      & getChamp1() {return champ1;}
     
       champ2_type const& getChamp2() const {return champ2;}
       champ2_type      & getChamp2() {return champ2;}
    };
     
    class Bidule_format {
    private:
       types::string  champ1;
       types::decimal champ2;
    public:
    //les constructeurs des types permettent les réglages de validations en lecture et écriture
       Bidule_format() : champ1(8), champ2(4) {}
     
       //produce a value from internal state
       Bidule operator()() const { return Bidule( champ1(), champ2() ); }
     
       Bidule_format& clear() {
          champ1.clear();
          champ2.clear();
          return *this;
       }
     
       //set internal state according to value, and return itself
       Bidule_format & operator()(Bidule const& source) {
          champ1(source.getChamp1());
          champ2(source.getChamp2());
          return *this;
       }
     
       Bidule_format & from(std::istream& stream) {
          stream >> champ1 >> champ2;
          return *this;
       }
       Bidule_format const& into(std::ostream& stream) const {
          stream << champ1 << champ2;
          return *this;
       }
    };
    Au passage, j'aimerai bien trouver un moyen d'�crire de partager la d�finition de type entre Bidule et Bidule_format...
    sauf que la pr�d�claration de Bidule n'est pas suffisante pour Bidule_format::operator()(), et que Bidule utiliserait Bidule_format::champ1_type::value_type


    Il s'agit donc d'�crire dans une biblioth�que tout le code qui ne changerait pas d'une description � l'autre.
    Et c'est l� que mes soucis commencent.

    J'ai une classe extractor qui me sert de base pour les diff�rents types.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    class extractor_base {
    public:
       virtual ~extractor() {}
     
       virtual void from(std::istream & stream) = 0;
       virtual void into(std::ostream & stream) const = 0;
       virtual void clear() =0;
    };
     
    inline std::istream& operator>> (std::istream& stream, extractor_base & extractor) {
       extractor.from(stream);
       return stream;
    }
     
    inline std::ostream& operator<<(std::ostream& stream, extractor_base const & extractor) {
       extractor.into(stream);
       return stream;
    }
     
    template <typename T, bool optional = false>
    class extractor : public extractor_base{
    public:
       typedef T concrete_type;
       typedef typename option_type<T, optional>::value_type value_type;//std::optional<T> ou T, selon que optional soit vrai ou non
    private:
       value_type v;   
    protected:
       explicit extractor() {}
       explicit extractor(value_type const& v) : v(v) {}
    public:
       virtual ~extractor() {}
     
       value_type const& operator() () const {return v;}
       value_type      & operator() ()       {return v;}
     
       void operator() (value_type const& value) {v = value;}
     
       virtual void clear() {v=value_type();}
    };
    types::integer, types::optional_string, etc sont h�riti�res de extractor.

    Sauf que j'ai deux mutualisations possibles, que je n'arrive pas � �crire correctement:
    D'un cot�, integer et optional_integer ont le m�me format.
    De l'autre, les optional ont la m�me interaction avec les flux, et les autres types en partage une autre

    Typiquement, je peux �crire
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    template <typename Value>
    class strict_type : public extractor<Value, false> {
    public:
       virtual void from(std::istream & stream) {
          set(extract(next(stream)));
       }
     
       virtual void into(std::ostream & stream) const {
          stream << format(get()) << delimiter();
       }
    };
     
    template <typename Value>
    class optional_type : public extractor<Value, true> {
    public:
       virtual void from(std::istream & stream) {
          std::string token = next(stream);
          if (empty(token)) {
             set(optional::none);
          } else {
             set(extract(token));
          }
       }
     
       virtual void into(std::ostream & stream) const {
          if (get()) {
             stream << format(*get());
          }
          stream << delimiter();
       }
    };
    Sauf que la dedans, format() et extract() sont li�es au types (les memes fonctions pour integer et optional_integer)

    Et c'est la que je suis un peu perdu.
    Comment continueriez-vous cette architecture?

    J'ai au moins une contrainte sur le choix: scientific et decimal sont deux types ayant des formats diff�rents, mais utilisant double comme type concret.
    C'est ce qui m'a pouss� jusque l� � ne pas partir sur des sp�cialisations.

    Je peux faire pas mal de chaos la dedans, les fonctions de formatage sont des fonctions libres (r�cup�r�es pour le moment).

  2. #2
    Expert �minent

    Femme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    D�tails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par d�faut
    Visiblement, ma question ne vous inspire pas trop

    J'ai trouv� une solution � mes questions:
    Il "suffit" de passer par des classes interm�diaires.
    Ici, j'ai pris optional<Format> et required<Format>. Elles contiennent un champ du type du format, sont des extracteurs.
    Ainsi, mon optional_integer est devenu un typedef de optional<integer>.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    template <typename T, bool optional = false>
    class extractor {
    public:
       typedef T concrete_type;
       typedef typename option_type<T, optional>::value_type value_type;
    private:
       value_type v;   
    protected:
       explicit extractor() {}
       explicit extractor(value_type const& value) : v(value) {}
    public:
       virtual ~extractor() {}
     
       virtual void from(std::istream & stream) = 0;
       virtual void into(std::ostream & stream) const = 0;
     
       value_type const& operator() () const {return v;}
       value_type      & operator() ()       {return v;}
     
       value_type const& get() const {return v;}
       void set() (value_type const& value) {v = value;}
     
       virtual void clear() {v=value_type();}
    };
     
    //sets the internal value of the extractor.
    template <typename T, bool optional>
    inline std::istream& operator>> (std::istream& stream, extractor<T, optional> & extractor) {
       extractor.from(stream);
       return stream;
    }
     
    //outputs the internal value of the extractor.
    template <typename T, bool optional>
    inline std::ostream& operator<<(std::ostream& stream, extractor<T, optional> const & extractor) {
       extractor.into(stream);
       return stream;
    }
     
    template<typename Format>
    class required : public extractor<typename Format::type, false> {
    private:
       Format format;
    public:
       required(Format const& format) : extractor(), format(format) {}
     
       virtual void from(std::istream & stream) {
          set( format.extract(next(stream)) );
       }
     
       virtual void into(std::ostream & stream) const {
          stream << format.format(get()) << delimiter();
       }
    };
     
    template<typename Format>
    class optional : public extractor<typename Format::value_type, true> {
    private:
       Format format;
    public:
       optional(Format const& format) : extractor(), format(format) {}
     
       virtual void from(std::istream & stream) {
          std::string token;
          std::getline(stream, token, ';');
          if (my::empty(token)) {
             set(nonstd::nullopt());
          } else {
             set(format.extract(token));
          }
       }
     
       virtual void into(std::ostream & stream) const {
          if (get()) {
             stream << format.format(*get());
          }
       }
    };
     
    class integer {
    public:
       typedef long value_type;
       typedef std::string::size_type size_type;
     
    private:
       size_type digits;
     
    public:
       integer(size_type digits) : digits(digits) {}
     
       std::string format(value_type valeur) const { ...  }
       value_type extract(std::string const& token) const { ... }
    };
    Il me reste toujours ma question au passage, mais le sujet principal est clos.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [andromda]Infos sur andromda, g�n�rateur de code JAVA
    Par ugos dans le forum EDI et Outils pour Java
    R�ponses: 5
    Dernier message: 08/09/2009, 15h30
  2. [Sunopsis] et les ETL g�n�rateur de code ?
    Par manuaccess10 dans le forum ODI (ex-Sunopsis)
    R�ponses: 5
    Dernier message: 20/12/2006, 12h54
  3. G�n�rateur de code
    Par jojo. dans le forum Mode d'emploi & aide aux nouveaux
    R�ponses: 1
    Dernier message: 21/04/2006, 10h24
  4. R�ponses: 4
    Dernier message: 21/02/2006, 19h45
  5. [Info][API]G�n�rateur de code
    Par Archangelo dans le forum API standards et tierces
    R�ponses: 6
    Dernier message: 24/07/2005, 14h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo