forward_adapter.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*=============================================================================
  2. Copyright (c) 2007 Tobias Schwinger
  3. Use modification and distribution are subject to the Boost Software
  4. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. ==============================================================================*/
  7. #include <boost/config.hpp>
  8. #ifdef BOOST_MSVC
  9. # pragma warning(disable: 4244) // no conversion warnings, please
  10. #endif
  11. #include <boost/core/lightweight_test.hpp>
  12. #include <boost/functional/forward_adapter.hpp>
  13. #include <boost/type_traits/is_same.hpp>
  14. #include <boost/blank.hpp>
  15. #include <boost/noncopyable.hpp>
  16. #include <memory>
  17. template <class Base = boost::blank>
  18. class test_func : public Base
  19. {
  20. int val;
  21. public:
  22. test_func(int v) : val(v) { }
  23. template<class B>
  24. test_func(test_func<B> const & that)
  25. : val(that.val)
  26. { }
  27. template<class B> friend class test_func;
  28. int operator()(int & l, int const & r) const
  29. {
  30. return l=r+val;
  31. }
  32. long operator()(int & l, int const & r)
  33. {
  34. return -(l=r+val);
  35. }
  36. char operator()(int& l, int& r)
  37. {
  38. return l=r+val;
  39. }
  40. template <typename Sig>
  41. struct result
  42. {
  43. typedef void type;
  44. };
  45. // ensure result_of argument types are what's expected
  46. // note: this is *not* how client code should look like
  47. template <class Self>
  48. struct result< Self const(int&,int const&) > { typedef int type; };
  49. template <class Self>
  50. struct result< Self(int&,int const&) > { typedef long type; };
  51. template <class Self>
  52. struct result< Self(int&,int&) > { typedef char type; };
  53. };
  54. enum { int_, long_, char_ };
  55. int type_of(int) { return int_; }
  56. int type_of(long) { return long_; }
  57. int type_of(char) { return char_; }
  58. int main()
  59. {
  60. {
  61. using boost::is_same;
  62. using boost::result_of;
  63. typedef boost::forward_adapter< test_func<> > f;
  64. // lvalue,rvalue
  65. BOOST_TEST(( is_same<
  66. result_of< f(int&, int) >::type, long >::value ));
  67. BOOST_TEST(( is_same<
  68. result_of< f const (int&, int) >::type, int >::value ));
  69. // lvalue,const lvalue
  70. BOOST_TEST(( is_same<
  71. result_of< f(int&, int const &) >::type, long >::value ));
  72. BOOST_TEST(( is_same<
  73. result_of< f const (int&, int const &) >::type, int >::value ));
  74. // lvalue,lvalue
  75. BOOST_TEST(( is_same<
  76. result_of< f(int&, int&) >::type, char >::value ));
  77. // result_of works differently for C++11 here, so compare
  78. // with using it against test_func.
  79. BOOST_TEST(( is_same<
  80. result_of< f const (int&, int&) >::type,
  81. result_of< test_func<> const (int&, int&)>::type >::value ));
  82. }
  83. {
  84. using boost::noncopyable;
  85. using boost::forward_adapter;
  86. int x = 0;
  87. test_func<noncopyable> f(7);
  88. forward_adapter< test_func<> > func(f);
  89. forward_adapter< test_func<noncopyable> & > func_ref(f);
  90. forward_adapter< test_func<noncopyable> & > const func_ref_c(f);
  91. forward_adapter< test_func<> const > func_c(f);
  92. forward_adapter< test_func<> > const func_c2(f);
  93. forward_adapter< test_func<noncopyable> const & > func_c_ref(f);
  94. BOOST_TEST( type_of( func(x,1) ) == long_ );
  95. BOOST_TEST( type_of( func_ref(x,1) ) == long_ );
  96. BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ );
  97. BOOST_TEST( type_of( func_c(x,1) ) == int_ );
  98. BOOST_TEST( type_of( func_c2(x,1) ) == int_ );
  99. BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ );
  100. BOOST_TEST( type_of( func(x,x) ) == char_ );
  101. BOOST_TEST( func(x,1) == -8 );
  102. BOOST_TEST( func_ref(x,1) == -8 );
  103. BOOST_TEST( func_ref_c(x,1) == -8 );
  104. BOOST_TEST( func_c(x,1) == 8 );
  105. BOOST_TEST( func_c2(x,1) == 8 );
  106. BOOST_TEST( func_c_ref(x,1) == 8 );
  107. }
  108. return boost::report_errors();
  109. }