1.1 --- a/lemon/bits/utility.h Fri May 12 09:51:45 2006 +0000
1.2 +++ b/lemon/bits/utility.h Fri May 12 09:52:28 2006 +0000
1.3 @@ -35,6 +35,8 @@
1.4 #ifndef LEMON_BITS_UTILITY_H
1.5 #define LEMON_BITS_UTILITY_H
1.6
1.7 +#include <lemon/error.h>
1.8 +
1.9 ///\file
1.10 ///\brief Miscellaneous basic utilities
1.11 ///
1.12 @@ -73,7 +75,224 @@
1.13 private:
1.14 InvalidType();
1.15 };
1.16 +
1.17 + template <bool left, bool right>
1.18 + struct CTOr {
1.19 + static const bool value = true;
1.20 + };
1.21 +
1.22 + template <>
1.23 + struct CTOr<false, false> {
1.24 + static const bool value = false;
1.25 + };
1.26 +
1.27 + template <bool left, bool right>
1.28 + struct CTAnd {
1.29 + static const bool value = false;
1.30 + };
1.31 +
1.32 + template <>
1.33 + struct CTAnd<true, true> {
1.34 + static const bool value = true;
1.35 + };
1.36 +
1.37 + template <int left, int right>
1.38 + struct CTEqual {
1.39 + static const bool value = false;
1.40 + };
1.41 +
1.42 + template <int val>
1.43 + struct CTEqual<val, val> {
1.44 + static const bool value = true;
1.45 + };
1.46 +
1.47 + template <bool sless, bool sequal, bool bless>
1.48 + struct CTLessImpl {
1.49 + static const bool value =
1.50 + CTOr<sless, CTAnd<sequal, bless>::value>::value;
1.51 + };
1.52 +
1.53 + template <int left, int right>
1.54 + struct CTLess {
1.55 + static const bool value =
1.56 + CTLessImpl<CTLess<left >> 1, right >> 1>::value,
1.57 + CTEqual<left >> 1, right >> 1>::value,
1.58 + CTLess<left & 1, right & 1>::value >::value;
1.59 + };
1.60 +
1.61 + template <int left>
1.62 + struct CTLess<left, 0> {
1.63 + static const bool value = false;
1.64 + };
1.65 +
1.66 + template <int right>
1.67 + struct CTLess<0, right> {
1.68 + static const bool value = true;
1.69 + };
1.70 +
1.71 + template <>
1.72 + struct CTLess<0, 0> {
1.73 + static const bool value = false;
1.74 + };
1.75 +
1.76 + template <>
1.77 + struct CTLess<1, 1> {
1.78 + static const bool value = false;
1.79 + };
1.80 +
1.81 + template <bool less, int left, int right>
1.82 + struct CTMaxImpl {
1.83 + static const int value = left;
1.84 + };
1.85 +
1.86 + template <int left, int right>
1.87 + struct CTMaxImpl<true, left, right> {
1.88 + static const int value = right;
1.89 + };
1.90
1.91 + template <int left, int right>
1.92 + struct CTMax {
1.93 + static const int value =
1.94 + CTMaxImpl<CTLess<left, right>::value, left, right>::value;
1.95 + };
1.96 +
1.97 +
1.98 + /// \brief Simple Variant type with two type
1.99 + ///
1.100 + /// Simple Variant type with two type
1.101 + template <typename _First, typename _Second>
1.102 + class BiVariant {
1.103 + public:
1.104 +
1.105 + typedef _First First;
1.106 + typedef _Second Second;
1.107 +
1.108 + struct WrongStateError : public lemon::LogicError {
1.109 + public:
1.110 + virtual const char* exceptionName() const {
1.111 + return "lemon::BiVariant::WrongStateError";
1.112 + }
1.113 + };
1.114 +
1.115 + BiVariant() {
1.116 + flag = true;
1.117 + new(reinterpret_cast<First*>(data)) First();
1.118 + }
1.119 +
1.120 + BiVariant(const First& first) {
1.121 + flag = true;
1.122 + new(reinterpret_cast<First*>(data)) First(first);
1.123 + }
1.124 +
1.125 + BiVariant(const Second& second) {
1.126 + flag = false;
1.127 + new(reinterpret_cast<Second*>(data)) Second(second);
1.128 + }
1.129 +
1.130 + BiVariant(const BiVariant& bivariant) {
1.131 + flag = bivariant.flag;
1.132 + if (flag) {
1.133 + new(reinterpret_cast<First*>(data)) First(bivariant.first());
1.134 + } else {
1.135 + new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
1.136 + }
1.137 + }
1.138 +
1.139 + ~BiVariant() {
1.140 + destroy();
1.141 + }
1.142 +
1.143 + BiVariant& setFirst() {
1.144 + destroy();
1.145 + flag = true;
1.146 + new(reinterpret_cast<First*>(data)) First();
1.147 + return *this;
1.148 + }
1.149 +
1.150 + BiVariant& setFirst(const First& first) {
1.151 + destroy();
1.152 + flag = true;
1.153 + new(reinterpret_cast<First*>(data)) First(first);
1.154 + return *this;
1.155 + }
1.156 +
1.157 + BiVariant& setSecond() {
1.158 + destroy();
1.159 + flag = false;
1.160 + new(reinterpret_cast<Second*>(data)) Second();
1.161 + return *this;
1.162 + }
1.163 +
1.164 + BiVariant& setSecond(const Second& second) {
1.165 + destroy();
1.166 + flag = false;
1.167 + new(reinterpret_cast<Second*>(data)) Second(second);
1.168 + return *this;
1.169 + }
1.170 +
1.171 + BiVariant& operator=(const First& first) {
1.172 + return setFirst(first);
1.173 + }
1.174 +
1.175 + BiVariant& operator=(const Second& second) {
1.176 + return setSecond(second);
1.177 + }
1.178 +
1.179 +
1.180 + BiVariant& operator=(const BiVariant& bivariant) {
1.181 + if (this == &bivariant) return *this;
1.182 + destroy();
1.183 + flag = bivariant.flag;
1.184 + if (flag) {
1.185 + new(reinterpret_cast<First*>(data)) First(bivariant.first());
1.186 + } else {
1.187 + new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
1.188 + }
1.189 + return *this;
1.190 + }
1.191 +
1.192 + First& first() {
1.193 + LEMON_ASSERT(flag, WrongStateError());
1.194 + return *reinterpret_cast<First*>(data);
1.195 + }
1.196 +
1.197 + const First& first() const {
1.198 + LEMON_ASSERT(flag, WrongStateError());
1.199 + return *reinterpret_cast<const First*>(data);
1.200 + }
1.201 +
1.202 + operator First&() { return first(); }
1.203 + operator const First&() const { return first(); }
1.204 +
1.205 + Second& second() {
1.206 + LEMON_ASSERT(!flag, WrongStateError());
1.207 + return *reinterpret_cast<Second*>(data);
1.208 + }
1.209 +
1.210 + const Second& second() const {
1.211 + LEMON_ASSERT(!flag, WrongStateError());
1.212 + return *reinterpret_cast<const Second*>(data);
1.213 + }
1.214 +
1.215 + operator Second&() { return second(); }
1.216 + operator const Second&() const { return second(); }
1.217 +
1.218 + bool firstState() const { return flag; }
1.219 + bool secondState() const { return !flag; }
1.220 +
1.221 + private:
1.222 +
1.223 + void destroy() {
1.224 + if (flag) {
1.225 + reinterpret_cast<First*>(data)->~First();
1.226 + } else {
1.227 + reinterpret_cast<Second*>(data)->~Second();
1.228 + }
1.229 + }
1.230 +
1.231 + char data[CTMax<sizeof(First), sizeof(Second)>::value];
1.232 + bool flag;
1.233 + };
1.234
1.235 template <typename T>
1.236 struct Wrap {