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

View File

@ -5,7 +5,6 @@
# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
#==============================================================================
# bring in rules for testing
import testing ;

View File

@ -1,5 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2007 Dan Marsden
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -23,8 +24,11 @@ using boost::is_same;
struct add_ints_only
{
template<typename T>
struct result;
template <typename T, typename State>
struct result
struct result<add_ints_only(T,State)>
{
typedef State type;
};
@ -45,8 +49,11 @@ struct add_ints_only
struct count_ints
{
template<typename T>
struct result;
template <typename T, typename CountT>
struct result
struct result<count_ints(T,CountT)>
{
typedef typename
if_<
@ -58,10 +65,10 @@ struct count_ints
};
template <typename T, typename CountT>
typename result<T, CountT>::type
typename result<count_ints(T, CountT)>::type
operator()(T const&, CountT const&) const
{
typedef typename result<T, CountT>::type result;
typedef typename result<count_ints(T, CountT)>::type result;
return result();
}
};

View File

@ -1,5 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2007 Dan Marsden
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -18,8 +19,11 @@
struct square
{
template<typename T>
struct result;
template <typename T>
struct result
struct result<square(T)>
{
BOOST_STATIC_ASSERT(!boost::is_reference<T>::value);
typedef int type;
@ -34,8 +38,11 @@ struct square
struct add
{
template<typename T>
struct result;
template <typename A, typename B>
struct result
struct result<add(A, B)>
{
typedef int type;
};

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);

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;
};

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

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 ));
}

View File

@ -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;
};

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>
{ };
};
};

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>
{ };
};
};

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>
{ };
};
};

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 ));
}

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 ));
}

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 ));
}

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 ));
}

View File

@ -26,8 +26,11 @@
struct square
{
template<typename T>
struct result;
template <typename T>
struct result
struct result<square(T)>
{
typedef int type;
};
@ -41,8 +44,11 @@ struct square
struct add
{
template<typename T>
struct result;
template <typename A, typename B>
struct result
struct result<add(A,B)>
{
typedef int type;
};