• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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:
test_func(int v)30     test_func(int v) : val(v) { }
31 
32     template<class B>
test_func(test_func<B> const & that)33     test_func(test_func<B> const & that)
34       : val(that.val)
35     { }
36 
37     template<class B> friend class test_func;
38 
operator ()(int & l,int const & r) const39     int operator()(int & l, int const & r) const
40     {
41         return l=r+val;
42     }
operator ()(int & l,int const & r)43     long operator()(int & l, int const & r)
44     {
45         return -(l=r+val);
46     }
operator ()(int & l,int & r)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 
type_of(int)72 int type_of(int)  { return int_; }
type_of(long)73 int type_of(long) { return long_; }
type_of(char)74 int type_of(char) { return char_; }
75 
main()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 
136