3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_BITS_VARIANT_H
20 #define LEMON_BITS_VARIANT_H
22 #include <lemon/error.h>
26 template <bool left, bool right>
28 static const bool value = true;
32 struct CTOr<false, false> {
33 static const bool value = false;
36 template <bool left, bool right>
38 static const bool value = false;
42 struct CTAnd<true, true> {
43 static const bool value = true;
46 template <int left, int right>
48 static const bool value = false;
52 struct CTEqual<val, val> {
53 static const bool value = true;
57 template <int left, int right>
59 static const bool value = left < right;
63 struct CTLess<left, 0> {
64 static const bool value = false;
68 struct CTLess<0, right> {
69 static const bool value = true;
74 static const bool value = false;
79 static const bool value = false;
82 template <bool less, int left, int right>
84 static const int value = left;
87 template <int left, int right>
88 struct CTMaxImpl<true, left, right> {
89 static const int value = right;
92 template <int left, int right>
94 static const int value =
95 CTMaxImpl<CTLess<left, right>::value, left, right>::value;
99 /// \brief Simple Variant type with two type
101 /// Simple Variant type with two type
102 template <typename _First, typename _Second>
106 typedef _First First;
107 typedef _Second Second;
109 struct WrongStateError : public lemon::LogicError {
111 virtual const char* what() const throw() {
112 return "lemon::BiVariant::WrongStateError";
118 new(reinterpret_cast<First*>(data)) First();
121 BiVariant(const First& first) {
123 new(reinterpret_cast<First*>(data)) First(first);
126 BiVariant(const Second& second) {
128 new(reinterpret_cast<Second*>(data)) Second(second);
131 BiVariant(const BiVariant& bivariant) {
132 flag = bivariant.flag;
134 new(reinterpret_cast<First*>(data)) First(bivariant.first());
136 new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
144 BiVariant& setFirst() {
147 new(reinterpret_cast<First*>(data)) First();
151 BiVariant& setFirst(const First& first) {
154 new(reinterpret_cast<First*>(data)) First(first);
158 BiVariant& setSecond() {
161 new(reinterpret_cast<Second*>(data)) Second();
165 BiVariant& setSecond(const Second& second) {
168 new(reinterpret_cast<Second*>(data)) Second(second);
172 BiVariant& operator=(const First& first) {
173 return setFirst(first);
176 BiVariant& operator=(const Second& second) {
177 return setSecond(second);
181 BiVariant& operator=(const BiVariant& bivariant) {
182 if (this == &bivariant) return *this;
184 flag = bivariant.flag;
186 new(reinterpret_cast<First*>(data)) First(bivariant.first());
188 new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
194 LEMON_ASSERT(flag, WrongStateError());
195 return *reinterpret_cast<First*>(data);
198 const First& first() const {
199 LEMON_ASSERT(flag, WrongStateError());
200 return *reinterpret_cast<const First*>(data);
203 operator First&() { return first(); }
204 operator const First&() const { return first(); }
207 LEMON_ASSERT(!flag, WrongStateError());
208 return *reinterpret_cast<Second*>(data);
211 const Second& second() const {
212 LEMON_ASSERT(!flag, WrongStateError());
213 return *reinterpret_cast<const Second*>(data);
216 operator Second&() { return second(); }
217 operator const Second&() const { return second(); }
219 bool firstState() const { return flag; }
220 bool secondState() const { return !flag; }
226 reinterpret_cast<First*>(data)->~First();
228 reinterpret_cast<Second*>(data)->~Second();
232 char data[CTMax<sizeof(First), sizeof(Second)>::value];