result_of and polymorphic function obj compatibility

[SVN r37962]
This commit is contained in:
Dan Marsden
2007-06-11 07:01:05 +00:00
parent 414b87dbdb
commit 0fcbc5b467
42 changed files with 477 additions and 410 deletions
+25 -6
View File
@@ -15,6 +15,9 @@
#include <boost/fusion/sequence/generation/make_vector.hpp>
#include <boost/fusion/sequence/container/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/assert.hpp>
namespace fusion = boost::fusion;
using boost::noncopyable;
@@ -52,17 +55,33 @@ struct test_func
int main()
{
test_func<noncopyable> f;
fusion::fused< test_func<> > fused_func;
fusion::fused< test_func<noncopyable> & > fused_func_ref(f);
fusion::fused< test_func<> const > fused_func_c;
fusion::fused< test_func<> > const fused_func_c2;
fusion::fused< test_func<noncopyable> const & > fused_func_c_ref(f);
fusion::vector<int,char> lv_vec(1,'\004');
typedef fusion::fused< test_func<> > ff;
ff fused_func;
typedef fusion::fused< test_func<noncopyable> & > ffr;
ffr fused_func_ref(f);
typedef fusion::fused< test_func<> const > ffc;
ffc fused_func_c;
typedef fusion::fused< test_func<> > const ffc2;
ffc2 fused_func_c2;
typedef fusion::fused< test_func<noncopyable> const & > ffcr;
ffcr fused_func_c_ref(f);
typedef fusion::vector<int,char> vec;
vec lv_vec(1,'\004');
BOOST_MPL_ASSERT((boost::is_same<boost::result_of<ff(vec)>::type, int>));
BOOST_TEST(fused_func(lv_vec) == 1);
BOOST_MPL_ASSERT((boost::is_same<boost::result_of<ffr(vec)>::type, int>));
BOOST_TEST(fused_func_c(lv_vec) == 0);
BOOST_MPL_ASSERT((boost::is_same<boost::result_of<ffc(vec)>::type, int>));
BOOST_TEST(fused_func_c2(lv_vec) == 0);
BOOST_TEST(fused_func_ref(lv_vec) == 1);
BOOST_MPL_ASSERT((boost::is_same<boost::result_of<ffcr(vec)>::type, int>));
BOOST_TEST(fused_func_c_ref(lv_vec) == 0);
BOOST_TEST(fused_func(fusion::make_vector(2,'\003')) == 1);
+5 -2
View File
@@ -22,8 +22,11 @@ template <class Base = boost::blank>
struct test_func
: Base
{
template <typename T0, typename T1>
struct result
template<typename T>
struct result;
template<typename B, typename T0, typename T1>
struct result<test_func<B>(T0, T1)>
{
typedef int type;
};
+53 -14
View File
@@ -40,10 +40,27 @@ struct object_nc : boost::noncopyable {};
struct fobj
{
typedef int result_type;
// Handle nullary separately to exercise result_of support
template<typename T>
struct result;
int operator()() { return 0; }
int operator()() const { return 1; }
template<typename T0>
struct result<fobj(T0)>
{
typedef int type;
};
template<typename T0, typename T1>
struct result<fobj(T0, T1)>
{
typedef int type;
};
template<typename T0, typename T1, typename T2>
struct result<fobj(T0, T1, T2)>
{
typedef int type;
};
int operator()(int i) { return 2 + i; }
int operator()(int i) const { return 3 + i; }
@@ -57,16 +74,38 @@ struct fobj
int operator()(int i, object &, object_nc &) const { return 11 + i; }
};
struct nullary_fobj
{
typedef int result_type;
int operator()() { return 0; }
int operator()() const { return 1; }
};
struct fobj_nc
: boost::noncopyable
{
// Handle nullary separately to exercise result_of support
template<typename T>
struct result;
template<typename T0>
struct result<fobj_nc(T0)>
{
typedef int type;
};
int operator()(int i) { return 14 + i; }
int operator()(int i) const { return 15 + i; }
};
struct nullary_fobj_nc
: boost::noncopyable
{
typedef int result_type;
int operator()() { return 12; }
int operator()() const { return 13; }
int operator()(int i) { return 14 + i; }
int operator()(int i) const { return 15 + i; }
};
int nullary() { return 16; }
@@ -147,7 +186,7 @@ void test_sequence_n(Sequence & seq, mpl::int_<0>)
{
// Function Objects
fobj f;
nullary_fobj f;
BOOST_TEST(f () == fusion::invoke(f , seq ));
BOOST_TEST(f () == fusion::invoke(f , const_(seq)));
@@ -155,16 +194,16 @@ void test_sequence_n(Sequence & seq, mpl::int_<0>)
// Note: The function object is taken by value, so we request the copy
// to be const with an explicit template argument. We can also request
// the function object to be pased by reference...
BOOST_TEST(const_(f)() == fusion::invoke<fobj const >(const_(f), seq ));
BOOST_TEST(const_(f)() == fusion::invoke<fobj const &>(const_(f), const_(seq)));
BOOST_TEST(const_(f)() == fusion::invoke<nullary_fobj const >(const_(f), seq ));
BOOST_TEST(const_(f)() == fusion::invoke<nullary_fobj const &>(const_(f), const_(seq)));
fobj_nc nc_f;
nullary_fobj_nc nc_f;
// ...and we further ensure there is no copying in this case, using a
// noncopyable function object.
BOOST_TEST(nc_f () == fusion::invoke<fobj_nc &>(nc_f , seq ));
BOOST_TEST(nc_f () == fusion::invoke<fobj_nc &>(nc_f , const_(seq)));
BOOST_TEST(const_(nc_f)() == fusion::invoke<fobj_nc const &>(const_(nc_f), seq ));
BOOST_TEST(const_(nc_f)() == fusion::invoke<fobj_nc const &>(const_(nc_f), const_(seq)));
BOOST_TEST(nc_f () == fusion::invoke<nullary_fobj_nc &>(nc_f , seq ));
BOOST_TEST(nc_f () == fusion::invoke<nullary_fobj_nc &>(nc_f , const_(seq)));
BOOST_TEST(const_(nc_f)() == fusion::invoke<nullary_fobj_nc const &>(const_(nc_f), seq ));
BOOST_TEST(const_(nc_f)() == fusion::invoke<nullary_fobj_nc const &>(const_(nc_f), const_(seq)));
// Builtin Functions
+52 -17
View File
@@ -40,8 +40,24 @@ struct object_nc : boost::noncopyable {};
struct fobj
{
template <typename T0 = void, typename T1 = void, typename T2 = void>
struct result
// Handle nullary separately to exercise result_of support
template<typename T>
struct result;
template<typename T0>
struct result<fobj(T0)>
{
typedef int type;
};
template<typename T0, typename T1>
struct result<fobj(T0, T1)>
{
typedef int type;
};
template<typename T0, typename T1, typename T2>
struct result<fobj(T0, T1, T2)>
{
typedef int type;
};
@@ -61,22 +77,41 @@ struct fobj
int operator()(int i, object &, object_nc &) const { return 11 + i; }
};
struct nullary_fobj
{
typedef int result_type;
int operator()() { return 0; }
int operator()() const { return 1; }
};
struct fobj_nc
: boost::noncopyable
{
template <typename T0 = void>
struct result
// Handle nullary separately to exercise result_of support
template <typename T>
struct result;
template<typename T0>
struct result<fobj_nc(T0)>
{
typedef int type;
};
int operator()() { return 12; }
int operator()() const { return 13; }
int operator()(int i) { return 14 + i; }
int operator()(int i) const { return 15 + i; }
};
struct nullary_fobj_nc
: boost::noncopyable
{
typedef int result_type;
int operator()() { return 12; }
int operator()() const { return 13; }
};
typedef int element1_type;
typedef object element2_type;
typedef object_nc & element3_type;
@@ -90,23 +125,23 @@ void test_sequence_n(Sequence & seq, mpl::int_<0>)
{
// Function Objects
fobj f;
nullary_fobj f;
BOOST_TEST(f () == fusion::invoke_function_object(f , seq ));
BOOST_TEST(f () == fusion::invoke_function_object(f , const_(seq)));
// Note: The function object is taken by value, so we request the copy
// to be const with an explicit template argument. We can also request
// the function object to be pased by reference...
BOOST_TEST(const_(f)() == fusion::invoke_function_object<fobj const >(const_(f), seq ));
BOOST_TEST(const_(f)() == fusion::invoke_function_object<fobj const &>(const_(f), const_(seq)));
BOOST_TEST(const_(f)() == fusion::invoke_function_object<nullary_fobj const >(const_(f), seq ));
BOOST_TEST(const_(f)() == fusion::invoke_function_object<nullary_fobj const &>(const_(f), const_(seq)));
fobj_nc nc_f;
nullary_fobj_nc nc_f;
// ...and we further ensure there is no copying in this case, using a
// noncopyable function object.
BOOST_TEST(nc_f () == fusion::invoke_function_object<fobj_nc &>(nc_f , seq ));
BOOST_TEST(nc_f () == fusion::invoke_function_object<fobj_nc &>(nc_f , const_(seq)));
BOOST_TEST(const_(nc_f)() == fusion::invoke_function_object<fobj_nc const &>(const_(nc_f), seq ));
BOOST_TEST(const_(nc_f)() == fusion::invoke_function_object<fobj_nc const &>(const_(nc_f), const_(seq)));
BOOST_TEST(nc_f () == fusion::invoke_function_object<nullary_fobj_nc &>(nc_f , seq ));
BOOST_TEST(nc_f () == fusion::invoke_function_object<nullary_fobj_nc &>(nc_f , const_(seq)));
BOOST_TEST(const_(nc_f)() == fusion::invoke_function_object<nullary_fobj_nc const &>(const_(nc_f), seq ));
BOOST_TEST(const_(nc_f)() == fusion::invoke_function_object<nullary_fobj_nc const &>(const_(nc_f), const_(seq)));
}
template <class Sequence>
@@ -154,7 +189,7 @@ void result_type_tests()
{
using boost::is_same;
BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< fobj, fusion::vector<> >::type, int >::value ));
BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< nullary_fobj, fusion::vector<> >::type, int >::value ));
BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< fobj, fusion::vector<element1_type> >::type, int >::value ));
BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< fobj, fusion::vector<element1_type,element2_type> >::type, int >::value ));
}
@@ -24,8 +24,14 @@ template <class Base = boost::blank>
struct test_func
: Base
{
template <typename T0, typename T1>
template<typename T>
struct result
{
};
template<typename B, typename T0, typename T1>
struct result<test_func<B>(T0, T1)>
{
typedef int type;
};
+7 -5
View File
@@ -38,7 +38,11 @@ template <class Base = boost::blank, class RemoveNullary = mpl::false_>
struct test_func
: Base
{
template <class Seq> struct result
template<typename Params>
struct result;
template <typename B, typename RM, class Seq>
struct result<test_func<B, RM>(Seq)>
: mpl::if_< mpl::and_< fusion::result_of::empty<Seq>, RemoveNullary >,
boost::blank, mpl::identity<long> >::type
{ };
@@ -61,6 +65,8 @@ struct test_func
struct fold_op
{
typedef long result_type;
template <typename T>
long operator()(T const & elem, long value) const
{
@@ -73,10 +79,6 @@ struct test_func
elem += sizeof(T);
return value;
}
template <typename T0, typename T1> struct result
: mpl::identity<long>
{ };
};
};
+7 -5
View File
@@ -37,7 +37,11 @@ template <class Base = boost::blank, class RemoveNullary = mpl::false_>
struct test_func
: Base
{
template <class Seq> struct result
template<typename Params>
struct result;
template <typename B, typename RN, class Seq>
struct result<test_func<B, RN>(Seq)>
: mpl::if_< mpl::and_< fusion::result_of::empty<Seq>, RemoveNullary >,
boost::blank, mpl::identity<long> >::type
{ };
@@ -60,16 +64,14 @@ struct test_func
struct fold_op
{
typedef long result_type;
template <typename T>
long operator()(T & elem, long value) const
{
elem += sizeof(T);
return value + elem;
}
template <typename T0, typename T1> struct result
: mpl::identity<long>
{ };
};
};
+7 -5
View File
@@ -35,7 +35,11 @@ template <class Base = boost::blank, class RemoveNullary = mpl::false_>
struct test_func
: Base
{
template <class Seq> struct result
template<typename Params>
struct result;
template <typename B, typename RN, class Seq>
struct result<test_func<B, RN>(Seq)>
: mpl::if_< mpl::and_< fusion::result_of::empty<Seq>, RemoveNullary >,
boost::blank, mpl::identity<long> >::type
{ };
@@ -58,15 +62,13 @@ struct test_func
struct fold_op
{
typedef long result_type;
template <typename T>
long operator()(T const & elem, long value) const
{
return value + sizeof(T) * elem;
}
template <typename T0, typename T1> struct result
: mpl::identity<long>
{ };
};
};
+11 -9
View File
@@ -35,10 +35,14 @@ template <class Base = boost::blank, class RemoveNullary = mpl::false_>
struct test_func
: Base
{
template <class Seq> struct result
template<typename T>
struct result;
template <typename B, typename RN, class Seq>
struct result<test_func<B,RN>(Seq)>
: mpl::if_< mpl::and_< fusion::result_of::empty<Seq>, RemoveNullary >,
boost::blank, mpl::identity<long> >::type
{ };
{};
template <typename Seq>
long operator()(Seq const & seq) const
@@ -58,6 +62,8 @@ struct test_func
struct fold_op
{
typedef long result_type;
template <typename T>
long operator()(T const & elem, long value) const
{
@@ -70,10 +76,6 @@ struct test_func
elem += sizeof(T);
return value;
}
template <typename T0, typename T1> struct result
: mpl::identity<long>
{ };
};
};
@@ -85,9 +87,9 @@ void result_type_tests()
typedef fusion::unfused_generic< test_func<noncopyable, no_nullary_call> > test_func_1;
typedef fusion::unfused_generic< test_func<noncopyable> > test_func_0;
BOOST_TEST(( has_type< test_func_0::result<> >::value ));
BOOST_TEST(( has_type< test_func_1::result<int> >::value ));
BOOST_TEST(( ! has_type< test_func_1::result<> >::value ));
BOOST_TEST(( has_type< test_func_0::result<test_func_0()> >::value ));
BOOST_TEST(( has_type< test_func_1::result<test_func_1(int)> >::value ));
BOOST_TEST(( ! has_type< test_func_1::result<test_func_1()> >::value ));
BOOST_TEST(( is_same< boost::result_of< test_func_0() >::type, long >::value ));
BOOST_TEST(( is_same< boost::result_of< test_func_1(int) >::type, long >::value ));
}
+10 -8
View File
@@ -32,7 +32,11 @@ template <class Base = boost::blank, class RemoveNullary = mpl::false_>
struct test_func
: Base
{
template <class Seq> struct result
template<typename T>
struct result;
template <typename B, typename RM, class Seq>
struct result<test_func<B, RM>(Seq)>
: mpl::if_< mpl::and_< fusion::result_of::empty<Seq>, RemoveNullary >,
boost::blank, mpl::identity<long> >::type
{ };
@@ -55,16 +59,14 @@ struct test_func
struct fold_op
{
typedef long result_type;
template <typename T>
long operator()(T & elem, long value) const
{
elem += sizeof(T);
return value + elem;
}
template <typename T0, typename T1> struct result
: mpl::identity<long>
{ };
};
};
@@ -76,9 +78,9 @@ void result_type_tests()
typedef fusion::unfused_lvalue_args< test_func<noncopyable, no_nullary_call> > test_func_1;
typedef fusion::unfused_lvalue_args< test_func<noncopyable> > test_func_0;
BOOST_TEST(( has_type< test_func_0::result<> >::value ));
BOOST_TEST(( has_type< test_func_1::result<int> >::value ));
BOOST_TEST(( ! has_type< test_func_1::result<> >::value ));
BOOST_TEST(( has_type< test_func_0::result<test_func_0()> >::value ));
BOOST_TEST(( has_type< test_func_1::result<test_func_1(int)> >::value ));
BOOST_TEST(( ! has_type< test_func_1::result<test_func_1()> >::value ));
BOOST_TEST(( is_same< boost::result_of< test_func_0() >::type, long >::value ));
BOOST_TEST(( is_same< boost::result_of< test_func_1(int) >::type, long >::value ));
}
+10 -8
View File
@@ -32,7 +32,11 @@ template <class Base = boost::blank, class RemoveNullary = mpl::false_>
struct test_func
: Base
{
template <class Seq> struct result
template<typename T>
struct result;
template <typename B, typename RN, class Seq>
struct result<test_func<B, RN>(Seq)>
: mpl::if_< mpl::and_< fusion::result_of::empty<Seq>, RemoveNullary >,
boost::blank, mpl::identity<long> >::type
{ };
@@ -55,15 +59,13 @@ struct test_func
struct fold_op
{
typedef long result_type;
template <typename T>
long operator()(T const & elem, long value) const
{
return value + sizeof(T) * elem;
}
template <typename T0, typename T1> struct result
: mpl::identity<long>
{ };
};
};
@@ -75,9 +77,9 @@ void result_type_tests()
typedef fusion::unfused_rvalue_args< test_func<noncopyable, no_nullary_call> > test_func_1;
typedef fusion::unfused_rvalue_args< test_func<noncopyable> > test_func_0;
BOOST_TEST(( has_type< test_func_0::result<> >::value ));
BOOST_TEST(( has_type< test_func_1::result<int> >::value ));
BOOST_TEST(( ! has_type< test_func_1::result<> >::value ));
BOOST_TEST(( has_type< test_func_0::result<test_func_0()> >::value ));
BOOST_TEST(( has_type< test_func_1::result<test_func_1(int)> >::value ));
BOOST_TEST(( ! has_type< test_func_1::result<test_func_1()> >::value ));
BOOST_TEST(( is_same< boost::result_of< test_func_0() >::type, long >::value ));
BOOST_TEST(( is_same< boost::result_of< test_func_1(int) >::type, long >::value ));
}
+10 -8
View File
@@ -42,7 +42,11 @@ template <class Base = boost::blank, class Validation = unconstrained>
struct test_func
: Base
{
template <class Seq> struct result
template<typename T>
struct result;
template <typename B, typename V, class Seq>
struct result<test_func<B,V>(Seq)>
: mpl::if_< typename mpl::apply<Validation, Seq>::type,
mpl::identity<long>, boost::blank >::type
{ };
@@ -65,6 +69,8 @@ struct test_func
struct fold_op
{
typedef long result_type;
template <typename T>
long operator()(T const & elem, long value) const
{
@@ -77,10 +83,6 @@ struct test_func
elem += sizeof(T);
return value;
}
template <typename T0, typename T1> struct result
: mpl::identity<long>
{ };
};
};
@@ -92,9 +94,9 @@ void result_type_tests()
typedef fusion::unfused_typed< test_func<noncopyable, non_variadic>, types > test_func_3;
typedef fusion::unfused_typed< test_func<noncopyable>, types > test_func_0;
BOOST_TEST(( has_type< test_func_0::result<> >::value ));
BOOST_TEST(( has_type< test_func_3::result<long &, int, char> >::value ));
BOOST_TEST(( ! has_type< test_func_3::result<> >::value ));
BOOST_TEST(( has_type< test_func_0::result<test_func_0()> >::value ));
BOOST_TEST(( has_type< test_func_3::result<test_func_3(long &, int, char)> >::value ));
BOOST_TEST(( ! has_type< test_func_3::result<test_func_3()> >::value ));
BOOST_TEST(( is_same< boost::result_of< test_func_0() >::type, long >::value ));
BOOST_TEST(( is_same< boost::result_of< test_func_3(long &, int, char) >::type, long >::value ));
}