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 // This file contains a modified version of the enable_if library from BOOST.
20 // See the appropriate copyright notice below.
22 // Boost enable_if library
24 // Copyright 2003 © The Trustees of Indiana University.
26 // Use, modification, and distribution is subject to the Boost Software
27 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
28 // http://www.boost.org/LICENSE_1_0.txt)
30 // Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
31 // Jeremiah Willcock (jewillco at osl.iu.edu)
32 // Andrew Lumsdaine (lums at osl.iu.edu)
35 #ifndef LEMON_BITS_UTILITY_H
36 #define LEMON_BITS_UTILITY_H
38 #include <lemon/error.h>
41 ///\brief Miscellaneous basic utilities
43 ///\todo Please rethink the organisation of the basic files like this.
44 ///E.g. this file might be merged with invalid.h.
50 /// Basic type for defining "tags". A "YES" condition for \c enable_if.
52 /// Basic type for defining "tags". A "YES" condition for \c enable_if.
56 /// \todo This should go to a separate "basic_types.h" (or something)
60 static const bool value = true;
63 /// Basic type for defining "tags". A "NO" condition for \c enable_if.
65 /// Basic type for defining "tags". A "NO" condition for \c enable_if.
70 static const bool value = false;
79 template <bool left, bool right>
81 static const bool value = true;
85 struct CTOr<false, false> {
86 static const bool value = false;
89 template <bool left, bool right>
91 static const bool value = false;
95 struct CTAnd<true, true> {
96 static const bool value = true;
99 template <int left, int right>
101 static const bool value = false;
105 struct CTEqual<val, val> {
106 static const bool value = true;
110 template <int left, int right>
112 static const bool value = left < right;
116 struct CTLess<left, 0> {
117 static const bool value = false;
121 struct CTLess<0, right> {
122 static const bool value = true;
126 struct CTLess<0, 0> {
127 static const bool value = false;
131 struct CTLess<1, 1> {
132 static const bool value = false;
135 template <bool less, int left, int right>
137 static const int value = left;
140 template <int left, int right>
141 struct CTMaxImpl<true, left, right> {
142 static const int value = right;
145 template <int left, int right>
147 static const int value =
148 CTMaxImpl<CTLess<left, right>::value, left, right>::value;
152 /// \brief Simple Variant type with two type
154 /// Simple Variant type with two type
155 template <typename _First, typename _Second>
159 typedef _First First;
160 typedef _Second Second;
162 struct WrongStateError : public lemon::LogicError {
164 virtual const char* exceptionName() const {
165 return "lemon::BiVariant::WrongStateError";
171 new(reinterpret_cast<First*>(data)) First();
174 BiVariant(const First& first) {
176 new(reinterpret_cast<First*>(data)) First(first);
179 BiVariant(const Second& second) {
181 new(reinterpret_cast<Second*>(data)) Second(second);
184 BiVariant(const BiVariant& bivariant) {
185 flag = bivariant.flag;
187 new(reinterpret_cast<First*>(data)) First(bivariant.first());
189 new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
197 BiVariant& setFirst() {
200 new(reinterpret_cast<First*>(data)) First();
204 BiVariant& setFirst(const First& first) {
207 new(reinterpret_cast<First*>(data)) First(first);
211 BiVariant& setSecond() {
214 new(reinterpret_cast<Second*>(data)) Second();
218 BiVariant& setSecond(const Second& second) {
221 new(reinterpret_cast<Second*>(data)) Second(second);
225 BiVariant& operator=(const First& first) {
226 return setFirst(first);
229 BiVariant& operator=(const Second& second) {
230 return setSecond(second);
234 BiVariant& operator=(const BiVariant& bivariant) {
235 if (this == &bivariant) return *this;
237 flag = bivariant.flag;
239 new(reinterpret_cast<First*>(data)) First(bivariant.first());
241 new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
247 LEMON_ASSERT(flag, WrongStateError());
248 return *reinterpret_cast<First*>(data);
251 const First& first() const {
252 LEMON_ASSERT(flag, WrongStateError());
253 return *reinterpret_cast<const First*>(data);
256 operator First&() { return first(); }
257 operator const First&() const { return first(); }
260 LEMON_ASSERT(!flag, WrongStateError());
261 return *reinterpret_cast<Second*>(data);
264 const Second& second() const {
265 LEMON_ASSERT(!flag, WrongStateError());
266 return *reinterpret_cast<const Second*>(data);
269 operator Second&() { return second(); }
270 operator const Second&() const { return second(); }
272 bool firstState() const { return flag; }
273 bool secondState() const { return !flag; }
279 reinterpret_cast<First*>(data)->~First();
281 reinterpret_cast<Second*>(data)->~Second();
285 char data[CTMax<sizeof(First), sizeof(Second)>::value];
289 template <typename T>
292 Wrap(const T &t) : value(t) {}
295 /**************** dummy class to avoid ambiguity ****************/
297 template<int T> struct dummy { dummy(int) {} };
299 /**************** enable_if from BOOST ****************/
301 template <bool B, class T = void>
307 struct enable_if_c<false, T> {};
309 template <class Cond, class T = void>
310 struct enable_if : public enable_if_c<Cond::value, T> {};
312 template <bool B, class T>
313 struct lazy_enable_if_c {
314 typedef typename T::type type;
318 struct lazy_enable_if_c<false, T> {};
320 template <class Cond, class T>
321 struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
324 template <bool B, class T = void>
325 struct disable_if_c {
330 struct disable_if_c<true, T> {};
332 template <class Cond, class T = void>
333 struct disable_if : public disable_if_c<Cond::value, T> {};
335 template <bool B, class T>
336 struct lazy_disable_if_c {
337 typedef typename T::type type;
341 struct lazy_disable_if_c<true, T> {};
343 template <class Cond, class T>
344 struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};