ebo_functor_holder.hpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Joaquin M Lopez Munoz 2006-2013
  4. // (C) Copyright Ion Gaztanaga 2014-2014
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // See http://www.boost.org/libs/intrusive for documentation.
  11. //
  12. /////////////////////////////////////////////////////////////////////////////
  13. #ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
  14. #define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
  15. #ifndef BOOST_CONFIG_HPP
  16. # include <boost/config.hpp>
  17. #endif
  18. #if defined(BOOST_HAS_PRAGMA_ONCE)
  19. # pragma once
  20. #endif
  21. #include <boost/intrusive/detail/workaround.hpp>
  22. #include <boost/move/utility_core.hpp>
  23. namespace boost {
  24. namespace intrusive {
  25. namespace detail {
  26. #if defined(BOOST_MSVC) || defined(__BORLANDC_)
  27. #define BOOST_INTRUSIVE_TT_DECL __cdecl
  28. #else
  29. #define BOOST_INTRUSIVE_TT_DECL
  30. #endif
  31. #if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(UNDER_CE)
  32. #define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
  33. #endif
  34. template <typename T>
  35. struct is_unary_or_binary_function_impl
  36. { static const bool value = false; };
  37. // see boost ticket #4094
  38. // avoid duplicate definitions of is_unary_or_binary_function_impl
  39. #ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
  40. template <typename R>
  41. struct is_unary_or_binary_function_impl<R (*)()>
  42. { static const bool value = true; };
  43. template <typename R>
  44. struct is_unary_or_binary_function_impl<R (*)(...)>
  45. { static const bool value = true; };
  46. #else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
  47. template <typename R>
  48. struct is_unary_or_binary_function_impl<R (__stdcall*)()>
  49. { static const bool value = true; };
  50. #ifndef _MANAGED
  51. template <typename R>
  52. struct is_unary_or_binary_function_impl<R (__fastcall*)()>
  53. { static const bool value = true; };
  54. #endif
  55. template <typename R>
  56. struct is_unary_or_binary_function_impl<R (__cdecl*)()>
  57. { static const bool value = true; };
  58. template <typename R>
  59. struct is_unary_or_binary_function_impl<R (__cdecl*)(...)>
  60. { static const bool value = true; };
  61. #endif
  62. // see boost ticket #4094
  63. // avoid duplicate definitions of is_unary_or_binary_function_impl
  64. #ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
  65. template <typename R, class T0>
  66. struct is_unary_or_binary_function_impl<R (*)(T0)>
  67. { static const bool value = true; };
  68. template <typename R, class T0>
  69. struct is_unary_or_binary_function_impl<R (*)(T0...)>
  70. { static const bool value = true; };
  71. #else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
  72. template <typename R, class T0>
  73. struct is_unary_or_binary_function_impl<R (__stdcall*)(T0)>
  74. { static const bool value = true; };
  75. #ifndef _MANAGED
  76. template <typename R, class T0>
  77. struct is_unary_or_binary_function_impl<R (__fastcall*)(T0)>
  78. { static const bool value = true; };
  79. #endif
  80. template <typename R, class T0>
  81. struct is_unary_or_binary_function_impl<R (__cdecl*)(T0)>
  82. { static const bool value = true; };
  83. template <typename R, class T0>
  84. struct is_unary_or_binary_function_impl<R (__cdecl*)(T0...)>
  85. { static const bool value = true; };
  86. #endif
  87. // see boost ticket #4094
  88. // avoid duplicate definitions of is_unary_or_binary_function_impl
  89. #ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
  90. template <typename R, class T0, class T1>
  91. struct is_unary_or_binary_function_impl<R (*)(T0, T1)>
  92. { static const bool value = true; };
  93. template <typename R, class T0, class T1>
  94. struct is_unary_or_binary_function_impl<R (*)(T0, T1...)>
  95. { static const bool value = true; };
  96. #else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
  97. template <typename R, class T0, class T1>
  98. struct is_unary_or_binary_function_impl<R (__stdcall*)(T0, T1)>
  99. { static const bool value = true; };
  100. #ifndef _MANAGED
  101. template <typename R, class T0, class T1>
  102. struct is_unary_or_binary_function_impl<R (__fastcall*)(T0, T1)>
  103. { static const bool value = true; };
  104. #endif
  105. template <typename R, class T0, class T1>
  106. struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1)>
  107. { static const bool value = true; };
  108. template <typename R, class T0, class T1>
  109. struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1...)>
  110. { static const bool value = true; };
  111. #endif
  112. template <typename T>
  113. struct is_unary_or_binary_function_impl<T&>
  114. { static const bool value = false; };
  115. template<typename T>
  116. struct is_unary_or_binary_function : is_unary_or_binary_function_impl<T>
  117. {};
  118. template<typename T, typename Tag = void, bool = is_unary_or_binary_function<T>::value>
  119. class ebo_functor_holder
  120. {
  121. BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder)
  122. public:
  123. typedef T functor_type;
  124. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder()
  125. : t_()
  126. {}
  127. BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t)
  128. : t_(t)
  129. {}
  130. BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t)
  131. : t_(::boost::move(t))
  132. {}
  133. template<class Arg1, class Arg2>
  134. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
  135. : t_(::boost::forward<Arg1>(arg1), ::boost::forward<Arg2>(arg2))
  136. {}
  137. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x)
  138. : t_(x.t_)
  139. {}
  140. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x)
  141. : t_(x.t_)
  142. {}
  143. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x)
  144. {
  145. this->get() = x.get();
  146. return *this;
  147. }
  148. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x)
  149. {
  150. this->get() = ::boost::move(x.get());
  151. return *this;
  152. }
  153. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x)
  154. {
  155. this->get() = x;
  156. return *this;
  157. }
  158. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x)
  159. {
  160. this->get() = ::boost::move(x);
  161. return *this;
  162. }
  163. BOOST_INTRUSIVE_FORCEINLINE T& get(){return t_;}
  164. BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return t_;}
  165. private:
  166. T t_;
  167. };
  168. template<typename T, typename Tag>
  169. class ebo_functor_holder<T, Tag, false>
  170. : public T
  171. {
  172. BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder)
  173. public:
  174. typedef T functor_type;
  175. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder()
  176. : T()
  177. {}
  178. BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t)
  179. : T(t)
  180. {}
  181. BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t)
  182. : T(::boost::move(t))
  183. {}
  184. template<class Arg1, class Arg2>
  185. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
  186. : T(::boost::forward<Arg1>(arg1), ::boost::forward<Arg2>(arg2))
  187. {}
  188. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x)
  189. : T(static_cast<const T&>(x))
  190. {}
  191. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x)
  192. : T(BOOST_MOVE_BASE(T, x))
  193. {}
  194. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x)
  195. {
  196. const ebo_functor_holder&r = x;
  197. this->get() = r;
  198. return *this;
  199. }
  200. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x)
  201. {
  202. this->get() = ::boost::move(x.get());
  203. return *this;
  204. }
  205. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x)
  206. {
  207. this->get() = x;
  208. return *this;
  209. }
  210. BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x)
  211. {
  212. this->get() = ::boost::move(x);
  213. return *this;
  214. }
  215. BOOST_INTRUSIVE_FORCEINLINE T& get(){return *this;}
  216. BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return *this;}
  217. };
  218. } //namespace detail {
  219. } //namespace intrusive {
  220. } //namespace boost {
  221. #endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP