SHARE
TWEET

hito

a guest Sep 20th, 2008 227 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #ifndef HITO_REF
  2. #define HITO_REF
  3.  
  4. #include <boost/type_traits/is_base_of.hpp>
  5. #include <boost/type_traits/integral_constant.hpp>
  6. #include <boost/mpl/has_xxx.hpp>
  7.  
  8.  
  9. namespace hito {
  10.  
  11. namespace detail {
  12.  
  13. // this macro generates a metafunction has_result_type<T>.
  14. // it returns true if T has nested type name T::result_type.
  15. // otherwise, it returns false.
  16. BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
  17.  
  18.  
  19. typedef char yes_type ;
  20. struct no_type { char padding[8] ; } ;
  21.  
  22.  
  23. template < typename T >
  24. struct is_base_of_unary_function_impl
  25. {
  26.         template < typename R, typename T1 >
  27.         static yes_type check( const volatile std::unary_function<T1, R> * ) ;
  28.        
  29.         static no_type check( const volatile void * ) ;
  30.        
  31.         static const bool value = sizeof( check( static_cast< T * >(NULL) ) ) == sizeof( yes_type ) ;    
  32. } ;
  33.  
  34. template < typename T >
  35. struct is_base_of_binary_function_impl
  36. {
  37.         template < typename R, typename T1, typename T2 >
  38.         static yes_type check( const volatile std::binary_function<T1, T2, R> * ) ;
  39.        
  40.         static no_type check( const volatile void * ) ;
  41.        
  42.         static const bool value = sizeof( check( static_cast< T * >(NULL) ) ) == sizeof( yes_type ) ;    
  43. } ;
  44.  
  45.  
  46. // this metafunction returns true if T is derived from std::unary_function
  47. // otherwise, it returns false.
  48. template < typename T >
  49. struct is_base_of_unary_function
  50.         : boost::integral_constant< bool, is_base_of_unary_function_impl<T>::value >
  51. { } ;
  52.  
  53. // this metafunction returns true if T is derived from std::binary_function
  54. // otherwise, it returns false.
  55. template < typename T >
  56. struct is_base_of_binary_function
  57.         : boost::integral_constant< bool, is_base_of_binary_function_impl<T>::value >
  58. { } ;
  59.  
  60.  
  61. // if T has nested type name result_type.
  62. // because TR1 only mentions about result_type,
  63. // we couldn't use argument_types, and couldn't know if it is a unary function or binary function or both.
  64. template < typename Derived, typename T >
  65. struct generic_invocation
  66. {
  67.         typedef  typename T::result_type result_type ;
  68.         template < typename T1 >
  69.         result_type operator () ( T1 const & arg1 ) const
  70.         {
  71.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  72.                 return self.get()( arg1 ) ;
  73.         }
  74.        
  75.         template < typename T1, typename T2 >
  76.         result_type operator () ( T1 const & arg1, T2 const & arg2 ) const
  77.         {
  78.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  79.                 return self.get()( arg1, arg2 ) ;
  80.         }
  81. } ;
  82.  
  83. // make base class. avoid multiple inheritance if possible.
  84. template < typename Derived, typename T, bool is_unary, bool is_binary, bool has_result >
  85. struct make_invocation_base
  86. {
  87.  
  88. } ;
  89.  
  90. // if it has unary_function as base
  91. template < typename Derived, typename T, bool val >
  92. struct make_invocation_base< Derived, T, true, false, val >
  93.         : std::unary_function< typename T::argument_type, typename T::result_type >
  94. {
  95.         result_type operator () ( argument_type const & arg1 ) const
  96.         {
  97.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  98.                 return self.get()( arg1 ) ;
  99.         }
  100.  
  101. } ;
  102.  
  103. // if it has binary_function as base
  104. template < typename Derived, typename T, bool val >
  105. struct make_invocation_base< Derived, T, false, true, val >
  106.         : std::binary_function< typename T::first_argument_type, typename T::second_argument_type, typename T::result_type >
  107. {
  108.         result_type operator () ( first_argument_type const & arg1, second_argument_type const & arg2 ) const
  109.         {
  110.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  111.                 return self.get()( arg1, arg2 ) ;
  112.         }
  113.  
  114. } ;
  115.  
  116. // if it has both unary_function and binary_function as bases
  117. template < typename Derived, typename T, bool val >
  118. struct make_invocation_base< Derived, T, true, true, val >
  119.         : std::unary_function< typename T::argument_type, typename T::result_type >
  120.         , std::binary_function< typename T::first_argument_type, typename T::second_argument_type, typename T::result_type >
  121. {
  122.         typedef typename T::result_type result_type ;
  123.        
  124.         result_type operator () ( argument_type const & arg1 ) const
  125.         {
  126.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  127.                 return self.get()( arg1 ) ;
  128.         }
  129.        
  130.         result_type operator () ( first_argument_type const & arg1, second_argument_type const & arg2 ) const
  131.         {
  132.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  133.                 return self.get()( arg1, arg2 ) ;
  134.         }
  135.  
  136. } ;
  137.  
  138. // else if it has nested type name result_type
  139. template < typename Derived, typename T >
  140. struct make_invocation_base< Derived, T, false, false, true >
  141.         : generic_invocation< Derived, T >
  142. { } ;
  143.  
  144.  
  145. // Primary Template for reference_wrapper_invocation.
  146. // this class defines function call operator and inherites unary_function/binary_function or both.
  147. template < typename Derived, typename T >
  148. struct reference_wrapper_invocation
  149.         : make_invocation_base< Derived, T
  150.                 , is_base_of_unary_function< T >::value
  151.                 , is_base_of_binary_function< T >::value
  152.                 , has_result_type< T >::value
  153.           >
  154. { } ;
  155.  
  156. // unary function type
  157. template < typename Derived, typename R, typename T1 >
  158. struct reference_wrapper_invocation< Derived, R(T1) >
  159.         : std::unary_function< T1, R >
  160. {      
  161.         R operator() ( T1 const & arg1 ) const
  162.         {
  163.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  164.                 return self.get()( arg1 ) ;
  165.         }
  166. } ;
  167.  
  168. // pointer to unary function type
  169. template < typename Derived, typename R, typename T1 >
  170. struct reference_wrapper_invocation< Derived, R(*)(T1) >
  171.         : std::unary_function< T1, R >
  172. {
  173.         R operator() ( T1 const & arg1 ) const
  174.         {
  175.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  176.                 return self.get()( arg1 ) ;
  177.         }
  178. } ;
  179.  
  180. // pointer to nullary member function type
  181. template < typename Derived, typename R, typename T1 >
  182. struct reference_wrapper_invocation< Derived, R (T1::*)() >
  183.         : std::unary_function< T1, R >
  184. {
  185.         R operator() ( T1 & arg1 ) const
  186.         {
  187.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  188.                 // call T1's member function by a pointer.
  189.                 return (arg1.*self.get())( ) ;
  190.         }
  191. } ;
  192.  
  193. // pointer to nullary member function type with const qualifier
  194. template < typename Derived, typename R, typename T1 >
  195. struct reference_wrapper_invocation< Derived, R (T1::*)() const >
  196.         : std::unary_function< T1, R >
  197. {
  198.         R operator() ( T1 & arg1 ) const
  199.         {
  200.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  201.                 // call T1's member function by a pointer.
  202.                 return (arg1.*self.get())( ) ;
  203.         }
  204. } ;
  205.  
  206. // binary function type
  207. template < typename Derived, typename R, typename T1, typename T2 >
  208. struct reference_wrapper_invocation< Derived, R(T1, T2) >
  209.         : std::binary_function< T1, T2, R >
  210. {      
  211.         R operator() ( T1 const & arg1, T2 const & arg2 ) const
  212.         {
  213.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  214.                 return self.get()( arg1, arg2 ) ;
  215.         }
  216. } ;
  217.  
  218. // pointer to binary function type
  219. template < typename Derived, typename R, typename T1, typename T2 >
  220. struct reference_wrapper_invocation< Derived, R(*)(T1, T2) >
  221.         : std::binary_function< T1, T2, R >
  222. {      
  223.         R operator() ( T1 const & arg1, T2 const & arg2 ) const
  224.         {
  225.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  226.                 return self.get()( arg1, arg2 ) ;
  227.         }
  228. } ;
  229.  
  230. // pointer to urnary member function type
  231. template < typename Derived, typename R, typename T1, typename T2 >
  232. struct reference_wrapper_invocation< Derived, R (T1::*)( T2 ) >
  233.         : std::binary_function< T1, T2, R >
  234. {
  235.         R operator() ( T1 & arg1, T2 const & arg2 ) const
  236.         {
  237.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  238.                 // call T1's member function by a pointer.
  239.                 return (arg1.*self.get())( arg2 ) ;
  240.         }
  241. } ;
  242.  
  243. // pointer to urnary member function type with const qualifier
  244. template < typename Derived, typename R, typename T1, typename T2 >
  245. struct reference_wrapper_invocation< Derived, R (T1::*)( T2 ) const >
  246.         : std::binary_function< T1, T2, R >
  247. {
  248.         R operator() ( T1 & arg1, T2 const & arg2 ) const
  249.         {
  250.                 Derived const & self = static_cast< Derived const & >( *this ) ;
  251.                 // call T1's member function by a pointer.
  252.                 return (arg1.*self.get())( arg2 ) ;
  253.         }
  254. } ;
  255.  
  256.  
  257. } // namespace detail
  258.  
  259. template < typename T >
  260. class reference_wrapper
  261.         : public detail::reference_wrapper_invocation< reference_wrapper< T >, T >
  262. {
  263. public :
  264.         typedef T type ;
  265.        
  266.         reference_wrapper( T & x )
  267.                 : object( x )
  268.         { }
  269.        
  270.         reference_wrapper( const reference_wrapper< T > & x )
  271.                 : object( x.get() )
  272.         { }
  273.        
  274.         operator T & () const
  275.         {
  276.                 return get() ;
  277.         }
  278.        
  279.        
  280.         T & get() const
  281.         {
  282.                 return object ;
  283.         }
  284.  
  285. private :
  286.         T & object ;
  287. } ;
  288.  
  289. // reference_wrapper helper functions
  290. template < typename T >
  291. reference_wrapper< T > ref( T & t )
  292. {
  293.         return reference_wrapper< T >( t ) ;
  294. }
  295.  
  296. template < typename T >
  297. reference_wrapper< T > ref( reference_wrapper< T > t )
  298. {
  299.         return ref( t.get() ) ;
  300. }
  301.  
  302. template < typename T >
  303. reference_wrapper< T const > cref( T const & t )
  304. {
  305.         return reference_wrapper< T const >( t ) ;
  306. }
  307.  
  308. template < typename T >
  309. reference_wrapper< T const > cref( reference_wrapper< T > t )
  310. {
  311.         return cref( t.get() ) ;
  312. }      
  313.  
  314.  
  315. } // namespace hito
  316.  
  317. #endif // #ifndef HITO_REF
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top