1 /*=============================================================================
2 Copyright (c) 2007 Tobias Schwinger
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 ==============================================================================*/
9 #include <boost/config.hpp>
12 # pragma warning(disable: 4244) // no conversion warnings, please
15 #include <boost/detail/lightweight_test.hpp>
16 #include <boost/functional/lightweight_forward_adapter.hpp>
18 #include <boost/type_traits/is_same.hpp>
20 #include <boost/blank.hpp>
21 #include <boost/noncopyable.hpp>
25 template <class Base
= boost::blank
>
26 class test_func
: public Base
30 test_func(int v
) : val(v
) { }
33 test_func(test_func
<B
> const & that
)
37 template<class B
> friend class test_func
;
39 int operator()(int & l
, int const & r
) const
43 long operator()(int & l
, int const & r
)
47 char operator()(int & l
, int & r
)
52 template <typename Sig
>
58 // ensure result_of argument types are what's expected
59 // note: this is *not* how client code should look like
61 struct result
< Self
const(int&,int const&) > { typedef int type
; };
64 struct result
< Self(int&,int const&) > { typedef long type
; };
67 struct result
< Self(int&,int&) > { typedef char type
; };
70 enum { int_
, long_
, char_
};
72 int type_of(int) { return int_
; }
73 int type_of(long) { return long_
; }
74 int type_of(char) { return char_
; }
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
;
87 result_of
< f(ref
, int) >::type
, long >::value
));
89 result_of
< f
const (ref
, int) >::type
, int >::value
));
90 // lvalue,const lvalue
92 result_of
< f(ref
, cref
) >::type
, long >::value
));
94 result_of
< f
const (ref
, cref
) >::type
, int >::value
));
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
));
105 using boost::noncopyable
;
106 using boost::lightweight_forward_adapter
;
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
);
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_
);
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 );
133 return boost::report_errors();