lightweight_forward_adapter.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*=============================================================================
  2. Copyright (c) 2007 Tobias Schwinger
  3. Use modification and distribution are subject to the Boost Software
  4. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. ==============================================================================*/
  7. #ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
  8. # ifndef BOOST_PP_IS_ITERATING
  9. # include <boost/config.hpp>
  10. # include <boost/detail/workaround.hpp>
  11. # include <boost/preprocessor/cat.hpp>
  12. # include <boost/preprocessor/iteration/iterate.hpp>
  13. # include <boost/preprocessor/repetition/enum.hpp>
  14. # include <boost/preprocessor/repetition/enum_params.hpp>
  15. # include <boost/preprocessor/repetition/enum_binary_params.hpp>
  16. # include <boost/preprocessor/facilities/intercept.hpp>
  17. # include <boost/utility/result_of.hpp>
  18. # include <boost/ref.hpp>
  19. # ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
  20. # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 10
  21. # elif BOOST_FUNCTIONAL_FORDWARD_ADAPTER_MAX_ARITY < 3
  22. # undef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
  23. # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 3
  24. # endif
  25. namespace boost
  26. {
  27. template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
  28. class lightweight_forward_adapter;
  29. //----- ---- --- -- - - - -
  30. namespace detail
  31. {
  32. template< class MostDerived, typename Function, typename FunctionConst,
  33. int Arity, int MinArity >
  34. struct lightweight_forward_adapter_impl;
  35. struct lightweight_forward_adapter_result
  36. {
  37. template< typename Sig > struct apply;
  38. // Utility metafunction for argument transform
  39. template< typename T > struct x { typedef T const& t; };
  40. template< typename T > struct x< boost::reference_wrapper<T> >
  41. { typedef T& t; };
  42. template< typename T > struct x<T&> : x<T> { };
  43. template< typename T > struct x<T const&> : x<T> { };
  44. template< typename T > struct x<T const> : x<T> { };
  45. // Utility metafunction to choose target function qualification
  46. template< typename T > struct c
  47. { typedef typename T::target_function_t t; };
  48. template< typename T > struct c<T& >
  49. { typedef typename T::target_function_t t; };
  50. template< typename T > struct c<T const >
  51. { typedef typename T::target_function_const_t t; };
  52. template< typename T > struct c<T const&>
  53. { typedef typename T::target_function_const_t t; };
  54. };
  55. }
  56. # define BOOST_TMP_MACRO(f,fn,fc) \
  57. boost::detail::lightweight_forward_adapter_impl< \
  58. lightweight_forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
  59. (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
  60. :BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY), \
  61. (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
  62. template< typename Function, int Arity_Or_MinArity, int MaxArity >
  63. class lightweight_forward_adapter
  64. : public BOOST_TMP_MACRO(Function,Function,Function const)
  65. , private Function
  66. {
  67. public:
  68. lightweight_forward_adapter(Function const& f = Function())
  69. : Function(f)
  70. { }
  71. typedef Function target_function_t;
  72. typedef Function const target_function_const_t;
  73. Function & target_function() { return *this; }
  74. Function const & target_function() const { return *this; }
  75. template< typename Sig > struct result
  76. : detail::lightweight_forward_adapter_result::template apply<Sig>
  77. { };
  78. using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
  79. };
  80. template< typename Function, int Arity_Or_MinArity, int MaxArity >
  81. class lightweight_forward_adapter< Function const, Arity_Or_MinArity,
  82. MaxArity >
  83. : public BOOST_TMP_MACRO(Function const, Function const, Function const)
  84. , private Function
  85. {
  86. public:
  87. lightweight_forward_adapter(Function const& f = Function())
  88. : Function(f)
  89. { }
  90. typedef Function const target_function_t;
  91. typedef Function const target_function_const_t;
  92. Function const & target_function() const { return *this; }
  93. template< typename Sig > struct result
  94. : detail::lightweight_forward_adapter_result::template apply<Sig>
  95. { };
  96. using BOOST_TMP_MACRO(Function const,Function const, Function const)
  97. ::operator();
  98. };
  99. template< typename Function, int Arity_Or_MinArity, int MaxArity >
  100. class lightweight_forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
  101. : public BOOST_TMP_MACRO(Function&, Function, Function)
  102. {
  103. Function& ref_function;
  104. public:
  105. lightweight_forward_adapter(Function& f)
  106. : ref_function(f)
  107. { }
  108. typedef Function target_function_t;
  109. typedef Function target_function_const_t;
  110. Function & target_function() const { return this->ref_function; }
  111. template< typename Sig > struct result
  112. : detail::lightweight_forward_adapter_result::template apply<Sig>
  113. { };
  114. using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
  115. };
  116. #undef BOOST_TMP_MACRO
  117. namespace detail
  118. {
  119. template< class Self >
  120. struct lightweight_forward_adapter_result::apply< Self() >
  121. : boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
  122. { };
  123. template< class MD, class F, class FC >
  124. struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
  125. : lightweight_forward_adapter_result
  126. {
  127. inline typename boost::result_of< FC() >::type
  128. operator()() const
  129. {
  130. return static_cast<MD const*>(this)->target_function()();
  131. }
  132. inline typename boost::result_of< F() >::type
  133. operator()()
  134. {
  135. return static_cast<MD*>(this)->target_function()();
  136. }
  137. };
  138. # define BOOST_PP_FILENAME_1 \
  139. <boost/functional/lightweight_forward_adapter.hpp>
  140. # define BOOST_PP_ITERATION_LIMITS \
  141. (1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY)
  142. # include BOOST_PP_ITERATE()
  143. } // namespace detail
  144. template<class F, int A0, int A1>
  145. struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const ()>
  146. : boost::detail::lightweight_forward_adapter_result::template apply<
  147. boost::lightweight_forward_adapter<F,A0,A1> const () >
  148. { };
  149. template<class F, int A0, int A1>
  150. struct result_of<boost::lightweight_forward_adapter<F,A0,A1>()>
  151. : boost::detail::lightweight_forward_adapter_result::template apply<
  152. boost::lightweight_forward_adapter<F,A0,A1>() >
  153. { };
  154. template<class F, int A0, int A1>
  155. struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const& ()>
  156. : boost::detail::lightweight_forward_adapter_result::template apply<
  157. boost::lightweight_forward_adapter<F,A0,A1> const () >
  158. { };
  159. template<class F, int A0, int A1>
  160. struct result_of<boost::lightweight_forward_adapter<F,A0,A1>& ()>
  161. : boost::detail::lightweight_forward_adapter_result::template apply<
  162. boost::lightweight_forward_adapter<F,A0,A1>() >
  163. { };
  164. }
  165. # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
  166. # else // defined(BOOST_PP_IS_ITERATING)
  167. # define N BOOST_PP_ITERATION()
  168. template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
  169. struct lightweight_forward_adapter_result::apply<
  170. Self (BOOST_PP_ENUM_PARAMS(N,T)) >
  171. : boost::result_of<
  172. BOOST_DEDUCED_TYPENAME c<Self>::t (BOOST_PP_ENUM_BINARY_PARAMS(N,
  173. typename x<T,>::t BOOST_PP_INTERCEPT)) >
  174. { };
  175. template< class MD, class F, class FC >
  176. struct lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
  177. : lightweight_forward_adapter_result
  178. {
  179. template< BOOST_PP_ENUM_PARAMS(N,typename T) >
  180. inline typename boost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N,
  181. T,const& BOOST_PP_INTERCEPT)) >::type
  182. operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
  183. };
  184. template< class MD, class F, class FC, int MinArity >
  185. struct lightweight_forward_adapter_impl<MD,F,FC,N,MinArity>
  186. : lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
  187. {
  188. using lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),
  189. MinArity>::operator();
  190. # define M(z,i,d) \
  191. static_cast<typename d::template x<T##i>::t>(a##i)
  192. template< BOOST_PP_ENUM_PARAMS(N,typename T) >
  193. inline typename lightweight_forward_adapter_result::template apply<
  194. MD const (BOOST_PP_ENUM_BINARY_PARAMS(N,
  195. T,const& BOOST_PP_INTERCEPT)) >::type
  196. operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const
  197. {
  198. typedef lightweight_forward_adapter_result _;
  199. return static_cast<MD const*>(this)->target_function()(
  200. BOOST_PP_ENUM(N,M,_));
  201. }
  202. template< BOOST_PP_ENUM_PARAMS(N,typename T) >
  203. inline typename lightweight_forward_adapter_result::template apply<
  204. MD (BOOST_PP_ENUM_BINARY_PARAMS(N,
  205. T,const& BOOST_PP_INTERCEPT)) >::type
  206. operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a))
  207. {
  208. typedef lightweight_forward_adapter_result _;
  209. return static_cast<MD*>(this)->target_function()(
  210. BOOST_PP_ENUM(N,M,_));
  211. }
  212. # undef M
  213. };
  214. # undef N
  215. # endif // defined(BOOST_PP_IS_ITERATING)
  216. #endif // include guard