[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