indirect_traits.hpp 11 KB

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