lemon/bits/variant.h
changeset 2346 c06a956a92fa
parent 2177 416a7030b7e3
child 2386 81b47fc5c444
equal deleted inserted replaced
0:91a645748685 1:cc2a75c2e98d
    19 #ifndef LEMON_BITS_VARIANT_H
    19 #ifndef LEMON_BITS_VARIANT_H
    20 #define LEMON_BITS_VARIANT_H
    20 #define LEMON_BITS_VARIANT_H
    21 
    21 
    22 #include <lemon/error.h>
    22 #include <lemon/error.h>
    23 
    23 
       
    24 /// \file
       
    25 /// \brief Variant types
       
    26 
    24 namespace lemon {
    27 namespace lemon {
    25 
    28 
    26   template <bool left, bool right>
    29   namespace _variant_bits {
    27   struct CTOr {
       
    28     static const bool value = true;
       
    29   };
       
    30 
       
    31   template <>
       
    32   struct CTOr<false, false> {
       
    33     static const bool value = false;
       
    34   };
       
    35 
       
    36   template <bool left, bool right>
       
    37   struct CTAnd {
       
    38     static const bool value = false;
       
    39   };
       
    40 
       
    41   template <>
       
    42   struct CTAnd<true, true> {
       
    43     static const bool value = true;
       
    44   };
       
    45 
       
    46   template <int left, int right>
       
    47   struct CTEqual {
       
    48     static const bool value = false;
       
    49   };
       
    50 
       
    51   template <int val>
       
    52   struct CTEqual<val, val> {
       
    53     static const bool value = true;
       
    54   };
       
    55 
       
    56 
       
    57   template <int left, int right>
       
    58   struct CTLess {
       
    59     static const bool value = left < right;
       
    60   };
       
    61 
       
    62   template <int left>
       
    63   struct CTLess<left, 0> {
       
    64     static const bool value = false;
       
    65   };
       
    66 
       
    67   template <int right>
       
    68   struct CTLess<0, right> {
       
    69     static const bool value = true;
       
    70   };
       
    71 
       
    72   template <>
       
    73   struct CTLess<0, 0> {
       
    74     static const bool value = false;
       
    75   };
       
    76 
       
    77   template <>
       
    78   struct CTLess<1, 1> {
       
    79     static const bool value = false;
       
    80   };
       
    81 
       
    82   template <bool less, int left, int right>
       
    83   struct CTMaxImpl {
       
    84     static const int value = left;    
       
    85   };
       
    86 
       
    87   template <int left, int right>
       
    88   struct CTMaxImpl<true, left, right> {
       
    89     static const int value = right;
       
    90   };
       
    91   
    30   
    92   template <int left, int right>
    31     template <int left, int right>
    93   struct CTMax {
    32     struct CTMax {
    94     static const int value = 
    33       static const int value = left < right ? right : left;
    95     CTMaxImpl<CTLess<left, right>::value, left, right>::value;
    34     };
    96   };
    35 
    97 
    36   }
    98 
    37 
    99   /// \brief Simple Variant type with two type
    38 
       
    39   /// \brief Simple Variant type for two types
   100   ///
    40   ///
   101   /// Simple Variant type with two type
    41   /// Simple Variant type for two types. The Variant type is a type
       
    42   /// safe union. The C++ has strong limitations for using unions, by
       
    43   /// example we can not store type with non default constructor or
       
    44   /// destructor in an union. This class always knowns the current
       
    45   /// state of the variant and it cares for the proper construction
       
    46   /// and destruction.
   102   template <typename _First, typename _Second>
    47   template <typename _First, typename _Second>
   103   class BiVariant {
    48   class BiVariant {
   104   public:
    49   public:
   105 
    50 
       
    51     /// \brief The \c First type.
   106     typedef _First First;
    52     typedef _First First;
       
    53     /// \brief The \c Second type.
   107     typedef _Second Second;
    54     typedef _Second Second;
   108 
    55 
   109     struct WrongStateError : public lemon::LogicError {
    56     struct WrongStateError : public lemon::LogicError {
   110     public:
    57     public:
   111       virtual const char* what() const throw() {
    58       virtual const char* what() const throw() {
   112         return "lemon::BiVariant::WrongStateError";
    59         return "lemon::BiVariant::WrongStateError";
   113       }
    60       }
   114     };
    61     };
   115 
    62 
       
    63     /// \brief Constructor
       
    64     ///
       
    65     /// This constructor initalizes to the default value of the \c First
       
    66     /// type.
   116     BiVariant() {
    67     BiVariant() {
   117       flag = true;
    68       flag = true;
   118       new(reinterpret_cast<First*>(data)) First();
    69       new(reinterpret_cast<First*>(data)) First();
   119     }
    70     }
   120 
    71 
       
    72     /// \brief Constructor
       
    73     ///
       
    74     /// This constructor initalizes to the given value of the \c First
       
    75     /// type.
   121     BiVariant(const First& first) {
    76     BiVariant(const First& first) {
   122       flag = true;
    77       flag = true;
   123       new(reinterpret_cast<First*>(data)) First(first);
    78       new(reinterpret_cast<First*>(data)) First(first);
   124     }
    79     }
   125 
    80 
       
    81     /// \brief Constructor
       
    82     ///
       
    83     /// This constructor initalizes to the given value of the \c
       
    84     /// Second type.
   126     BiVariant(const Second& second) {
    85     BiVariant(const Second& second) {
   127       flag = false;
    86       flag = false;
   128       new(reinterpret_cast<Second*>(data)) Second(second);
    87       new(reinterpret_cast<Second*>(data)) Second(second);
   129     }
    88     }
   130 
    89 
       
    90     /// \brief Copy constructor
       
    91     ///
       
    92     /// Copy constructor
   131     BiVariant(const BiVariant& bivariant) {
    93     BiVariant(const BiVariant& bivariant) {
   132       flag = bivariant.flag;
    94       flag = bivariant.flag;
   133       if (flag) {
    95       if (flag) {
   134         new(reinterpret_cast<First*>(data)) First(bivariant.first());      
    96         new(reinterpret_cast<First*>(data)) First(bivariant.first());      
   135       } else {
    97       } else {
   136         new(reinterpret_cast<Second*>(data)) Second(bivariant.second());      
    98         new(reinterpret_cast<Second*>(data)) Second(bivariant.second());      
   137       }
    99       }
   138     }
   100     }
   139 
   101 
       
   102     /// \brief Destrcutor
       
   103     ///
       
   104     /// Destructor
   140     ~BiVariant() {
   105     ~BiVariant() {
   141       destroy();
   106       destroy();
   142     }
   107     }
   143 
   108 
       
   109     /// \brief Set to the default value of the \c First type.
       
   110     ///
       
   111     /// This function sets the variant to the default value of the \c
       
   112     /// First type.
   144     BiVariant& setFirst() {
   113     BiVariant& setFirst() {
   145       destroy();
   114       destroy();
   146       flag = true;
   115       flag = true;
   147       new(reinterpret_cast<First*>(data)) First();   
   116       new(reinterpret_cast<First*>(data)) First();   
   148       return *this;
   117       return *this;
   149     }
   118     }
   150 
   119 
       
   120     /// \brief Set to the given value of the \c First type.
       
   121     ///
       
   122     /// This function sets the variant to the given value of the \c
       
   123     /// First type.
   151     BiVariant& setFirst(const First& first) {
   124     BiVariant& setFirst(const First& first) {
   152       destroy();
   125       destroy();
   153       flag = true;
   126       flag = true;
   154       new(reinterpret_cast<First*>(data)) First(first);   
   127       new(reinterpret_cast<First*>(data)) First(first);   
   155       return *this;
   128       return *this;
   156     }
   129     }
   157 
   130 
       
   131     /// \brief Set to the default value of the \c Second type.
       
   132     ///
       
   133     /// This function sets the variant to the default value of the \c
       
   134     /// Second type.
   158     BiVariant& setSecond() {
   135     BiVariant& setSecond() {
   159       destroy();
   136       destroy();
   160       flag = false;
   137       flag = false;
   161       new(reinterpret_cast<Second*>(data)) Second();   
   138       new(reinterpret_cast<Second*>(data)) Second();   
   162       return *this;
   139       return *this;
   163     }
   140     }
   164 
   141 
       
   142     /// \brief Set to the given value of the \c Second type.
       
   143     ///
       
   144     /// This function sets the variant to the given value of the \c
       
   145     /// Second type.
   165     BiVariant& setSecond(const Second& second) {
   146     BiVariant& setSecond(const Second& second) {
   166       destroy();
   147       destroy();
   167       flag = false;
   148       flag = false;
   168       new(reinterpret_cast<Second*>(data)) Second(second);   
   149       new(reinterpret_cast<Second*>(data)) Second(second);   
   169       return *this;
   150       return *this;
   170     }
   151     }
   171 
   152 
       
   153     /// \brief Operator form of the \c setFirst()
   172     BiVariant& operator=(const First& first) {
   154     BiVariant& operator=(const First& first) {
   173       return setFirst(first);
   155       return setFirst(first);
   174     }
   156     }
   175 
   157 
       
   158     /// \brief Operator form of the \c setSecond()
   176     BiVariant& operator=(const Second& second) {
   159     BiVariant& operator=(const Second& second) {
   177       return setSecond(second);
   160       return setSecond(second);
   178     }
   161     }
   179 
   162 
   180 
   163     /// \brief Assign operator
   181     BiVariant& operator=(const BiVariant& bivariant) {
   164     BiVariant& operator=(const BiVariant& bivariant) {
   182       if (this == &bivariant) return *this;
   165       if (this == &bivariant) return *this;
   183       destroy();
   166       destroy();
   184       flag = bivariant.flag;
   167       flag = bivariant.flag;
   185       if (flag) {
   168       if (flag) {
   188         new(reinterpret_cast<Second*>(data)) Second(bivariant.second());      
   171         new(reinterpret_cast<Second*>(data)) Second(bivariant.second());      
   189       }
   172       }
   190       return *this;
   173       return *this;
   191     }
   174     }
   192 
   175 
       
   176     /// \brief Reference to the value
       
   177     ///
       
   178     /// Reference to the value of the \c First type.
       
   179     /// \pre The BiVariant should store value of \c First type.
   193     First& first() {
   180     First& first() {
   194       LEMON_ASSERT(flag, WrongStateError());
   181       LEMON_ASSERT(flag, WrongStateError());
   195       return *reinterpret_cast<First*>(data); 
   182       return *reinterpret_cast<First*>(data); 
   196     }
   183     }
   197 
   184 
       
   185     /// \brief Const reference to the value
       
   186     ///
       
   187     /// Const reference to the value of the \c First type.
       
   188     /// \pre The BiVariant should store value of \c First type.
   198     const First& first() const { 
   189     const First& first() const { 
   199       LEMON_ASSERT(flag, WrongStateError());
   190       LEMON_ASSERT(flag, WrongStateError());
   200       return *reinterpret_cast<const First*>(data); 
   191       return *reinterpret_cast<const First*>(data); 
   201     }
   192     }
   202 
   193 
       
   194     /// \brief Operator form of the \c first()
   203     operator First&() { return first(); }
   195     operator First&() { return first(); }
       
   196     /// \brief Operator form of the const \c first()
   204     operator const First&() const { return first(); }
   197     operator const First&() const { return first(); }
   205 
   198 
       
   199     /// \brief Reference to the value
       
   200     ///
       
   201     /// Reference to the value of the \c Second type.
       
   202     /// \pre The BiVariant should store value of \c Second type.
   206     Second& second() { 
   203     Second& second() { 
   207       LEMON_ASSERT(!flag, WrongStateError());
   204       LEMON_ASSERT(!flag, WrongStateError());
   208       return *reinterpret_cast<Second*>(data); 
   205       return *reinterpret_cast<Second*>(data); 
   209     }
   206     }
   210 
   207 
       
   208     /// \brief Const reference to the value
       
   209     ///
       
   210     /// Const reference to the value of the \c Second type.
       
   211     /// \pre The BiVariant should store value of \c Second type.
   211     const Second& second() const { 
   212     const Second& second() const { 
   212       LEMON_ASSERT(!flag, WrongStateError());
   213       LEMON_ASSERT(!flag, WrongStateError());
   213       return *reinterpret_cast<const Second*>(data); 
   214       return *reinterpret_cast<const Second*>(data); 
   214     }
   215     }
   215 
   216 
       
   217     /// \brief Operator form of the \c second()
   216     operator Second&() { return second(); }
   218     operator Second&() { return second(); }
       
   219     /// \brief Operator form of the const \c second()
   217     operator const Second&() const { return second(); }
   220     operator const Second&() const { return second(); }
   218 
   221 
       
   222     /// \brief %True when the variant is in the first state
       
   223     ///
       
   224     /// %True when the variant stores value of the \c First type.
   219     bool firstState() const { return flag; }
   225     bool firstState() const { return flag; }
       
   226 
       
   227     /// \brief %True when the variant is in the second state
       
   228     ///
       
   229     /// %True when the variant stores value of the \c Second type.
   220     bool secondState() const { return !flag; }
   230     bool secondState() const { return !flag; }
   221 
   231 
   222   private:
   232   private:
   223 
   233 
   224     void destroy() {
   234     void destroy() {
   227       } else {
   237       } else {
   228         reinterpret_cast<Second*>(data)->~Second();
   238         reinterpret_cast<Second*>(data)->~Second();
   229       }
   239       }
   230     }
   240     }
   231     
   241     
   232     char data[CTMax<sizeof(First), sizeof(Second)>::value];
   242     char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value];
   233     bool flag;
   243     bool flag;
   234   };
   244   };
   235 
   245 
       
   246   namespace _variant_bits {
       
   247     
       
   248     template <int _idx, typename _TypeMap>
       
   249     struct Memory {
       
   250 
       
   251       typedef typename _TypeMap::template Map<_idx>::Type Current;
       
   252 
       
   253       static void destroy(int index, char* place) {
       
   254         if (index == _idx) {
       
   255           reinterpret_cast<Current*>(place)->~Current();
       
   256         } else {
       
   257           Memory<_idx - 1, _TypeMap>::destroy(index, place);
       
   258         }
       
   259       }
       
   260 
       
   261       static void copy(int index, char* to, const char* from) {
       
   262         if (index == _idx) {
       
   263           new (reinterpret_cast<Current*>(to))
       
   264             Current(reinterpret_cast<const Current*>(from));
       
   265         } else {
       
   266           Memory<_idx - 1, _TypeMap>::copy(index, to, from);
       
   267         }
       
   268       }
       
   269 
       
   270     };
       
   271 
       
   272     template <typename _TypeMap>
       
   273     struct Memory<-1, _TypeMap> {
       
   274 
       
   275       static void destroy(int, char*) {
       
   276         LEMON_ASSERT(false, "Wrong Variant Index.");
       
   277       }
       
   278 
       
   279       static void copy(int, char*, const char*) {
       
   280         LEMON_ASSERT(false, "Wrong Variant Index.");
       
   281       }
       
   282     };
       
   283 
       
   284     template <int _idx, typename _TypeMap>
       
   285     struct Size {
       
   286       static const int value = 
       
   287       CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type), 
       
   288             Size<_idx - 1, _TypeMap>::value>::value;
       
   289     };
       
   290 
       
   291     template <typename _TypeMap>
       
   292     struct Size<0, _TypeMap> {
       
   293       static const int value = 
       
   294       sizeof(typename _TypeMap::template Map<0>::Type);
       
   295     };
       
   296 
       
   297   }
       
   298 
       
   299   /// \brief Variant type
       
   300   ///
       
   301   /// Simple Variant type. The Variant type is a type safe union. The
       
   302   /// C++ has strong limitations for using unions, by example we
       
   303   /// cannot store type with non default constructor or destructor in
       
   304   /// a union. This class always knowns the current state of the
       
   305   /// variant and it cares for the proper construction and
       
   306   /// destruction.
       
   307   ///
       
   308   /// \param _num The number of the types which can be stored in the
       
   309   /// variant type.
       
   310   /// \param _TypeMap This class describes the types of the Variant. The
       
   311   /// _TypeMap::Map<index>::Type should be a valid type for each index 
       
   312   /// in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
       
   313   /// class to define such type mappings up to 10 types.
       
   314   ///
       
   315   /// And the usage of the class:
       
   316   ///\code
       
   317   /// typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
       
   318   /// MyVariant var;
       
   319   /// var.set<0>(12);
       
   320   /// std::cout << var.get<0>() << std::endl;
       
   321   /// var.set<1>("alpha");
       
   322   /// std::cout << var.get<1>() << std::endl;
       
   323   /// var.set<2>(0.75);
       
   324   /// std::cout << var.get<2>() << std::endl;
       
   325   ///\endcode
       
   326   ///
       
   327   /// The result of course:
       
   328   ///\code
       
   329   /// 12
       
   330   /// alpha
       
   331   /// 0.75
       
   332   ///\endcode
       
   333   template <int _num, typename _TypeMap>
       
   334   class Variant {
       
   335   public:
       
   336 
       
   337     static const int num = _num;
       
   338 
       
   339     typedef _TypeMap TypeMap;
       
   340 
       
   341     struct WrongStateError : public lemon::LogicError {
       
   342     public:
       
   343       virtual const char* what() const throw() {
       
   344         return "lemon::Variant::WrongStateError";
       
   345       }
       
   346     };
       
   347 
       
   348     /// \brief Constructor
       
   349     ///
       
   350     /// This constructor initalizes to the default value of the \c type
       
   351     /// with 0 index.
       
   352     Variant() {
       
   353       flag = 0;
       
   354       new(reinterpret_cast<typename TypeMap::template Map<0>::Type*>(data)) 
       
   355         typename TypeMap::template Map<0>::Type();
       
   356     }
       
   357 
       
   358 
       
   359     /// \brief Copy constructor
       
   360     ///
       
   361     /// Copy constructor
       
   362     Variant(const Variant& variant) {
       
   363       flag = variant.flag;
       
   364       _variant_bits::Memory<num - 1, TypeMap>::copy(flag, data, variant.data);
       
   365     }
       
   366 
       
   367     /// \brief Assign operator
       
   368     ///
       
   369     /// Assign operator
       
   370     Variant& operator=(const Variant& variant) {
       
   371       if (this == &variant) return *this;
       
   372       _variant_bits::Memory<num - 1, TypeMap>::
       
   373         destroy(flag, data);
       
   374       flag = variant.flag;
       
   375       _variant_bits::Memory<num - 1, TypeMap>::
       
   376         copy(flag, data, variant.data);
       
   377       return *this;
       
   378     }
       
   379 
       
   380     /// \brief Destrcutor
       
   381     ///
       
   382     /// Destructor
       
   383     ~Variant() {
       
   384       _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
       
   385     }
       
   386 
       
   387     /// \brief Set to the default value of the type with \c _idx index.
       
   388     ///
       
   389     /// This function sets the variant to the default value of the
       
   390     /// type with \c _idx index.
       
   391     template <int _idx>
       
   392     Variant& set() {
       
   393       _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
       
   394       flag = _idx;
       
   395       new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data)) 
       
   396         typename TypeMap::template Map<_idx>::Type();
       
   397       return *this;
       
   398     }
       
   399 
       
   400     /// \brief Set to the given value of the type with \c _idx index.
       
   401     ///
       
   402     /// This function sets the variant to the given value of the type
       
   403     /// with \c _idx index.
       
   404     template <int _idx>
       
   405     Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) {
       
   406       _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
       
   407       flag = _idx;
       
   408       new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data)) 
       
   409         typename TypeMap::template Map<_idx>::Type(init);
       
   410       return *this;
       
   411     }
       
   412 
       
   413     /// \brief Gets the current value of the type with \c _idx index.
       
   414     ///
       
   415     /// Gets the current value of the type with \c _idx index.
       
   416     template <int _idx>
       
   417     const typename TypeMap::template Map<_idx>::Type& get() const {
       
   418       LEMON_ASSERT(_idx == flag, "Wrong Variant Index.");
       
   419       return *reinterpret_cast<const typename TypeMap::
       
   420         template Map<_idx>::Type*>(data); 
       
   421     }
       
   422 
       
   423     /// \brief Gets the current value of the type with \c _idx index.
       
   424     ///
       
   425     /// Gets the current value of the type with \c _idx index.
       
   426     template <int _idx>
       
   427     typename _TypeMap::template Map<_idx>::Type& get() {
       
   428       LEMON_ASSERT(_idx == flag, "Wrong Variant Index.");
       
   429       return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>
       
   430         (data); 
       
   431     }
       
   432 
       
   433     /// \brief Returns the current state of the variant.
       
   434     ///
       
   435     /// Returns the current state of the variant.
       
   436     int state() const {
       
   437       return flag;
       
   438     }
       
   439 
       
   440   private:
       
   441     
       
   442     char data[_variant_bits::Size<num - 1, TypeMap>::value];
       
   443     int flag;
       
   444   };
       
   445 
       
   446   namespace _variant_bits {
       
   447 
       
   448     template <int _index, typename _List>
       
   449     struct Get {
       
   450       typedef typename Get<_index - 1, typename _List::Next>::Type Type;
       
   451     };
       
   452 
       
   453     template <typename _List>
       
   454     struct Get<0, _List> {
       
   455       typedef typename _List::Type Type;
       
   456     };
       
   457 
       
   458     struct List {};
       
   459     
       
   460     template <typename _Type, typename _List>
       
   461     struct Insert {
       
   462       typedef _List Next;
       
   463       typedef _Type Type;
       
   464     };
       
   465 
       
   466     template <int _idx, typename _T0, typename _T1, typename _T2, 
       
   467               typename _T3, typename _T5, typename _T4, typename _T6,
       
   468               typename _T7, typename _T8, typename _T9>
       
   469     struct Mapper {
       
   470       typedef List L10;
       
   471       typedef Insert<_T9, L10> L9;
       
   472       typedef Insert<_T8, L9> L8;
       
   473       typedef Insert<_T7, L8> L7;
       
   474       typedef Insert<_T6, L7> L6;
       
   475       typedef Insert<_T5, L6> L5;
       
   476       typedef Insert<_T4, L5> L4;
       
   477       typedef Insert<_T3, L4> L3;
       
   478       typedef Insert<_T2, L3> L2;
       
   479       typedef Insert<_T1, L2> L1;
       
   480       typedef Insert<_T0, L1> L0;
       
   481       typedef typename Get<_idx, L0>::Type Type;
       
   482     };
       
   483     
       
   484   }
       
   485 
       
   486   /// \brief Helper class for Variant
       
   487   ///
       
   488   /// Helper class to define type mappings for Variant. This class
       
   489   /// converts the template parameters to be mappable by integer.
       
   490   /// \see Variant
       
   491   template <
       
   492     typename _T0, 
       
   493     typename _T1 = void, typename _T2 = void, typename _T3 = void,
       
   494     typename _T5 = void, typename _T4 = void, typename _T6 = void,
       
   495     typename _T7 = void, typename _T8 = void, typename _T9 = void>
       
   496   struct VariantTypeMap {
       
   497     template <int _idx>
       
   498     struct Map {
       
   499       typedef typename _variant_bits::
       
   500       Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type
       
   501       Type;
       
   502     };
       
   503   };
       
   504   
   236 }
   505 }
   237 
   506 
   238 
   507 
   239 #endif
   508 #endif