1 // (C) Copyright Jeremy Siek 2000. 2 // Distributed under the Boost Software License, Version 1.0. (See 3 // accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 // The ct_if implementation that avoids partial specialization is 7 // based on the IF class by Ulrich W. Eisenecker and Krzysztof 8 // Czarnecki. 9 10 #ifndef BOOST_CT_IF_HPP 11 #define BOOST_CT_IF_HPP 12 13 #include <boost/config.hpp> 14 15 /* 16 There is a bug in the Borland compiler with regards to using 17 integers to specialize templates. This made it hard to use ct_if in 18 the graph library. Changing from 'ct_if' to 'ct_if_t' fixed the 19 problem. 20 */ 21 22 #include <boost/type_traits/integral_constant.hpp> // true_type and false_type 23 24 namespace boost { 25 26 struct ct_if_error { }; 27 28 template <class A, class B> 29 struct ct_and { typedef false_type type; }; 30 template <> struct ct_and<true_type,true_type> { typedef true_type type; }; 31 32 template <class A> struct ct_not { typedef ct_if_error type; }; 33 template <> struct ct_not<true_type> { typedef false_type type; }; 34 template <> struct ct_not<false_type> { typedef true_type type; }; 35 36 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 37 38 // agurt, 15/sep/02: in certain cases Borland has problems with 39 // choosing the right 'ct_if' specialization even though 'cond' 40 // _does_ equal '1'; the easiest way to fix it is to make first 41 // 'ct_if' non-type template parameter boolean. 42 #if !defined(__BORLANDC__) 43 template <bool cond, class A, class B> 44 struct ct_if { typedef ct_if_error type; }; 45 template <class A, class B> 46 struct ct_if<true, A, B> { typedef A type; }; 47 template <class A, class B> 48 struct ct_if<false, A, B> { typedef B type; }; 49 #else 50 template <bool cond, class A, class B> 51 struct ct_if { typedef A type; }; 52 template <class A, class B> 53 struct ct_if<false, A, B> { typedef B type; }; 54 #endif 55 56 template <class cond, class A, class B> 57 struct ct_if_t { typedef ct_if_error type; }; 58 template <class A, class B> 59 struct ct_if_t<true_type, A, B> { typedef A type; }; 60 template <class A, class B> 61 struct ct_if_t<false_type, A, B> { typedef B type; }; 62 63 #else 64 65 namespace detail { 66 67 template <int condition, class A, class B> struct IF; 68 template <int condition> struct SlectSelector; 69 struct SelectFirstType; 70 struct SelectSecondType; 71 72 struct SelectFirstType { 73 template<class A, class B> 74 struct Template { typedef A type; }; 75 }; 76 77 struct SelectSecondType { 78 template<class A, class B> 79 struct Template { typedef B type; }; 80 }; 81 82 template<int condition> 83 struct SlectSelector { 84 typedef SelectFirstType type; 85 }; 86 87 template <> 88 struct SlectSelector<0> { 89 typedef SelectSecondType type; 90 }; 91 92 } // namespace detail 93 94 template<int condition, class A, class B> 95 struct ct_if 96 { 97 typedef typename detail::SlectSelector<condition>::type Selector; 98 typedef typename Selector::template Template<A, B>::type type; 99 }; 100 101 template <class cond, class A, class B> 102 struct ct_if_t { 103 typedef typename ct_if<cond::value, A, B>::type type; 104 }; 105 106 #endif 107 108 } // namespace boost 109 110 #endif // BOOST_CT_IF_HPP 111 112