Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef HITO_REF
- #define HITO_REF
- #include <boost/type_traits/is_base_of.hpp>
- #include <boost/type_traits/integral_constant.hpp>
- #include <boost/mpl/has_xxx.hpp>
- namespace hito {
- namespace detail {
- // this macro generates a metafunction has_result_type<T>.
- // it returns true if T has nested type name T::result_type.
- // otherwise, it returns false.
- BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
- typedef char yes_type ;
- struct no_type { char padding[8] ; } ;
- template < typename T >
- struct is_base_of_unary_function_impl
- {
- template < typename R, typename T1 >
- static yes_type check( const volatile std::unary_function<T1, R> * ) ;
- static no_type check( const volatile void * ) ;
- static const bool value = sizeof( check( static_cast< T * >(NULL) ) ) == sizeof( yes_type ) ;
- } ;
- template < typename T >
- struct is_base_of_binary_function_impl
- {
- template < typename R, typename T1, typename T2 >
- static yes_type check( const volatile std::binary_function<T1, T2, R> * ) ;
- static no_type check( const volatile void * ) ;
- static const bool value = sizeof( check( static_cast< T * >(NULL) ) ) == sizeof( yes_type ) ;
- } ;
- // this metafunction returns true if T is derived from std::unary_function
- // otherwise, it returns false.
- template < typename T >
- struct is_base_of_unary_function
- : boost::integral_constant< bool, is_base_of_unary_function_impl<T>::value >
- { } ;
- // this metafunction returns true if T is derived from std::binary_function
- // otherwise, it returns false.
- template < typename T >
- struct is_base_of_binary_function
- : boost::integral_constant< bool, is_base_of_binary_function_impl<T>::value >
- { } ;
- // if T has nested type name result_type.
- // because TR1 only mentions about result_type,
- // we couldn't use argument_types, and couldn't know if it is a unary function or binary function or both.
- template < typename Derived, typename T >
- struct generic_invocation
- {
- typedef typename T::result_type result_type ;
- template < typename T1 >
- result_type operator () ( T1 const & arg1 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1 ) ;
- }
- template < typename T1, typename T2 >
- result_type operator () ( T1 const & arg1, T2 const & arg2 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1, arg2 ) ;
- }
- } ;
- // make base class. avoid multiple inheritance if possible.
- template < typename Derived, typename T, bool is_unary, bool is_binary, bool has_result >
- struct make_invocation_base
- {
- } ;
- // if it has unary_function as base
- template < typename Derived, typename T, bool val >
- struct make_invocation_base< Derived, T, true, false, val >
- : std::unary_function< typename T::argument_type, typename T::result_type >
- {
- result_type operator () ( argument_type const & arg1 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1 ) ;
- }
- } ;
- // if it has binary_function as base
- template < typename Derived, typename T, bool val >
- struct make_invocation_base< Derived, T, false, true, val >
- : std::binary_function< typename T::first_argument_type, typename T::second_argument_type, typename T::result_type >
- {
- result_type operator () ( first_argument_type const & arg1, second_argument_type const & arg2 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1, arg2 ) ;
- }
- } ;
- // if it has both unary_function and binary_function as bases
- template < typename Derived, typename T, bool val >
- struct make_invocation_base< Derived, T, true, true, val >
- : std::unary_function< typename T::argument_type, typename T::result_type >
- , std::binary_function< typename T::first_argument_type, typename T::second_argument_type, typename T::result_type >
- {
- typedef typename T::result_type result_type ;
- result_type operator () ( argument_type const & arg1 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1 ) ;
- }
- result_type operator () ( first_argument_type const & arg1, second_argument_type const & arg2 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1, arg2 ) ;
- }
- } ;
- // else if it has nested type name result_type
- template < typename Derived, typename T >
- struct make_invocation_base< Derived, T, false, false, true >
- : generic_invocation< Derived, T >
- { } ;
- // Primary Template for reference_wrapper_invocation.
- // this class defines function call operator and inherites unary_function/binary_function or both.
- template < typename Derived, typename T >
- struct reference_wrapper_invocation
- : make_invocation_base< Derived, T
- , is_base_of_unary_function< T >::value
- , is_base_of_binary_function< T >::value
- , has_result_type< T >::value
- >
- { } ;
- // unary function type
- template < typename Derived, typename R, typename T1 >
- struct reference_wrapper_invocation< Derived, R(T1) >
- : std::unary_function< T1, R >
- {
- R operator() ( T1 const & arg1 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1 ) ;
- }
- } ;
- // pointer to unary function type
- template < typename Derived, typename R, typename T1 >
- struct reference_wrapper_invocation< Derived, R(*)(T1) >
- : std::unary_function< T1, R >
- {
- R operator() ( T1 const & arg1 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1 ) ;
- }
- } ;
- // pointer to nullary member function type
- template < typename Derived, typename R, typename T1 >
- struct reference_wrapper_invocation< Derived, R (T1::*)() >
- : std::unary_function< T1, R >
- {
- R operator() ( T1 & arg1 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- // call T1's member function by a pointer.
- return (arg1.*self.get())( ) ;
- }
- } ;
- // pointer to nullary member function type with const qualifier
- template < typename Derived, typename R, typename T1 >
- struct reference_wrapper_invocation< Derived, R (T1::*)() const >
- : std::unary_function< T1, R >
- {
- R operator() ( T1 & arg1 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- // call T1's member function by a pointer.
- return (arg1.*self.get())( ) ;
- }
- } ;
- // binary function type
- template < typename Derived, typename R, typename T1, typename T2 >
- struct reference_wrapper_invocation< Derived, R(T1, T2) >
- : std::binary_function< T1, T2, R >
- {
- R operator() ( T1 const & arg1, T2 const & arg2 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1, arg2 ) ;
- }
- } ;
- // pointer to binary function type
- template < typename Derived, typename R, typename T1, typename T2 >
- struct reference_wrapper_invocation< Derived, R(*)(T1, T2) >
- : std::binary_function< T1, T2, R >
- {
- R operator() ( T1 const & arg1, T2 const & arg2 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- return self.get()( arg1, arg2 ) ;
- }
- } ;
- // pointer to urnary member function type
- template < typename Derived, typename R, typename T1, typename T2 >
- struct reference_wrapper_invocation< Derived, R (T1::*)( T2 ) >
- : std::binary_function< T1, T2, R >
- {
- R operator() ( T1 & arg1, T2 const & arg2 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- // call T1's member function by a pointer.
- return (arg1.*self.get())( arg2 ) ;
- }
- } ;
- // pointer to urnary member function type with const qualifier
- template < typename Derived, typename R, typename T1, typename T2 >
- struct reference_wrapper_invocation< Derived, R (T1::*)( T2 ) const >
- : std::binary_function< T1, T2, R >
- {
- R operator() ( T1 & arg1, T2 const & arg2 ) const
- {
- Derived const & self = static_cast< Derived const & >( *this ) ;
- // call T1's member function by a pointer.
- return (arg1.*self.get())( arg2 ) ;
- }
- } ;
- } // namespace detail
- template < typename T >
- class reference_wrapper
- : public detail::reference_wrapper_invocation< reference_wrapper< T >, T >
- {
- public :
- typedef T type ;
- reference_wrapper( T & x )
- : object( x )
- { }
- reference_wrapper( const reference_wrapper< T > & x )
- : object( x.get() )
- { }
- operator T & () const
- {
- return get() ;
- }
- T & get() const
- {
- return object ;
- }
- private :
- T & object ;
- } ;
- // reference_wrapper helper functions
- template < typename T >
- reference_wrapper< T > ref( T & t )
- {
- return reference_wrapper< T >( t ) ;
- }
- template < typename T >
- reference_wrapper< T > ref( reference_wrapper< T > t )
- {
- return ref( t.get() ) ;
- }
- template < typename T >
- reference_wrapper< T const > cref( T const & t )
- {
- return reference_wrapper< T const >( t ) ;
- }
- template < typename T >
- reference_wrapper< T const > cref( reference_wrapper< T > t )
- {
- return cref( t.get() ) ;
- }
- } // namespace hito
- #endif // #ifndef HITO_REF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement