]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
11fdf7f2 | 15 | #include <boost/core/lightweight_test.hpp> |
7c673cae FG |
16 | #include <boost/functional/lightweight_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::lightweight_forward_adapter< test_func<> > f; | |
82 | typedef boost::reference_wrapper<int> ref; | |
83 | typedef boost::reference_wrapper<int const> cref; | |
84 | ||
85 | // lvalue,rvalue | |
86 | BOOST_TEST(( is_same< | |
87 | result_of< f(ref, int) >::type, long >::value )); | |
88 | BOOST_TEST(( is_same< | |
89 | result_of< f const (ref, int) >::type, int >::value )); | |
90 | // lvalue,const lvalue | |
91 | BOOST_TEST(( is_same< | |
92 | result_of< f(ref, cref) >::type, long >::value )); | |
93 | BOOST_TEST(( is_same< | |
94 | result_of< f const (ref, cref) >::type, int >::value )); | |
95 | // lvalue,lvalue | |
96 | BOOST_TEST(( is_same< | |
97 | result_of< f(ref, ref) >::type, char >::value )); | |
98 | // result_of works differently for C++11 here, so compare | |
99 | // with using it against test_func. | |
100 | BOOST_TEST(( is_same< | |
101 | result_of< f const (ref, ref) >::type, | |
102 | result_of< test_func<> const (int&, int&) >::type >::value )); | |
103 | } | |
104 | { | |
105 | using boost::noncopyable; | |
106 | using boost::lightweight_forward_adapter; | |
107 | ||
108 | int v = 0; boost::reference_wrapper<int> x(v); | |
109 | test_func<noncopyable> f(7); | |
110 | lightweight_forward_adapter< test_func<> > func(f); | |
111 | lightweight_forward_adapter< test_func<noncopyable> & > func_ref(f); | |
112 | lightweight_forward_adapter< test_func<noncopyable> & > const func_ref_c(f); | |
113 | lightweight_forward_adapter< test_func<> const > func_c(f); | |
114 | lightweight_forward_adapter< test_func<> > const func_c2(f); | |
115 | lightweight_forward_adapter< test_func<noncopyable> const & > func_c_ref(f); | |
116 | ||
117 | BOOST_TEST( type_of( func(x,1) ) == long_ ); | |
118 | BOOST_TEST( type_of( func_ref(x,1) ) == long_ ); | |
119 | BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ ); | |
120 | BOOST_TEST( type_of( func_c(x,1) ) == int_ ); | |
121 | BOOST_TEST( type_of( func_c2(x,1) ) == int_ ); | |
122 | BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ ); | |
123 | BOOST_TEST( type_of( func(x,x) ) == char_ ); | |
124 | ||
125 | BOOST_TEST( func(x,1) == -8 ); | |
126 | BOOST_TEST( func_ref(x,1) == -8 ); | |
127 | BOOST_TEST( func_ref_c(x,1) == -8 ); | |
128 | BOOST_TEST( func_c(x,1) == 8 ); | |
129 | BOOST_TEST( func_c2(x,1) == 8 ); | |
130 | BOOST_TEST( func_c_ref(x,1) == 8 ); | |
131 | } | |
132 | ||
133 | return boost::report_errors(); | |
134 | } | |
135 |