imgtools/imglib/boostlibrary/boost/mpl/has_xxx.hpp
changeset 2 39c28ec933dd
equal deleted inserted replaced
1:820b22e13ff1 2:39c28ec933dd
       
     1 
       
     2 #ifndef BOOST_MPL_HAS_XXX_HPP_INCLUDED
       
     3 #define BOOST_MPL_HAS_XXX_HPP_INCLUDED
       
     4 
       
     5 // Copyright Aleksey Gurtovoy 2002-2006
       
     6 // Copyright David Abrahams 2002-2003
       
     7 //
       
     8 // Distributed under the Boost Software License, Version 1.0. 
       
     9 // (See accompanying file LICENSE_1_0.txt or copy at 
       
    10 // http://www.boost.org/LICENSE_1_0.txt)
       
    11 //
       
    12 // See http://www.boost.org/libs/mpl for documentation.
       
    13 
       
    14 // $Id: has_xxx.hpp 49273 2008-10-11 06:54:06Z agurtovoy $
       
    15 // $Date: 2008-10-11 02:54:06 -0400 (Sat, 11 Oct 2008) $
       
    16 // $Revision: 49273 $
       
    17 
       
    18 #include <boost/mpl/bool.hpp>
       
    19 #include <boost/mpl/aux_/type_wrapper.hpp>
       
    20 #include <boost/mpl/aux_/yes_no.hpp>
       
    21 #include <boost/mpl/aux_/config/has_xxx.hpp>
       
    22 #include <boost/mpl/aux_/config/msvc_typename.hpp>
       
    23 #include <boost/mpl/aux_/config/msvc.hpp>
       
    24 #include <boost/mpl/aux_/config/static_constant.hpp>
       
    25 #include <boost/mpl/aux_/config/workaround.hpp>
       
    26 
       
    27 #include <boost/preprocessor/cat.hpp>
       
    28 
       
    29 #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) )
       
    30 # include <boost/type_traits/is_class.hpp>
       
    31 #endif
       
    32 
       
    33 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX)
       
    34 
       
    35 #   if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
       
    36 
       
    37 // agurt, 11/sep/02: MSVC-specific version (< 7.1), based on a USENET 
       
    38 // newsgroup's posting by John Madsen (comp.lang.c++.moderated, 
       
    39 // 1999-11-12 19:17:06 GMT); the code is _not_ standard-conforming, but 
       
    40 // it works way more reliably than the SFINAE-based implementation
       
    41 
       
    42 // Modified dwa 8/Oct/02 to handle reference types.
       
    43 
       
    44 #   include <boost/mpl/if.hpp>
       
    45 #   include <boost/mpl/bool.hpp>
       
    46 
       
    47 namespace boost { namespace mpl { namespace aux {
       
    48 
       
    49 struct has_xxx_tag;
       
    50 
       
    51 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
       
    52 template< typename U > struct msvc_incomplete_array
       
    53 {
       
    54     typedef char (&type)[sizeof(U) + 1];
       
    55 };
       
    56 #endif
       
    57 
       
    58 template< typename T >
       
    59 struct msvc_is_incomplete
       
    60 {
       
    61     // MSVC is capable of some kinds of SFINAE.  If U is an incomplete
       
    62     // type, it won't pick the second overload
       
    63     static char tester(...);
       
    64 
       
    65 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
       
    66     template< typename U >
       
    67     static typename msvc_incomplete_array<U>::type tester(type_wrapper<U>);
       
    68 #else
       
    69     template< typename U >
       
    70     static char (& tester(type_wrapper<U>) )[sizeof(U)+1];
       
    71 #endif 
       
    72     
       
    73     BOOST_STATIC_CONSTANT(bool, value = 
       
    74           sizeof(tester(type_wrapper<T>())) == 1
       
    75         );
       
    76 };
       
    77 
       
    78 template<>
       
    79 struct msvc_is_incomplete<int>
       
    80 {
       
    81     BOOST_STATIC_CONSTANT(bool, value = false);
       
    82 };
       
    83 
       
    84 }}}
       
    85 
       
    86 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, default_) \
       
    87 template< typename T, typename name = ::boost::mpl::aux::has_xxx_tag > \
       
    88 struct BOOST_PP_CAT(trait,_impl) : T \
       
    89 { \
       
    90     static boost::mpl::aux::no_tag \
       
    91     test(void(*)(::boost::mpl::aux::has_xxx_tag)); \
       
    92     \
       
    93     static boost::mpl::aux::yes_tag test(...); \
       
    94     \
       
    95     BOOST_STATIC_CONSTANT(bool, value = \
       
    96           sizeof(test(static_cast<void(*)(name)>(0))) \
       
    97             != sizeof(boost::mpl::aux::no_tag) \
       
    98         ); \
       
    99     typedef boost::mpl::bool_<value> type; \
       
   100 }; \
       
   101 \
       
   102 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
       
   103 struct trait \
       
   104     : boost::mpl::if_c< \
       
   105           boost::mpl::aux::msvc_is_incomplete<T>::value \
       
   106         , boost::mpl::bool_<false> \
       
   107         , BOOST_PP_CAT(trait,_impl)<T> \
       
   108         >::type \
       
   109 { \
       
   110 }; \
       
   111 \
       
   112 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, void) \
       
   113 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, bool) \
       
   114 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, char) \
       
   115 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed char) \
       
   116 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned char) \
       
   117 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed short) \
       
   118 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned short) \
       
   119 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed int) \
       
   120 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned int) \
       
   121 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed long) \
       
   122 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned long) \
       
   123 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, float) \
       
   124 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, double) \
       
   125 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, long double) \
       
   126 /**/
       
   127 
       
   128 #   define BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, T) \
       
   129 template<> struct trait<T> \
       
   130 { \
       
   131     BOOST_STATIC_CONSTANT(bool, value = false); \
       
   132     typedef boost::mpl::bool_<false> type; \
       
   133 }; \
       
   134 /**/
       
   135 
       
   136 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
       
   137 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \
       
   138     BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \
       
   139     BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, wchar_t) \
       
   140 /**/
       
   141 #else
       
   142 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \
       
   143     BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \
       
   144 /**/
       
   145 #endif
       
   146 
       
   147 
       
   148 // SFINAE-based implementations below are derived from a USENET newsgroup's 
       
   149 // posting by Rani Sharoni (comp.lang.c++.moderated, 2002-03-17 07:45:09 PST)
       
   150 
       
   151 #   elif BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
       
   152       || BOOST_WORKAROUND(__IBMCPP__, <= 700)
       
   153 
       
   154 // MSVC 7.1+ & VACPP
       
   155 
       
   156 // agurt, 15/jun/05: replace overload-based SFINAE implementation with SFINAE
       
   157 // applied to partial specialization to fix some apparently random failures 
       
   158 // (thanks to Daniel Wallin for researching this!)
       
   159 
       
   160 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
       
   161 template< typename T > \
       
   162 struct BOOST_PP_CAT(trait, _msvc_sfinae_helper) \
       
   163 { \
       
   164     typedef void type; \
       
   165 };\
       
   166 \
       
   167 template< typename T, typename U = void > \
       
   168 struct BOOST_PP_CAT(trait,_impl_) \
       
   169 { \
       
   170     BOOST_STATIC_CONSTANT(bool, value = false); \
       
   171     typedef boost::mpl::bool_<value> type; \
       
   172 }; \
       
   173 \
       
   174 template< typename T > \
       
   175 struct BOOST_PP_CAT(trait,_impl_)< \
       
   176       T \
       
   177     , typename BOOST_PP_CAT(trait, _msvc_sfinae_helper)< typename T::name >::type \
       
   178     > \
       
   179 { \
       
   180     BOOST_STATIC_CONSTANT(bool, value = true); \
       
   181     typedef boost::mpl::bool_<value> type; \
       
   182 }; \
       
   183 \
       
   184 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
       
   185 struct trait \
       
   186     : BOOST_PP_CAT(trait,_impl_)<T> \
       
   187 { \
       
   188 }; \
       
   189 /**/
       
   190 
       
   191 #   elif BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) )
       
   192 
       
   193 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF(trait, trait_tester, name, default_) \
       
   194 template< typename T, bool IS_CLASS > \
       
   195 struct trait_tester \
       
   196 { \
       
   197     BOOST_STATIC_CONSTANT( bool,  value = false ); \
       
   198 }; \
       
   199 template< typename T > \
       
   200 struct trait_tester< T, true > \
       
   201 { \
       
   202     struct trait_tester_impl \
       
   203     { \
       
   204         template < class U > \
       
   205         static int  resolve( boost::mpl::aux::type_wrapper<U> const volatile * \
       
   206                            , boost::mpl::aux::type_wrapper<typename U::name >* = 0 ); \
       
   207         static char resolve( ... ); \
       
   208     }; \
       
   209     typedef boost::mpl::aux::type_wrapper<T> t_; \
       
   210     BOOST_STATIC_CONSTANT( bool, value = ( sizeof( trait_tester_impl::resolve( static_cast< t_ * >(0) ) ) == sizeof(int) ) ); \
       
   211 }; \
       
   212 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
       
   213 struct trait           \
       
   214 {                      \
       
   215     BOOST_STATIC_CONSTANT( bool, value = (trait_tester< T, boost::is_class< T >::value >::value) );     \
       
   216     typedef boost::mpl::bool_< trait< T, fallback_ >::value > type; \
       
   217 };
       
   218 
       
   219 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
       
   220     BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF( trait \
       
   221                                          , BOOST_PP_CAT(trait,_tester)      \
       
   222                                          , name       \
       
   223                                          , default_ ) \
       
   224 /**/
       
   225 
       
   226 #   else // other SFINAE-capable compilers
       
   227 
       
   228 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
       
   229 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
       
   230 struct trait \
       
   231 { \
       
   232     struct gcc_3_2_wknd \
       
   233     { \
       
   234         template< typename U > \
       
   235         static boost::mpl::aux::yes_tag test( \
       
   236               boost::mpl::aux::type_wrapper<U> const volatile* \
       
   237             , boost::mpl::aux::type_wrapper<BOOST_MSVC_TYPENAME U::name>* = 0 \
       
   238             ); \
       
   239     \
       
   240         static boost::mpl::aux::no_tag test(...); \
       
   241     }; \
       
   242     \
       
   243     typedef boost::mpl::aux::type_wrapper<T> t_; \
       
   244     BOOST_STATIC_CONSTANT(bool, value = \
       
   245           sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) \
       
   246             == sizeof(boost::mpl::aux::yes_tag) \
       
   247         ); \
       
   248     typedef boost::mpl::bool_<value> type; \
       
   249 }; \
       
   250 /**/
       
   251 
       
   252 #   endif // BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
       
   253 
       
   254 
       
   255 #else // BOOST_MPL_CFG_NO_HAS_XXX
       
   256 
       
   257 // placeholder implementation
       
   258 
       
   259 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
       
   260 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
       
   261 struct trait \
       
   262 { \
       
   263     BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
       
   264     typedef fallback_ type; \
       
   265 }; \
       
   266 /**/
       
   267 
       
   268 #endif
       
   269 
       
   270 #define BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \
       
   271     BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \
       
   272 /**/
       
   273 
       
   274 #endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED