unique_ptr_meta_utils.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2012-2012.
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // See http://www.boost.org/libs/move for documentation.
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11. //! \file
  12. #ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
  13. #define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
  14. #ifndef BOOST_CONFIG_HPP
  15. # include <boost/config.hpp>
  16. #endif
  17. #
  18. #if defined(BOOST_HAS_PRAGMA_ONCE)
  19. # pragma once
  20. #endif
  21. #include <cstddef> //for std::size_t
  22. //Small meta-typetraits to support move
  23. namespace boost {
  24. namespace movelib {
  25. template <class T>
  26. struct default_delete;
  27. } //namespace movelib {
  28. #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
  29. //Forward declare boost::rv
  30. template <class T> class rv;
  31. #endif
  32. namespace move_upmu {
  33. //////////////////////////////////////
  34. // nat
  35. //////////////////////////////////////
  36. struct nat{};
  37. //////////////////////////////////////
  38. // natify
  39. //////////////////////////////////////
  40. template <class T> struct natify{};
  41. //////////////////////////////////////
  42. // if_c
  43. //////////////////////////////////////
  44. template<bool C, typename T1, typename T2>
  45. struct if_c
  46. {
  47. typedef T1 type;
  48. };
  49. template<typename T1, typename T2>
  50. struct if_c<false,T1,T2>
  51. {
  52. typedef T2 type;
  53. };
  54. //////////////////////////////////////
  55. // if_
  56. //////////////////////////////////////
  57. template<typename T1, typename T2, typename T3>
  58. struct if_ : if_c<0 != T1::value, T2, T3>
  59. {};
  60. //enable_if_
  61. template <bool B, class T = nat>
  62. struct enable_if_c
  63. {
  64. typedef T type;
  65. };
  66. //////////////////////////////////////
  67. // enable_if_c
  68. //////////////////////////////////////
  69. template <class T>
  70. struct enable_if_c<false, T> {};
  71. //////////////////////////////////////
  72. // enable_if
  73. //////////////////////////////////////
  74. template <class Cond, class T = nat>
  75. struct enable_if : public enable_if_c<Cond::value, T> {};
  76. //////////////////////////////////////
  77. // remove_reference
  78. //////////////////////////////////////
  79. template<class T>
  80. struct remove_reference
  81. {
  82. typedef T type;
  83. };
  84. template<class T>
  85. struct remove_reference<T&>
  86. {
  87. typedef T type;
  88. };
  89. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  90. template<class T>
  91. struct remove_reference<T&&>
  92. {
  93. typedef T type;
  94. };
  95. #else
  96. template<class T>
  97. struct remove_reference< rv<T> >
  98. {
  99. typedef T type;
  100. };
  101. template<class T>
  102. struct remove_reference< rv<T> &>
  103. {
  104. typedef T type;
  105. };
  106. template<class T>
  107. struct remove_reference< const rv<T> &>
  108. {
  109. typedef T type;
  110. };
  111. #endif
  112. //////////////////////////////////////
  113. // remove_const
  114. //////////////////////////////////////
  115. template< class T >
  116. struct remove_const
  117. {
  118. typedef T type;
  119. };
  120. template< class T >
  121. struct remove_const<const T>
  122. {
  123. typedef T type;
  124. };
  125. //////////////////////////////////////
  126. // remove_volatile
  127. //////////////////////////////////////
  128. template< class T >
  129. struct remove_volatile
  130. {
  131. typedef T type;
  132. };
  133. template< class T >
  134. struct remove_volatile<volatile T>
  135. {
  136. typedef T type;
  137. };
  138. //////////////////////////////////////
  139. // remove_cv
  140. //////////////////////////////////////
  141. template< class T >
  142. struct remove_cv
  143. {
  144. typedef typename remove_volatile
  145. <typename remove_const<T>::type>::type type;
  146. };
  147. //////////////////////////////////////
  148. // remove_extent
  149. //////////////////////////////////////
  150. template<class T>
  151. struct remove_extent
  152. {
  153. typedef T type;
  154. };
  155. template<class T>
  156. struct remove_extent<T[]>
  157. {
  158. typedef T type;
  159. };
  160. template<class T, std::size_t N>
  161. struct remove_extent<T[N]>
  162. {
  163. typedef T type;
  164. };
  165. //////////////////////////////////////
  166. // extent
  167. //////////////////////////////////////
  168. template<class T, unsigned N = 0>
  169. struct extent
  170. {
  171. static const std::size_t value = 0;
  172. };
  173. template<class T>
  174. struct extent<T[], 0>
  175. {
  176. static const std::size_t value = 0;
  177. };
  178. template<class T, unsigned N>
  179. struct extent<T[], N>
  180. {
  181. static const std::size_t value = extent<T, N-1>::value;
  182. };
  183. template<class T, std::size_t N>
  184. struct extent<T[N], 0>
  185. {
  186. static const std::size_t value = N;
  187. };
  188. template<class T, std::size_t I, unsigned N>
  189. struct extent<T[I], N>
  190. {
  191. static const std::size_t value = extent<T, N-1>::value;
  192. };
  193. //////////////////////////////////////
  194. // add_lvalue_reference
  195. //////////////////////////////////////
  196. template<class T>
  197. struct add_lvalue_reference
  198. {
  199. typedef T& type;
  200. };
  201. template<class T>
  202. struct add_lvalue_reference<T&>
  203. {
  204. typedef T& type;
  205. };
  206. template<>
  207. struct add_lvalue_reference<void>
  208. {
  209. typedef void type;
  210. };
  211. template<>
  212. struct add_lvalue_reference<const void>
  213. {
  214. typedef const void type;
  215. };
  216. template<>
  217. struct add_lvalue_reference<volatile void>
  218. {
  219. typedef volatile void type;
  220. };
  221. template<>
  222. struct add_lvalue_reference<const volatile void>
  223. {
  224. typedef const volatile void type;
  225. };
  226. template<class T>
  227. struct add_const_lvalue_reference
  228. {
  229. typedef typename remove_reference<T>::type t_unreferenced;
  230. typedef const t_unreferenced t_unreferenced_const;
  231. typedef typename add_lvalue_reference
  232. <t_unreferenced_const>::type type;
  233. };
  234. //////////////////////////////////////
  235. // is_same
  236. //////////////////////////////////////
  237. template<class T, class U>
  238. struct is_same
  239. {
  240. static const bool value = false;
  241. };
  242. template<class T>
  243. struct is_same<T, T>
  244. {
  245. static const bool value = true;
  246. };
  247. //////////////////////////////////////
  248. // is_pointer
  249. //////////////////////////////////////
  250. template< class T >
  251. struct is_pointer
  252. {
  253. static const bool value = false;
  254. };
  255. template< class T >
  256. struct is_pointer<T*>
  257. {
  258. static const bool value = true;
  259. };
  260. //////////////////////////////////////
  261. // is_reference
  262. //////////////////////////////////////
  263. template< class T >
  264. struct is_reference
  265. {
  266. static const bool value = false;
  267. };
  268. template< class T >
  269. struct is_reference<T&>
  270. {
  271. static const bool value = true;
  272. };
  273. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  274. template< class T >
  275. struct is_reference<T&&>
  276. {
  277. static const bool value = true;
  278. };
  279. #endif
  280. //////////////////////////////////////
  281. // is_lvalue_reference
  282. //////////////////////////////////////
  283. template<class T>
  284. struct is_lvalue_reference
  285. {
  286. static const bool value = false;
  287. };
  288. template<class T>
  289. struct is_lvalue_reference<T&>
  290. {
  291. static const bool value = true;
  292. };
  293. //////////////////////////////////////
  294. // is_array
  295. //////////////////////////////////////
  296. template<class T>
  297. struct is_array
  298. {
  299. static const bool value = false;
  300. };
  301. template<class T>
  302. struct is_array<T[]>
  303. {
  304. static const bool value = true;
  305. };
  306. template<class T, std::size_t N>
  307. struct is_array<T[N]>
  308. {
  309. static const bool value = true;
  310. };
  311. //////////////////////////////////////
  312. // has_pointer_type
  313. //////////////////////////////////////
  314. template <class T>
  315. struct has_pointer_type
  316. {
  317. struct two { char c[2]; };
  318. template <class U> static two test(...);
  319. template <class U> static char test(typename U::pointer* = 0);
  320. static const bool value = sizeof(test<T>(0)) == 1;
  321. };
  322. //////////////////////////////////////
  323. // pointer_type
  324. //////////////////////////////////////
  325. template <class T, class D, bool = has_pointer_type<D>::value>
  326. struct pointer_type_imp
  327. {
  328. typedef typename D::pointer type;
  329. };
  330. template <class T, class D>
  331. struct pointer_type_imp<T, D, false>
  332. {
  333. typedef T* type;
  334. };
  335. template <class T, class D>
  336. struct pointer_type
  337. {
  338. typedef typename pointer_type_imp
  339. <typename remove_extent<T>::type, typename remove_reference<D>::type>::type type;
  340. };
  341. //////////////////////////////////////
  342. // is_convertible
  343. //////////////////////////////////////
  344. #if defined(_MSC_VER) && (_MSC_VER >= 1400)
  345. //use intrinsic since in MSVC
  346. //overaligned types can't go through ellipsis
  347. template <class T, class U>
  348. struct is_convertible
  349. {
  350. static const bool value = __is_convertible_to(T, U);
  351. };
  352. #else
  353. template <class T, class U>
  354. class is_convertible
  355. {
  356. typedef typename add_lvalue_reference<T>::type t_reference;
  357. typedef char true_t;
  358. class false_t { char dummy[2]; };
  359. static false_t dispatch(...);
  360. static true_t dispatch(U);
  361. static t_reference trigger();
  362. public:
  363. static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
  364. };
  365. #endif
  366. //////////////////////////////////////
  367. // is_unary_function
  368. //////////////////////////////////////
  369. #if defined(BOOST_MSVC) || defined(__BORLANDC_)
  370. #define BOOST_MOVE_TT_DECL __cdecl
  371. #else
  372. #define BOOST_MOVE_TT_DECL
  373. #endif
  374. #if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(UNDER_CE)
  375. #define BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
  376. #endif
  377. template <typename T>
  378. struct is_unary_function_impl
  379. { static const bool value = false; };
  380. // avoid duplicate definitions of is_unary_function_impl
  381. #ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
  382. template <typename R>
  383. struct is_unary_function_impl<R (*)()>
  384. { static const bool value = true; };
  385. template <typename R>
  386. struct is_unary_function_impl<R (*)(...)>
  387. { static const bool value = true; };
  388. #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
  389. template <typename R>
  390. struct is_unary_function_impl<R (__stdcall*)()>
  391. { static const bool value = true; };
  392. #ifndef _MANAGED
  393. template <typename R>
  394. struct is_unary_function_impl<R (__fastcall*)()>
  395. { static const bool value = true; };
  396. #endif
  397. template <typename R>
  398. struct is_unary_function_impl<R (__cdecl*)()>
  399. { static const bool value = true; };
  400. template <typename R>
  401. struct is_unary_function_impl<R (__cdecl*)(...)>
  402. { static const bool value = true; };
  403. #endif
  404. // avoid duplicate definitions of is_unary_function_impl
  405. #ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
  406. template <typename R, class T0>
  407. struct is_unary_function_impl<R (*)(T0)>
  408. { static const bool value = true; };
  409. template <typename R, class T0>
  410. struct is_unary_function_impl<R (*)(T0...)>
  411. { static const bool value = true; };
  412. #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
  413. template <typename R, class T0>
  414. struct is_unary_function_impl<R (__stdcall*)(T0)>
  415. { static const bool value = true; };
  416. #ifndef _MANAGED
  417. template <typename R, class T0>
  418. struct is_unary_function_impl<R (__fastcall*)(T0)>
  419. { static const bool value = true; };
  420. #endif
  421. template <typename R, class T0>
  422. struct is_unary_function_impl<R (__cdecl*)(T0)>
  423. { static const bool value = true; };
  424. template <typename R, class T0>
  425. struct is_unary_function_impl<R (__cdecl*)(T0...)>
  426. { static const bool value = true; };
  427. #endif
  428. template <typename T>
  429. struct is_unary_function_impl<T&>
  430. { static const bool value = false; };
  431. template<typename T>
  432. struct is_unary_function
  433. { static const bool value = is_unary_function_impl<T>::value; };
  434. //////////////////////////////////////
  435. // has_virtual_destructor
  436. //////////////////////////////////////
  437. #if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
  438. || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
  439. # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
  440. #elif defined(BOOST_CLANG) && defined(__has_feature)
  441. # if __has_feature(has_virtual_destructor)
  442. # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
  443. # endif
  444. #elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
  445. # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
  446. #elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
  447. # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
  448. #elif defined(__CODEGEARC__)
  449. # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
  450. #endif
  451. #ifdef BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR
  452. template<class T>
  453. struct has_virtual_destructor{ static const bool value = BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T); };
  454. #else
  455. //If no intrinsic is available you trust the programmer knows what is doing
  456. template<class T>
  457. struct has_virtual_destructor{ static const bool value = true; };
  458. #endif
  459. //////////////////////////////////////
  460. // missing_virtual_destructor
  461. //////////////////////////////////////
  462. template< class T, class U
  463. , bool enable = is_convertible< U*, T*>::value &&
  464. !is_array<T>::value &&
  465. !is_same<typename remove_cv<T>::type, void>::value &&
  466. !is_same<typename remove_cv<U>::type, typename remove_cv<T>::type>::value
  467. >
  468. struct missing_virtual_destructor_default_delete
  469. { static const bool value = !has_virtual_destructor<T>::value; };
  470. template<class T, class U>
  471. struct missing_virtual_destructor_default_delete<T, U, false>
  472. { static const bool value = false; };
  473. template<class Deleter, class U>
  474. struct missing_virtual_destructor
  475. { static const bool value = false; };
  476. template<class T, class U>
  477. struct missing_virtual_destructor< ::boost::movelib::default_delete<T>, U >
  478. : missing_virtual_destructor_default_delete<T, U>
  479. {};
  480. } //namespace move_upmu {
  481. } //namespace boost {
  482. #endif //#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP