1 // 2 // Boost.Pointer Container 3 // 4 // Copyright Thorsten Ottosen 2003-2007. Use, modification and 5 // distribution is subject to the Boost Software License, Version 6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // For more information, see http://www.boost.org/libs/ptr_container/ 10 // 11 12 #ifndef BOOST_PTR_CONTAINER_INDIRECT_FUN_HPP 13 #define BOOST_PTR_CONTAINER_INDIRECT_FUN_HPP 14 15 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #pragma once 17 #endif 18 19 #include <boost/config.hpp> 20 21 #ifdef BOOST_NO_SFINAE 22 #else 23 #include <boost/utility/result_of.hpp> 24 #include <boost/pointee.hpp> 25 #endif // BOOST_NO_SFINAE 26 27 #include <boost/assert.hpp> 28 #include <boost/static_assert.hpp> 29 #include <boost/type_traits/is_void.hpp> 30 #include <functional> 31 32 33 namespace boost 34 { 35 36 namespace ptr_container_detail 37 { 38 template <typename Type, typename Dummy> 39 struct make_lazy 40 { 41 typedef typename Type::type type; 42 }; 43 } 44 45 template 46 < 47 class Fun 48 #ifdef BOOST_NO_SFINAE 49 , class Result = bool 50 #endif 51 > 52 class indirect_fun 53 { 54 Fun fun; 55 public: indirect_fun()56 indirect_fun() : fun(Fun()) 57 { } 58 indirect_fun(Fun f)59 indirect_fun( Fun f ) : fun(f) 60 { } 61 62 template< class T > 63 #ifdef BOOST_NO_SFINAE 64 Result 65 #else 66 typename boost::result_of< const Fun( typename pointee<T>::type& ) >::type 67 #endif operator ()(const T & r) const68 operator()( const T& r ) const 69 { 70 return fun( *r ); 71 } 72 73 template< class T, class U > 74 #ifdef BOOST_NO_SFINAE 75 Result 76 #else 77 typename boost::result_of< const Fun( typename pointee<T>::type&, 78 typename pointee<U>::type& ) >::type 79 #endif operator ()(const T & r,const U & r2) const80 operator()( const T& r, const U& r2 ) const 81 { 82 return fun( *r, *r2 ); 83 } 84 }; 85 86 template< class Fun > make_indirect_fun(Fun f)87 inline indirect_fun<Fun> make_indirect_fun( Fun f ) 88 { 89 return indirect_fun<Fun>( f ); 90 } 91 92 93 template 94 < 95 class Fun, 96 class Arg1, 97 class Arg2 = Arg1 98 #ifdef BOOST_NO_SFINAE 99 , class Result = bool 100 #endif 101 > 102 class void_ptr_indirect_fun 103 { 104 Fun fun; 105 106 public: 107 void_ptr_indirect_fun()108 void_ptr_indirect_fun() : fun(Fun()) 109 { } 110 void_ptr_indirect_fun(Fun f)111 void_ptr_indirect_fun( Fun f ) : fun(f) 112 { } 113 114 template< class Void > 115 #ifdef BOOST_NO_SFINAE 116 Result 117 #else 118 typename ptr_container_detail::make_lazy< 119 boost::result_of<const Fun(const Arg1&)>, Void>::type 120 #endif operator ()(const Void * r) const121 operator()( const Void* r ) const 122 { 123 BOOST_STATIC_ASSERT(boost::is_void<Void>::value); 124 BOOST_ASSERT( r != 0 ); 125 return fun( * static_cast<const Arg1*>( r ) ); 126 } 127 128 template< class Void > 129 #ifdef BOOST_NO_SFINAE 130 Result 131 #else 132 typename ptr_container_detail::make_lazy< 133 boost::result_of<const Fun(const Arg1&, const Arg2&)>, Void>::type 134 #endif operator ()(const Void * l,const Void * r) const135 operator()( const Void* l, const Void* r ) const 136 { 137 BOOST_STATIC_ASSERT(boost::is_void<Void>::value); 138 BOOST_ASSERT( l != 0 && r != 0 ); 139 return fun( * static_cast<const Arg1*>( l ), * static_cast<const Arg2*>( r ) ); 140 } 141 }; 142 143 template< class Arg, class Fun > make_void_ptr_indirect_fun(Fun f)144 inline void_ptr_indirect_fun<Fun,Arg> make_void_ptr_indirect_fun( Fun f ) 145 { 146 return void_ptr_indirect_fun<Fun,Arg>( f ); 147 } 148 149 } // namespace 'boost' 150 151 #endif 152