meta_utils.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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_DETAIL_META_UTILS_HPP
  13. #define BOOST_MOVE_DETAIL_META_UTILS_HPP
  14. #include <boost/move/detail/config_begin.hpp>
  15. //Small meta-typetraits to support move
  16. namespace boost {
  17. namespace move_detail {
  18. //if_
  19. template<bool C, typename T1, typename T2>
  20. struct if_c
  21. {
  22. typedef T1 type;
  23. };
  24. template<typename T1, typename T2>
  25. struct if_c<false,T1,T2>
  26. {
  27. typedef T2 type;
  28. };
  29. template<typename T1, typename T2, typename T3>
  30. struct if_
  31. {
  32. typedef typename if_c<0 != T1::value, T2, T3>::type type;
  33. };
  34. //enable_if_
  35. template <bool B, class T = void>
  36. struct enable_if_c
  37. {
  38. typedef T type;
  39. };
  40. template <class T>
  41. struct enable_if_c<false, T> {};
  42. template <class Cond, class T = void>
  43. struct enable_if : public enable_if_c<Cond::value, T> {};
  44. template <class Cond, class T = void>
  45. struct disable_if : public enable_if_c<!Cond::value, T> {};
  46. //integral_constant
  47. template<class T, T v>
  48. struct integral_constant
  49. {
  50. static const T value = v;
  51. typedef T value_type;
  52. typedef integral_constant<T, v> type;
  53. };
  54. //identity
  55. template <class T>
  56. struct identity
  57. {
  58. typedef T type;
  59. };
  60. //is_convertible
  61. template <class T, class U>
  62. class is_convertible
  63. {
  64. typedef char true_t;
  65. class false_t { char dummy[2]; };
  66. static true_t dispatch(U);
  67. static false_t dispatch(...);
  68. static T &trigger();
  69. public:
  70. enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
  71. };
  72. //and_ not_
  73. template <typename Condition1, typename Condition2, typename Condition3 = integral_constant<bool, true> >
  74. struct and_
  75. : public integral_constant<bool, Condition1::value && Condition2::value && Condition3::value>
  76. {};
  77. template <typename Boolean>
  78. struct not_
  79. : public integral_constant<bool, !Boolean::value>
  80. {};
  81. //is_lvalue_reference
  82. template<class T>
  83. struct is_lvalue_reference
  84. : public integral_constant<bool, false>
  85. {};
  86. template<class T>
  87. struct is_lvalue_reference<T&>
  88. : public integral_constant<bool, true>
  89. {};
  90. template<class T>
  91. struct is_class_or_union
  92. {
  93. struct twochar { char _[2]; };
  94. template <class U>
  95. static char is_class_or_union_tester(void(U::*)(void));
  96. template <class U>
  97. static twochar is_class_or_union_tester(...);
  98. static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
  99. };
  100. struct empty{};
  101. //addressof
  102. template<class T> struct addr_impl_ref
  103. {
  104. T & v_;
  105. inline addr_impl_ref( T & v ): v_( v ) {}
  106. inline operator T& () const { return v_; }
  107. private:
  108. addr_impl_ref & operator=(const addr_impl_ref &);
  109. };
  110. template<class T> struct addressof_impl
  111. {
  112. static inline T * f( T & v, long )
  113. {
  114. return reinterpret_cast<T*>(
  115. &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
  116. }
  117. static inline T * f( T * v, int )
  118. { return v; }
  119. };
  120. template<class T>
  121. inline T * addressof( T & v )
  122. {
  123. return ::boost::move_detail::addressof_impl<T>::f
  124. ( ::boost::move_detail::addr_impl_ref<T>( v ), 0 );
  125. }
  126. } //namespace move_detail {
  127. } //namespace boost {
  128. #include <boost/move/detail/config_end.hpp>
  129. #endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP