indirect_fun.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. #ifndef BOOST_PTR_CONTAINER_INDIRECT_FUN_HPP
  12. #define BOOST_PTR_CONTAINER_INDIRECT_FUN_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. #pragma once
  15. #endif
  16. #include <boost/config.hpp>
  17. #ifdef BOOST_NO_SFINAE
  18. #else
  19. #include <boost/utility/result_of.hpp>
  20. #include <boost/pointee.hpp>
  21. #endif // BOOST_NO_SFINAE
  22. #include <boost/assert.hpp>
  23. #include <boost/static_assert.hpp>
  24. #include <boost/type_traits/is_void.hpp>
  25. #include <functional>
  26. namespace boost
  27. {
  28. namespace ptr_container_detail
  29. {
  30. template <typename Type, typename Dummy>
  31. struct make_lazy
  32. {
  33. typedef typename Type::type type;
  34. };
  35. }
  36. template
  37. <
  38. class Fun
  39. #ifdef BOOST_NO_SFINAE
  40. , class Result = bool
  41. #endif
  42. >
  43. class indirect_fun
  44. {
  45. Fun fun;
  46. public:
  47. indirect_fun() : fun(Fun())
  48. { }
  49. indirect_fun( Fun f ) : fun(f)
  50. { }
  51. template< class T >
  52. #ifdef BOOST_NO_SFINAE
  53. Result
  54. #else
  55. typename boost::result_of< const Fun( typename pointee<T>::type& ) >::type
  56. #endif
  57. operator()( const T& r ) const
  58. {
  59. return fun( *r );
  60. }
  61. template< class T, class U >
  62. #ifdef BOOST_NO_SFINAE
  63. Result
  64. #else
  65. typename boost::result_of< const Fun( typename pointee<T>::type&,
  66. typename pointee<U>::type& ) >::type
  67. #endif
  68. operator()( const T& r, const U& r2 ) const
  69. {
  70. return fun( *r, *r2 );
  71. }
  72. };
  73. template< class Fun >
  74. inline indirect_fun<Fun> make_indirect_fun( Fun f )
  75. {
  76. return indirect_fun<Fun>( f );
  77. }
  78. template
  79. <
  80. class Fun,
  81. class Arg1,
  82. class Arg2 = Arg1
  83. #ifdef BOOST_NO_SFINAE
  84. , class Result = bool
  85. #endif
  86. >
  87. class void_ptr_indirect_fun
  88. {
  89. Fun fun;
  90. public:
  91. void_ptr_indirect_fun() : fun(Fun())
  92. { }
  93. void_ptr_indirect_fun( Fun f ) : fun(f)
  94. { }
  95. template< class Void >
  96. #ifdef BOOST_NO_SFINAE
  97. Result
  98. #else
  99. typename ptr_container_detail::make_lazy<
  100. boost::result_of<const Fun(const Arg1&)>, Void>::type
  101. #endif
  102. operator()( const Void* r ) const
  103. {
  104. BOOST_STATIC_ASSERT(boost::is_void<Void>::value);
  105. BOOST_ASSERT( r != 0 );
  106. return fun( * static_cast<const Arg1*>( r ) );
  107. }
  108. template< class Void >
  109. #ifdef BOOST_NO_SFINAE
  110. Result
  111. #else
  112. typename ptr_container_detail::make_lazy<
  113. boost::result_of<const Fun(const Arg1&, const Arg2&)>, Void>::type
  114. #endif
  115. operator()( const Void* l, const Void* r ) const
  116. {
  117. BOOST_STATIC_ASSERT(boost::is_void<Void>::value);
  118. BOOST_ASSERT( l != 0 && r != 0 );
  119. return fun( * static_cast<const Arg1*>( l ), * static_cast<const Arg2*>( r ) );
  120. }
  121. };
  122. template< class Arg, class Fun >
  123. inline void_ptr_indirect_fun<Fun,Arg> make_void_ptr_indirect_fun( Fun f )
  124. {
  125. return void_ptr_indirect_fun<Fun,Arg>( f );
  126. }
  127. } // namespace 'boost'
  128. #endif