builtin.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Boost.TypeErasure library
  2. //
  3. // Copyright 2011 Steven Watanabe
  4. //
  5. // Distributed under the Boost Software License Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // $Id$
  10. #ifndef BOOST_TYPE_ERASURE_BUILTIN_HPP_INCLUDED
  11. #define BOOST_TYPE_ERASURE_BUILTIN_HPP_INCLUDED
  12. #include <boost/mpl/vector.hpp>
  13. #include <boost/utility/enable_if.hpp>
  14. #include <boost/type_traits/is_reference.hpp>
  15. #include <boost/type_erasure/detail/storage.hpp>
  16. #include <boost/type_erasure/placeholder.hpp>
  17. #include <boost/type_erasure/constructible.hpp>
  18. #include <boost/type_erasure/rebind_any.hpp>
  19. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  20. # include <utility> // std::move
  21. #endif
  22. #include <typeinfo>
  23. namespace boost {
  24. namespace type_erasure {
  25. /**
  26. * The @ref destructible concept enables forwarding to
  27. * the destructor of the contained type. This is required
  28. * whenever an @ref any is created by value.
  29. *
  30. * \note The @ref destructible concept rarely needs to
  31. * be specified explicitly, because it is included in
  32. * the @ref copy_constructible concept.
  33. *
  34. * \note @ref destructible may not be specialized and
  35. * may not be passed to \call as it depends on the
  36. * implementation details of @ref any.
  37. */
  38. template<class T = _self>
  39. struct destructible
  40. {
  41. /** INTERNAL ONLY */
  42. typedef void (*type)(detail::storage&);
  43. /** INTERNAL ONLY */
  44. static void value(detail::storage& arg)
  45. {
  46. delete static_cast<T*>(arg.data);
  47. }
  48. /** INTERNAL ONLY */
  49. static void apply(detail::storage& arg)
  50. {
  51. delete static_cast<T*>(arg.data);
  52. }
  53. };
  54. /**
  55. * The @ref copy_constructible concept allows objects to
  56. * be copied and destroyed.
  57. *
  58. * \note This concept is defined to match C++ 2003,
  59. * [lib.copyconstructible]. It is not equivalent to
  60. * the concept of the same name in C++11.
  61. */
  62. template<class T = _self>
  63. struct copy_constructible :
  64. ::boost::mpl::vector<constructible<T(const T&)>, destructible<T> >
  65. {};
  66. #ifdef BOOST_TYPE_ERASURE_DOXYGEN
  67. /**
  68. * Enables assignment of @ref any types.
  69. */
  70. template<class T = _self, class U = const T&>
  71. struct assignable
  72. {
  73. static void apply(T& dst, U src);
  74. };
  75. #else
  76. /**
  77. * Enables assignment of @ref any types.
  78. */
  79. template<class T = _self, class U = const T&>
  80. struct assignable :
  81. ::boost::mpl::vector<assignable<T, const U&> >
  82. {};
  83. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  84. /** INTERNAL ONLY */
  85. template<class T, class U>
  86. struct assignable<T, U&&>
  87. {
  88. static void apply(T& dst, U&& src) { dst = std::forward<U>(src); }
  89. };
  90. #endif
  91. /** INTERNAL ONLY */
  92. template<class T, class U>
  93. struct assignable<T, U&>
  94. {
  95. static void apply(T& dst, U& src) { dst = src; }
  96. };
  97. /** INTERNAL ONLY */
  98. template<class T, class U, class Base>
  99. struct concept_interface<assignable<T, U>, Base, T,
  100. typename ::boost::enable_if_c< ::boost::is_reference<U>::value>::type> : Base
  101. {
  102. using Base::_boost_type_erasure_deduce_assign;
  103. assignable<T, U>* _boost_type_erasure_deduce_assign(
  104. typename ::boost::type_erasure::as_param<Base, U>::type)
  105. {
  106. return 0;
  107. }
  108. };
  109. #endif
  110. /**
  111. * Enables runtime type information. This is required
  112. * if you want to use \any_cast or \typeid_of.
  113. *
  114. * \note @ref typeid_ cannot be specialized because several
  115. * library components including \any_cast would not work
  116. * correctly if its behavior changed. There is no need
  117. * to specialize it anyway, since it works for all types.
  118. * @ref typeid_ also cannot be passed to \call. To access it,
  119. * use \typeid_of.
  120. */
  121. template<class T = _self>
  122. struct typeid_
  123. {
  124. /** INTERNAL ONLY */
  125. typedef const std::type_info& (*type)();
  126. /** INTERNAL ONLY */
  127. static const std::type_info& value()
  128. {
  129. return typeid(T);
  130. }
  131. /** INTERNAL ONLY */
  132. static const std::type_info& apply()
  133. {
  134. return typeid(T);
  135. }
  136. };
  137. namespace detail {
  138. template<class C>
  139. struct get_null_vtable_entry;
  140. template<class T>
  141. struct get_null_vtable_entry< ::boost::type_erasure::typeid_<T> >
  142. {
  143. typedef typeid_<void> type;
  144. };
  145. struct null_destroy {
  146. static void value(::boost::type_erasure::detail::storage&) {}
  147. };
  148. template<class T>
  149. struct get_null_vtable_entry< ::boost::type_erasure::destructible<T> >
  150. {
  151. typedef ::boost::type_erasure::detail::null_destroy type;
  152. };
  153. }
  154. }
  155. }
  156. #endif