williamr@2: // (C) Copyright Jeremy Siek 2000. williamr@2: // Distributed under the Boost Software License, Version 1.0. (See williamr@2: // accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: williamr@2: // The ct_if implementation that avoids partial specialization is williamr@2: // based on the IF class by Ulrich W. Eisenecker and Krzysztof williamr@2: // Czarnecki. williamr@2: williamr@2: #ifndef BOOST_CT_IF_HPP williamr@2: #define BOOST_CT_IF_HPP williamr@2: williamr@2: #include williamr@2: williamr@2: /* williamr@2: There is a bug in the Borland compiler with regards to using williamr@2: integers to specialize templates. This made it hard to use ct_if in williamr@2: the graph library. Changing from 'ct_if' to 'ct_if_t' fixed the williamr@2: problem. williamr@2: */ williamr@2: williamr@2: #include // true_type and false_type williamr@2: williamr@2: namespace boost { williamr@2: williamr@2: struct ct_if_error { }; williamr@2: williamr@2: template williamr@2: struct ct_and { typedef false_type type; }; williamr@2: template <> struct ct_and { typedef true_type type; }; williamr@2: williamr@2: template struct ct_not { typedef ct_if_error type; }; williamr@2: template <> struct ct_not { typedef false_type type; }; williamr@2: template <> struct ct_not { typedef true_type type; }; williamr@2: williamr@2: #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION williamr@2: williamr@2: // agurt, 15/sep/02: in certain cases Borland has problems with williamr@2: // choosing the right 'ct_if' specialization even though 'cond' williamr@2: // _does_ equal '1'; the easiest way to fix it is to make first williamr@2: // 'ct_if' non-type template parameter boolean. williamr@2: #if !defined(__BORLANDC__) williamr@2: template williamr@2: struct ct_if { typedef ct_if_error type; }; williamr@2: template williamr@2: struct ct_if { typedef A type; }; williamr@2: template williamr@2: struct ct_if { typedef B type; }; williamr@2: #else williamr@2: template williamr@2: struct ct_if { typedef A type; }; williamr@2: template williamr@2: struct ct_if { typedef B type; }; williamr@2: #endif williamr@2: williamr@2: template williamr@2: struct ct_if_t { typedef ct_if_error type; }; williamr@2: template williamr@2: struct ct_if_t { typedef A type; }; williamr@2: template williamr@2: struct ct_if_t { typedef B type; }; williamr@2: williamr@2: #else williamr@2: williamr@2: namespace detail { williamr@2: williamr@2: template struct IF; williamr@2: template struct SlectSelector; williamr@2: struct SelectFirstType; williamr@2: struct SelectSecondType; williamr@2: williamr@2: struct SelectFirstType { williamr@2: template williamr@2: struct Template { typedef A type; }; williamr@2: }; williamr@2: williamr@2: struct SelectSecondType { williamr@2: template williamr@2: struct Template { typedef B type; }; williamr@2: }; williamr@2: williamr@2: template williamr@2: struct SlectSelector { williamr@2: typedef SelectFirstType type; williamr@2: }; williamr@2: williamr@2: template <> williamr@2: struct SlectSelector<0> { williamr@2: typedef SelectSecondType type; williamr@2: }; williamr@2: williamr@2: } // namespace detail williamr@2: williamr@2: template williamr@2: struct ct_if williamr@2: { williamr@2: typedef typename detail::SlectSelector::type Selector; williamr@2: typedef typename Selector::template Template::type type; williamr@2: }; williamr@2: williamr@2: template williamr@2: struct ct_if_t { williamr@2: typedef typename ct_if::type type; williamr@2: }; williamr@2: williamr@2: #endif williamr@2: williamr@2: } // namespace boost williamr@2: williamr@2: #endif // BOOST_CT_IF_HPP williamr@2: