diff --git a/include/boost/fusion/functional/invocation/invoke.hpp b/include/boost/fusion/functional/invocation/invoke.hpp index 2de4fced..c2e11408 100644 --- a/include/boost/fusion/functional/invocation/invoke.hpp +++ b/include/boost/fusion/functional/invocation/invoke.hpp @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -52,29 +53,10 @@ namespace boost { namespace fusion { - //~ namespace result_of - //~ { - //~ template - //~ struct invoke; - //~ } - - //~ template - //~ inline typename result_of::invoke::type - //~ invoke(Function, Sequence &); - - //~ template - //~ inline typename result_of::invoke::type - //~ invoke(Function, Sequence const &); - - //----- ---- --- -- - - - - - namespace detail { namespace ft = function_types; - template struct always_void_ { typedef T type; }; - template< typename Function, class Sequence, int N = result_of::size::value, @@ -161,14 +143,20 @@ namespace boost { namespace fusion namespace result_of { - template ::type, Sequence - >::result_type> - struct invoke + template + struct invoke; + + template + struct invoke::type, Sequence + >::result_type + >::type> { - typedef Enable type; + typedef typename detail::invoke_impl< + typename boost::remove_reference::type, Sequence + >::result_type type; }; } @@ -207,7 +195,7 @@ namespace boost { namespace fusion template struct invoke_impl::type >::type> { @@ -301,7 +289,7 @@ namespace boost { namespace fusion template struct invoke_impl::BOOST_PP_CAT(T, j) typename boost::result_of::type >::type> diff --git a/include/boost/fusion/functional/invocation/invoke_function_object.hpp b/include/boost/fusion/functional/invocation/invoke_function_object.hpp index a5c9510c..95e8cb92 100644 --- a/include/boost/fusion/functional/invocation/invoke_function_object.hpp +++ b/include/boost/fusion/functional/invocation/invoke_function_object.hpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -34,29 +35,13 @@ namespace boost { namespace fusion { - namespace result_of - { - template struct invoke_function_object; - } - - template - BOOST_FUSION_GPU_ENABLED - inline typename result_of::invoke_function_object::type - invoke_function_object(Function, Sequence &); - - template - BOOST_FUSION_GPU_ENABLED - inline typename result_of::invoke_function_object::type invoke_function_object(Function, Sequence const &); - - //----- ---- --- -- - - - - - namespace detail { template< class Function, class Sequence, int N = result_of::size::value, - bool RandomAccess = traits::is_random_access::value + bool RandomAccess = traits::is_random_access::value, + typename Enable = void > struct invoke_function_object_impl; @@ -72,7 +57,16 @@ namespace boost { namespace fusion namespace result_of { - template struct invoke_function_object + template + struct invoke_function_object; + + template + struct invoke_function_object::type, Sequence + >::result_type + >::type> { typedef typename detail::invoke_function_object_impl< typename boost::remove_reference::type, Sequence @@ -111,14 +105,18 @@ namespace boost { namespace fusion /////////////////////////////////////////////////////////////////////////////// #define N BOOST_PP_ITERATION() +#define M(z,j,data) \ + typename result_of::at_c::type + template - struct invoke_function_object_impl + struct invoke_function_object_impl::type + >::type> { public: typedef typename boost::result_of< -#define M(z,j,data) \ - typename result_of::at_c::type Function (BOOST_PP_ENUM(N,M,~)) >::type result_type; #undef M @@ -148,8 +146,15 @@ namespace boost { namespace fusion }; +#define M(z,j,data) \ + typename invoke_function_object_param_types::T ## j + template - struct invoke_function_object_impl + struct invoke_function_object_impl::type + >::type> +#undef M { private: typedef invoke_function_object_param_types seq; diff --git a/include/boost/fusion/functional/invocation/invoke_procedure.hpp b/include/boost/fusion/functional/invocation/invoke_procedure.hpp index bd3e49b9..ca5a9592 100644 --- a/include/boost/fusion/functional/invocation/invoke_procedure.hpp +++ b/include/boost/fusion/functional/invocation/invoke_procedure.hpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -38,24 +39,6 @@ namespace boost { namespace fusion { - namespace result_of - { - template struct invoke_procedure - { - typedef void type; - }; - } - - template - BOOST_FUSION_GPU_ENABLED - inline void invoke_procedure(Function, Sequence &); - - template - BOOST_FUSION_GPU_ENABLED - inline void invoke_procedure(Function, Sequence const &); - - //----- ---- --- -- - - - - - namespace detail { namespace ft = function_types; @@ -76,9 +59,27 @@ namespace boost { namespace fusion } + namespace result_of + { + template + struct invoke_procedure; + + template + struct invoke_procedure::type,Sequence + >::result_type + >::type> + { + typedef void type; + }; + } + template BOOST_FUSION_GPU_ENABLED - inline void invoke_procedure(Function f, Sequence & s) + inline typename result_of::invoke_procedure::type + invoke_procedure(Function f, Sequence & s) { detail::invoke_procedure_impl< typename boost::remove_reference::type,Sequence @@ -87,7 +88,8 @@ namespace boost { namespace fusion template BOOST_FUSION_GPU_ENABLED - inline void invoke_procedure(Function f, Sequence const & s) + inline typename result_of::invoke_procedure::type + invoke_procedure(Function f, Sequence const & s) { detail::invoke_procedure_impl< typename boost::remove_reference::type,Sequence const @@ -110,6 +112,7 @@ namespace boost { namespace fusion template struct invoke_procedure_impl { + typedef void result_type; #if N > 0 @@ -135,6 +138,8 @@ namespace boost { namespace fusion template struct invoke_procedure_impl { + typedef void result_type; + BOOST_FUSION_GPU_ENABLED static inline void call(Function & f, Sequence & s) { @@ -155,6 +160,7 @@ namespace boost { namespace fusion template struct invoke_procedure_impl { + typedef void result_type; #if N > 0 @@ -182,6 +188,8 @@ namespace boost { namespace fusion template struct invoke_procedure_impl { + typedef void result_type; + BOOST_FUSION_GPU_ENABLED static inline void call(Function & f, Sequence & s) { diff --git a/include/boost/fusion/support/detail/enabler.hpp b/include/boost/fusion/support/detail/enabler.hpp new file mode 100644 index 00000000..48b69f32 --- /dev/null +++ b/include/boost/fusion/support/detail/enabler.hpp @@ -0,0 +1,18 @@ +/*============================================================================= + Copyright (c) 2015 Kohei Takahashi + + Use modification and distribution are subject to 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). +==============================================================================*/ +#ifndef FUSION_DETAIL_ENABLER_02082015_163810 +#define FUSION_DETAIL_ENABLER_02082015_163810 + +namespace boost { namespace fusion { namespace detail +{ + template + struct enabler { typedef T type; }; +}}} + +#endif + diff --git a/test/compile_time/sfinae_friendly.hpp b/test/compile_time/sfinae_friendly.hpp new file mode 100644 index 00000000..77b148b8 --- /dev/null +++ b/test/compile_time/sfinae_friendly.hpp @@ -0,0 +1,54 @@ +/*============================================================================= + Copyright (c) 2015 Kohei Takahashi + + Use modification and distribution are subject to 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). +==============================================================================*/ + +#ifndef FUSION_TEST_SFINAE_FRIENDLY_HPP +#define FUSION_TEST_SFINAE_FRIENDLY_HPP + +#include +#include +#include +#include + +#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_FUSION_NO_DECLTYPE_BASED_RESULT_OF) + +#include + +namespace sfinae_friendly +{ + template struct void_ { typedef T type; }; + + template struct arg_; + template struct arg_ { typedef T type; }; + + template + struct check + : boost::mpl::true_ { }; + + template + struct check::type> + : boost::mpl::false_ { }; + + struct unspecified {}; + typedef boost::fusion::vector<> v0; + typedef boost::fusion::vector v1; + typedef boost::fusion::vector v2; + typedef boost::fusion::vector v3; +} + +#define SFINAE_FRIENDLY_ASSERT(Traits) \ + BOOST_MPL_ASSERT((::sfinae_friendly::check::type>)) + +#else + +#define SFINAE_FRIENDLY_ASSERT(Traits) \ + BOOST_MPL_ASSERT((boost::mpl::true_)) + +#endif + +#endif // FUSION_TEST_SFINAE_FRIENDLY_HPP + diff --git a/test/functional/invoke.cpp b/test/functional/invoke.cpp index 5975e79b..2a94539f 100644 --- a/test/functional/invoke.cpp +++ b/test/functional/invoke.cpp @@ -82,11 +82,10 @@ struct fobj int operator()(int i, object const &, object_nc &); int operator()(int i, object const &, object_nc &) const; }; -// FIXME: -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); struct nullary_fobj @@ -96,10 +95,9 @@ struct nullary_fobj int operator()() { return 0; } int operator()() const { return 1; } }; -// FIXME: -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); struct fobj_nc @@ -118,11 +116,10 @@ struct fobj_nc int operator()(int i) { return 14 + i; } int operator()(int i) const { return 15 + i; } }; -// FIXME: -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); struct nullary_fobj_nc @@ -133,10 +130,9 @@ struct nullary_fobj_nc int operator()() { return 12; } int operator()() const { return 13; } }; -// FIXME: -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke)); int nullary() { return 16; } diff --git a/test/functional/invoke_function_object.cpp b/test/functional/invoke_function_object.cpp index 176be186..7c75f06d 100644 --- a/test/functional/invoke_function_object.cpp +++ b/test/functional/invoke_function_object.cpp @@ -84,11 +84,9 @@ struct fobj int operator()(int i, object const &, object_nc &); int operator()(int i, object const &, object_nc &) const; }; -// FIXME: -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); struct nullary_fobj { @@ -97,10 +95,9 @@ struct nullary_fobj int operator()() { return 0; } int operator()() const { return 1; } }; -// FIXME: -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); struct fobj_nc : boost::noncopyable @@ -118,11 +115,10 @@ struct fobj_nc int operator()(int i) { return 14 + i; } int operator()(int i) const { return 15 + i; } }; -// FIXME: -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); struct nullary_fobj_nc : boost::noncopyable @@ -132,10 +128,9 @@ struct nullary_fobj_nc int operator()() { return 12; } int operator()() const { return 13; } }; -// FIXME: -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); -//SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); +SFINAE_FRIENDLY_ASSERT((fusion::result_of::invoke_function_object)); typedef int element1_type;