[Lemon-commits] [lemon_svn] deba: r2740 - hugo/trunk/lemon/bits

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:54:52 CET 2006


Author: deba
Date: Fri May 12 11:52:28 2006
New Revision: 2740

Modified:
   hugo/trunk/lemon/bits/utility.h

Log:
Two state Variant
+ Some Compile Time arithmetic




Modified: hugo/trunk/lemon/bits/utility.h
==============================================================================
--- hugo/trunk/lemon/bits/utility.h	(original)
+++ hugo/trunk/lemon/bits/utility.h	Fri May 12 11:52:28 2006
@@ -35,6 +35,8 @@
 #ifndef LEMON_BITS_UTILITY_H
 #define LEMON_BITS_UTILITY_H
 
+#include <lemon/error.h>
+
 ///\file
 ///\brief Miscellaneous basic utilities
 ///
@@ -73,7 +75,224 @@
   private:
     InvalidType();
   };
+
+  template <bool left, bool right>
+  struct CTOr {
+    static const bool value = true;
+  };
+
+  template <>
+  struct CTOr<false, false> {
+    static const bool value = false;
+  };
+
+  template <bool left, bool right>
+  struct CTAnd {
+    static const bool value = false;
+  };
+
+  template <>
+  struct CTAnd<true, true> {
+    static const bool value = true;
+  };
+
+  template <int left, int right>
+  struct CTEqual {
+    static const bool value = false;
+  };
+
+  template <int val>
+  struct CTEqual<val, val> {
+    static const bool value = true;
+  };
+
+  template <bool sless, bool sequal, bool bless>
+  struct CTLessImpl {
+   static const bool value =
+   CTOr<sless, CTAnd<sequal, bless>::value>::value;
+  };
+
+  template <int left, int right>
+  struct CTLess {
+    static const bool value = 
+    CTLessImpl<CTLess<left >> 1, right >> 1>::value, 
+               CTEqual<left >> 1, right >> 1>::value,
+               CTLess<left & 1, right & 1>::value >::value;
+  };
+
+  template <int left>
+  struct CTLess<left, 0> {
+    static const bool value = false;
+  };
+
+  template <int right>
+  struct CTLess<0, right> {
+    static const bool value = true;
+  };
+
+  template <>
+  struct CTLess<0, 0> {
+    static const bool value = false;
+  };
+
+  template <>
+  struct CTLess<1, 1> {
+    static const bool value = false;
+  };
+
+  template <bool less, int left, int right>
+  struct CTMaxImpl {
+    static const int value = left;    
+  };
+
+  template <int left, int right>
+  struct CTMaxImpl<true, left, right> {
+    static const int value = right;
+  };
   
+  template <int left, int right>
+  struct CTMax {
+    static const int value = 
+    CTMaxImpl<CTLess<left, right>::value, left, right>::value;
+  };
+
+
+  /// \brief Simple Variant type with two type
+  ///
+  /// Simple Variant type with two type
+  template <typename _First, typename _Second>
+  class BiVariant {
+  public:
+
+    typedef _First First;
+    typedef _Second Second;
+
+    struct WrongStateError : public lemon::LogicError {
+    public:
+      virtual const char* exceptionName() const {
+        return "lemon::BiVariant::WrongStateError";
+      }
+    };
+
+    BiVariant() {
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First();
+    }
+
+    BiVariant(const First& first) {
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First(first);
+    }
+
+    BiVariant(const Second& second) {
+      flag = false;
+      new(reinterpret_cast<Second*>(data)) Second(second);
+    }
+
+    BiVariant(const BiVariant& bivariant) {
+      flag = bivariant.flag;
+      if (flag) {
+        new(reinterpret_cast<First*>(data)) First(bivariant.first());      
+      } else {
+        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());      
+      }
+    }
+
+    ~BiVariant() {
+      destroy();
+    }
+
+    BiVariant& setFirst() {
+      destroy();
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First();   
+      return *this;
+    }
+
+    BiVariant& setFirst(const First& first) {
+      destroy();
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First(first);   
+      return *this;
+    }
+
+    BiVariant& setSecond() {
+      destroy();
+      flag = false;
+      new(reinterpret_cast<Second*>(data)) Second();   
+      return *this;
+    }
+
+    BiVariant& setSecond(const Second& second) {
+      destroy();
+      flag = false;
+      new(reinterpret_cast<Second*>(data)) Second(second);   
+      return *this;
+    }
+
+    BiVariant& operator=(const First& first) {
+      return setFirst(first);
+    }
+
+    BiVariant& operator=(const Second& second) {
+      return setSecond(second);
+    }
+
+
+    BiVariant& operator=(const BiVariant& bivariant) {
+      if (this == &bivariant) return *this;
+      destroy();
+      flag = bivariant.flag;
+      if (flag) {
+        new(reinterpret_cast<First*>(data)) First(bivariant.first());      
+      } else {
+        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());      
+      }
+      return *this;
+    }
+
+    First& first() {
+      LEMON_ASSERT(flag, WrongStateError());
+      return *reinterpret_cast<First*>(data); 
+    }
+
+    const First& first() const { 
+      LEMON_ASSERT(flag, WrongStateError());
+      return *reinterpret_cast<const First*>(data); 
+    }
+
+    operator First&() { return first(); }
+    operator const First&() const { return first(); }
+
+    Second& second() { 
+      LEMON_ASSERT(!flag, WrongStateError());
+      return *reinterpret_cast<Second*>(data); 
+    }
+
+    const Second& second() const { 
+      LEMON_ASSERT(!flag, WrongStateError());
+      return *reinterpret_cast<const Second*>(data); 
+    }
+
+    operator Second&() { return second(); }
+    operator const Second&() const { return second(); }
+
+    bool firstState() const { return flag; }
+    bool secondState() const { return !flag; }
+
+  private:
+
+    void destroy() {
+      if (flag) {
+        reinterpret_cast<First*>(data)->~First();
+      } else {
+        reinterpret_cast<Second*>(data)->~Second();
+      }
+    }
+    
+    char data[CTMax<sizeof(First), sizeof(Second)>::value];
+    bool flag;
+  };
 
   template <typename T>
   struct Wrap {



More information about the Lemon-commits mailing list