williamr@2: //
williamr@2: // Boost.Pointer Container
williamr@2: //
williamr@2: //  Copyright Thorsten Ottosen 2003-2005. Use, modification and
williamr@2: //  distribution is subject to the Boost Software License, Version
williamr@2: //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
williamr@2: //  http://www.boost.org/LICENSE_1_0.txt)
williamr@2: //
williamr@2: // For more information, see http://www.boost.org/libs/ptr_container/
williamr@2: //
williamr@2: 
williamr@2: #ifndef BOOST_PTR_CONTAINER_INDIRECT_FUN_HPP
williamr@2: #define BOOST_PTR_CONTAINER_INDIRECT_FUN_HPP
williamr@2: 
williamr@2: #if defined(_MSC_VER) && (_MSC_VER >= 1200)
williamr@2:     #pragma once
williamr@2: #endif
williamr@2: 
williamr@2: #include <boost/config.hpp>
williamr@2: 
williamr@2: #ifdef BOOST_NO_SFINAE
williamr@2: #else
williamr@2: #include <boost/utility/result_of.hpp>
williamr@2: #include <boost/pointee.hpp>
williamr@2: #endif // BOOST_NO_SFINAE
williamr@2: 
williamr@2: #include <boost/assert.hpp>
williamr@2: #include <functional>
williamr@2: 
williamr@2: 
williamr@2: namespace boost
williamr@2: {
williamr@2: 
williamr@2: 
williamr@2:     template
williamr@2:     < 
williamr@2:               class Fun
williamr@2: #ifdef BOOST_NO_SFINAE
williamr@2:             , class Result = bool
williamr@2: #endif        
williamr@2:     >
williamr@2:     class indirect_fun
williamr@2:     {
williamr@2:         Fun fun;
williamr@2:     public:
williamr@2:         indirect_fun() : fun(Fun())
williamr@2:         { }
williamr@2:         
williamr@2:         indirect_fun( Fun f ) : fun(f)
williamr@2:         { }
williamr@2:     
williamr@2:         template< class T >
williamr@2: #ifdef BOOST_NO_SFINAE
williamr@2:         Result    
williamr@2: #else            
williamr@2:         BOOST_DEDUCED_TYPENAME result_of< Fun( BOOST_DEDUCED_TYPENAME pointee<T>::type ) >::type 
williamr@2: #endif            
williamr@2:         operator()( const T& r ) const
williamr@2:         { 
williamr@2:             return fun( *r );
williamr@2:         }
williamr@2:     
williamr@2:         template< class T, class U >
williamr@2: #ifdef BOOST_NO_SFINAE
williamr@2:         Result    
williamr@2: #else                        
williamr@2:         BOOST_DEDUCED_TYPENAME result_of< Fun( BOOST_DEDUCED_TYPENAME pointee<T>::type, 
williamr@2:                                                BOOST_DEDUCED_TYPENAME pointee<U>::type ) >::type
williamr@2: #endif            
williamr@2:         operator()( const T& r, const U& r2 ) const
williamr@2:         { 
williamr@2:             return fun( *r, *r2 ); 
williamr@2:         }
williamr@2:     };
williamr@2: 
williamr@2:     template< class Fun >
williamr@2:     inline indirect_fun<Fun> make_indirect_fun( Fun f )
williamr@2:     {
williamr@2:         return indirect_fun<Fun>( f );
williamr@2:     }
williamr@2: 
williamr@2: 
williamr@2:     template
williamr@2:     < 
williamr@2:         class Fun, 
williamr@2:         class Arg1, 
williamr@2:         class Arg2 = Arg1 
williamr@2: #ifdef BOOST_NO_SFINAE
williamr@2:       , class Result = bool   
williamr@2: #endif           
williamr@2:     >
williamr@2:     class void_ptr_indirect_fun
williamr@2:     {
williamr@2:         Fun fun;
williamr@2:     public:
williamr@2:         
williamr@2:         void_ptr_indirect_fun() : fun(Fun())
williamr@2:         { }
williamr@2: 
williamr@2:         void_ptr_indirect_fun( Fun f ) : fun(f)
williamr@2:         { }
williamr@2: #ifdef BOOST_NO_SFINAE
williamr@2:         Result    
williamr@2: #else            
williamr@2:         BOOST_DEDUCED_TYPENAME result_of< Fun( Arg1 ) >::type 
williamr@2: #endif            
williamr@2:         operator()( const void* r ) const
williamr@2:         { 
williamr@2:             BOOST_ASSERT( r != 0 );
williamr@2:             return fun( * static_cast<const Arg1*>( r ) );
williamr@2:         }
williamr@2: 
williamr@2: #ifdef BOOST_NO_SFINAE
williamr@2:         Result    
williamr@2: #else                    
williamr@2:         BOOST_DEDUCED_TYPENAME result_of< Fun( Arg1, Arg2 ) >::type 
williamr@2: #endif            
williamr@2:         operator()( const void* l, const void* r ) const
williamr@2:         { 
williamr@2:             BOOST_ASSERT( l != 0 && r != 0 );
williamr@2:             return fun( * static_cast<const Arg1*>( l ), * static_cast<const Arg2*>( r ) );
williamr@2:         }
williamr@2:     };
williamr@2: 
williamr@2:     template< class Arg, class Fun >
williamr@2:     inline void_ptr_indirect_fun<Fun,Arg> make_void_ptr_indirect_fun( Fun f )
williamr@2:     {
williamr@2:         return void_ptr_indirect_fun<Fun,Arg>( f );
williamr@2:     }
williamr@2:      
williamr@2: } // namespace 'boost'
williamr@2: 
williamr@2: #endif