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