# HG changeset patch # User deba # Date 1147427548 0 # Node ID d687c0033bb545c7f44c21af07511bc3efe1dd78 # Parent 10681ee9d8ae31a790874022b5f28f90ee5080b6 Two state Variant + Some Compile Time arithmetic diff -r 10681ee9d8ae -r d687c0033bb5 lemon/bits/utility.h --- a/lemon/bits/utility.h Fri May 12 09:51:45 2006 +0000 +++ b/lemon/bits/utility.h Fri May 12 09:52:28 2006 +0000 @@ -35,6 +35,8 @@ #ifndef LEMON_BITS_UTILITY_H #define LEMON_BITS_UTILITY_H +#include + ///\file ///\brief Miscellaneous basic utilities /// @@ -73,7 +75,224 @@ private: InvalidType(); }; + + template + struct CTOr { + static const bool value = true; + }; + + template <> + struct CTOr { + static const bool value = false; + }; + + template + struct CTAnd { + static const bool value = false; + }; + + template <> + struct CTAnd { + static const bool value = true; + }; + + template + struct CTEqual { + static const bool value = false; + }; + + template + struct CTEqual { + static const bool value = true; + }; + + template + struct CTLessImpl { + static const bool value = + CTOr::value>::value; + }; + + template + struct CTLess { + static const bool value = + CTLessImpl> 1, right >> 1>::value, + CTEqual> 1, right >> 1>::value, + CTLess::value >::value; + }; + + template + struct CTLess { + static const bool value = false; + }; + + template + 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 + struct CTMaxImpl { + static const int value = left; + }; + + template + struct CTMaxImpl { + static const int value = right; + }; + template + struct CTMax { + static const int value = + CTMaxImpl::value, left, right>::value; + }; + + + /// \brief Simple Variant type with two type + /// + /// Simple Variant type with two type + template + 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(data)) First(); + } + + BiVariant(const First& first) { + flag = true; + new(reinterpret_cast(data)) First(first); + } + + BiVariant(const Second& second) { + flag = false; + new(reinterpret_cast(data)) Second(second); + } + + BiVariant(const BiVariant& bivariant) { + flag = bivariant.flag; + if (flag) { + new(reinterpret_cast(data)) First(bivariant.first()); + } else { + new(reinterpret_cast(data)) Second(bivariant.second()); + } + } + + ~BiVariant() { + destroy(); + } + + BiVariant& setFirst() { + destroy(); + flag = true; + new(reinterpret_cast(data)) First(); + return *this; + } + + BiVariant& setFirst(const First& first) { + destroy(); + flag = true; + new(reinterpret_cast(data)) First(first); + return *this; + } + + BiVariant& setSecond() { + destroy(); + flag = false; + new(reinterpret_cast(data)) Second(); + return *this; + } + + BiVariant& setSecond(const Second& second) { + destroy(); + flag = false; + new(reinterpret_cast(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(data)) First(bivariant.first()); + } else { + new(reinterpret_cast(data)) Second(bivariant.second()); + } + return *this; + } + + First& first() { + LEMON_ASSERT(flag, WrongStateError()); + return *reinterpret_cast(data); + } + + const First& first() const { + LEMON_ASSERT(flag, WrongStateError()); + return *reinterpret_cast(data); + } + + operator First&() { return first(); } + operator const First&() const { return first(); } + + Second& second() { + LEMON_ASSERT(!flag, WrongStateError()); + return *reinterpret_cast(data); + } + + const Second& second() const { + LEMON_ASSERT(!flag, WrongStateError()); + return *reinterpret_cast(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(data)->~First(); + } else { + reinterpret_cast(data)->~Second(); + } + } + + char data[CTMax::value]; + bool flag; + }; template struct Wrap {