1 // Copyright David Abrahams 2002. 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 #ifndef INDIRECT_TRAITS_DWA2002131_HPP 6 # define INDIRECT_TRAITS_DWA2002131_HPP 7 # include <boost/type_traits/is_function.hpp> 8 # include <boost/type_traits/is_reference.hpp> 9 # include <boost/type_traits/is_pointer.hpp> 10 # include <boost/type_traits/is_class.hpp> 11 # include <boost/type_traits/is_const.hpp> 12 # include <boost/type_traits/is_volatile.hpp> 13 # include <boost/type_traits/is_member_function_pointer.hpp> 14 # include <boost/type_traits/is_member_pointer.hpp> 15 # include <boost/type_traits/remove_cv.hpp> 16 # include <boost/type_traits/remove_reference.hpp> 17 # include <boost/type_traits/remove_pointer.hpp> 18 19 # include <boost/type_traits/detail/ice_and.hpp> 20 # include <boost/detail/workaround.hpp> 21 22 # include <boost/mpl/eval_if.hpp> 23 # include <boost/mpl/if.hpp> 24 # include <boost/mpl/bool.hpp> 25 # include <boost/mpl/and.hpp> 26 # include <boost/mpl/not.hpp> 27 # include <boost/mpl/aux_/lambda_support.hpp> 28 29 # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 30 # include <boost/detail/is_function_ref_tester.hpp> 31 # endif 32 33 namespace boost { namespace detail { 34 35 namespace indirect_traits { 36 37 # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 38 template <class T> 39 struct is_reference_to_const : mpl::false_ 40 { 41 }; 42 43 template <class T> 44 struct is_reference_to_const<T const&> : mpl::true_ 45 { 46 }; 47 48 # if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround 49 template<class T> 50 struct is_reference_to_const<T const volatile&> : mpl::true_ 51 { 52 }; 53 # endif 54 55 template <class T> 56 struct is_reference_to_function : mpl::false_ 57 { 58 }; 59 60 template <class T> 61 struct is_reference_to_function<T&> : is_function<T> 62 { 63 }; 64 65 template <class T> 66 struct is_pointer_to_function : mpl::false_ 67 { 68 }; 69 70 // There's no such thing as a pointer-to-cv-function, so we don't need 71 // specializations for those 72 template <class T> 73 struct is_pointer_to_function<T*> : is_function<T> 74 { 75 }; 76 77 template <class T> 78 struct is_reference_to_member_function_pointer_impl : mpl::false_ 79 { 80 }; 81 82 template <class T> 83 struct is_reference_to_member_function_pointer_impl<T&> 84 : is_member_function_pointer<typename remove_cv<T>::type> 85 { 86 }; 87 88 89 template <class T> 90 struct is_reference_to_member_function_pointer 91 : is_reference_to_member_function_pointer_impl<T> 92 { 93 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) 94 }; 95 96 template <class T> 97 struct is_reference_to_function_pointer_aux 98 : mpl::and_< 99 is_reference<T> 100 , is_pointer_to_function< 101 typename remove_cv< 102 typename remove_reference<T>::type 103 >::type 104 > 105 > 106 { 107 // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those 108 }; 109 110 template <class T> 111 struct is_reference_to_function_pointer 112 : mpl::if_< 113 is_reference_to_function<T> 114 , mpl::false_ 115 , is_reference_to_function_pointer_aux<T> 116 >::type 117 { 118 }; 119 120 template <class T> 121 struct is_reference_to_non_const 122 : mpl::and_< 123 is_reference<T> 124 , mpl::not_< 125 is_reference_to_const<T> 126 > 127 > 128 { 129 }; 130 131 template <class T> 132 struct is_reference_to_volatile : mpl::false_ 133 { 134 }; 135 136 template <class T> 137 struct is_reference_to_volatile<T volatile&> : mpl::true_ 138 { 139 }; 140 141 # if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround 142 template <class T> 143 struct is_reference_to_volatile<T const volatile&> : mpl::true_ 144 { 145 }; 146 # endif 147 148 149 template <class T> 150 struct is_reference_to_pointer : mpl::false_ 151 { 152 }; 153 154 template <class T> 155 struct is_reference_to_pointer<T*&> : mpl::true_ 156 { 157 }; 158 159 template <class T> 160 struct is_reference_to_pointer<T* const&> : mpl::true_ 161 { 162 }; 163 164 template <class T> 165 struct is_reference_to_pointer<T* volatile&> : mpl::true_ 166 { 167 }; 168 169 template <class T> 170 struct is_reference_to_pointer<T* const volatile&> : mpl::true_ 171 { 172 }; 173 174 template <class T> 175 struct is_reference_to_class 176 : mpl::and_< 177 is_reference<T> 178 , is_class< 179 typename remove_cv< 180 typename remove_reference<T>::type 181 >::type 182 > 183 > 184 { 185 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) 186 }; 187 188 template <class T> 189 struct is_pointer_to_class 190 : mpl::and_< 191 is_pointer<T> 192 , is_class< 193 typename remove_cv< 194 typename remove_pointer<T>::type 195 >::type 196 > 197 > 198 { 199 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T)) 200 }; 201 202 # else 203 204 using namespace boost::detail::is_function_ref_tester_; 205 206 typedef char (&inner_yes_type)[3]; 207 typedef char (&inner_no_type)[2]; 208 typedef char (&outer_no_type)[1]; 209 210 template <typename V> 211 struct is_const_help 212 { 213 typedef typename mpl::if_< 214 is_const<V> 215 , inner_yes_type 216 , inner_no_type 217 >::type type; 218 }; 219 220 template <typename V> 221 struct is_volatile_help 222 { 223 typedef typename mpl::if_< 224 is_volatile<V> 225 , inner_yes_type 226 , inner_no_type 227 >::type type; 228 }; 229 230 template <typename V> 231 struct is_pointer_help 232 { 233 typedef typename mpl::if_< 234 is_pointer<V> 235 , inner_yes_type 236 , inner_no_type 237 >::type type; 238 }; 239 240 template <typename V> 241 struct is_class_help 242 { 243 typedef typename mpl::if_< 244 is_class<V> 245 , inner_yes_type 246 , inner_no_type 247 >::type type; 248 }; 249 250 template <class T> 251 struct is_reference_to_function_aux 252 { 253 static T t; 254 BOOST_STATIC_CONSTANT( 255 bool, value = sizeof(detail::is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type)); 256 typedef mpl::bool_<value> type; 257 }; 258 259 template <class T> 260 struct is_reference_to_function 261 : mpl::if_<is_reference<T>, is_reference_to_function_aux<T>, mpl::bool_<false> >::type 262 { 263 }; 264 265 template <class T> 266 struct is_pointer_to_function_aux 267 { 268 static T t; 269 BOOST_STATIC_CONSTANT( 270 bool, value 271 = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); 272 typedef mpl::bool_<value> type; 273 }; 274 275 template <class T> 276 struct is_pointer_to_function 277 : mpl::if_<is_pointer<T>, is_pointer_to_function_aux<T>, mpl::bool_<false> >::type 278 { 279 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) 280 }; 281 282 struct false_helper1 283 { 284 template <class T> 285 struct apply : mpl::false_ 286 { 287 }; 288 }; 289 290 template <typename V> 291 typename is_const_help<V>::type reference_to_const_helper(V&); 292 outer_no_type 293 reference_to_const_helper(...); 294 295 struct true_helper1 296 { 297 template <class T> 298 struct apply 299 { 300 static T t; 301 BOOST_STATIC_CONSTANT( 302 bool, value 303 = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); 304 typedef mpl::bool_<value> type; 305 }; 306 }; 307 308 template <bool ref = true> 309 struct is_reference_to_const_helper1 : true_helper1 310 { 311 }; 312 313 template <> 314 struct is_reference_to_const_helper1<false> : false_helper1 315 { 316 }; 317 318 319 template <class T> 320 struct is_reference_to_const 321 : is_reference_to_const_helper1<is_reference<T>::value>::template apply<T> 322 { 323 }; 324 325 326 template <bool ref = true> 327 struct is_reference_to_non_const_helper1 328 { 329 template <class T> 330 struct apply 331 { 332 static T t; 333 BOOST_STATIC_CONSTANT( 334 bool, value 335 = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)); 336 337 typedef mpl::bool_<value> type; 338 }; 339 }; 340 341 template <> 342 struct is_reference_to_non_const_helper1<false> : false_helper1 343 { 344 }; 345 346 347 template <class T> 348 struct is_reference_to_non_const 349 : is_reference_to_non_const_helper1<is_reference<T>::value>::template apply<T> 350 { 351 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_non_const,(T)) 352 }; 353 354 355 template <typename V> 356 typename is_volatile_help<V>::type reference_to_volatile_helper(V&); 357 outer_no_type 358 reference_to_volatile_helper(...); 359 360 template <bool ref = true> 361 struct is_reference_to_volatile_helper1 362 { 363 template <class T> 364 struct apply 365 { 366 static T t; 367 BOOST_STATIC_CONSTANT( 368 bool, value 369 = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)); 370 typedef mpl::bool_<value> type; 371 }; 372 }; 373 374 template <> 375 struct is_reference_to_volatile_helper1<false> : false_helper1 376 { 377 }; 378 379 380 template <class T> 381 struct is_reference_to_volatile 382 : is_reference_to_volatile_helper1<is_reference<T>::value>::template apply<T> 383 { 384 }; 385 386 template <typename V> 387 typename is_pointer_help<V>::type reference_to_pointer_helper(V&); 388 outer_no_type reference_to_pointer_helper(...); 389 390 template <class T> 391 struct reference_to_pointer_impl 392 { 393 static T t; 394 BOOST_STATIC_CONSTANT( 395 bool, value 396 = (sizeof((reference_to_pointer_helper)(t)) == sizeof(inner_yes_type)) 397 ); 398 399 typedef mpl::bool_<value> type; 400 }; 401 402 template <class T> 403 struct is_reference_to_pointer 404 : mpl::eval_if<is_reference<T>, reference_to_pointer_impl<T>, mpl::false_>::type 405 { 406 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_pointer,(T)) 407 }; 408 409 template <class T> 410 struct is_reference_to_function_pointer 411 : mpl::eval_if<is_reference<T>, is_pointer_to_function_aux<T>, mpl::false_>::type 412 { 413 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) 414 }; 415 416 417 template <class T> 418 struct is_member_function_pointer_help 419 : mpl::if_<is_member_function_pointer<T>, inner_yes_type, inner_no_type> 420 {}; 421 422 template <typename V> 423 typename is_member_function_pointer_help<V>::type member_function_pointer_helper(V&); 424 outer_no_type member_function_pointer_helper(...); 425 426 template <class T> 427 struct is_pointer_to_member_function_aux 428 { 429 static T t; 430 BOOST_STATIC_CONSTANT( 431 bool, value 432 = sizeof((member_function_pointer_helper)(t)) == sizeof(inner_yes_type)); 433 typedef mpl::bool_<value> type; 434 }; 435 436 template <class T> 437 struct is_reference_to_member_function_pointer 438 : mpl::if_< 439 is_reference<T> 440 , is_pointer_to_member_function_aux<T> 441 , mpl::bool_<false> 442 >::type 443 { 444 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) 445 }; 446 447 template <typename V> 448 typename is_class_help<V>::type reference_to_class_helper(V const volatile&); 449 outer_no_type reference_to_class_helper(...); 450 451 template <class T> 452 struct is_reference_to_class 453 { 454 static T t; 455 BOOST_STATIC_CONSTANT( 456 bool, value 457 = (is_reference<T>::value 458 & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))) 459 ); 460 typedef mpl::bool_<value> type; 461 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) 462 }; 463 464 template <typename V> 465 typename is_class_help<V>::type pointer_to_class_helper(V const volatile*); 466 outer_no_type pointer_to_class_helper(...); 467 468 template <class T> 469 struct is_pointer_to_class 470 { 471 static T t; 472 BOOST_STATIC_CONSTANT( 473 bool, value 474 = (is_pointer<T>::value 475 && sizeof(pointer_to_class_helper(t)) == sizeof(inner_yes_type)) 476 ); 477 typedef mpl::bool_<value> type; 478 }; 479 # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 480 481 } 482 483 using namespace indirect_traits; 484 485 }} // namespace boost::python::detail 486 487 #endif // INDIRECT_TRAITS_DWA2002131_HPP 488