From 0d51ecff370af4eb753aef6534b34bff240a8372 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Mon, 15 Jul 2013 16:23:43 +0900 Subject: [PATCH] fix bind for GCC4.7 --- sprout/functional/bind/bind.hpp | 534 +++++++++++++++++++++----------- 1 file changed, 345 insertions(+), 189 deletions(-) diff --git a/sprout/functional/bind/bind.hpp b/sprout/functional/bind/bind.hpp index 8e707f80..e37a4a27 100644 --- a/sprout/functional/bind/bind.hpp +++ b/sprout/functional/bind/bind.hpp @@ -396,6 +396,97 @@ namespace sprout { } } // namespace detail + namespace detail { + template + class binder_impl; + template + class binder_impl + : public sprout::weak_result_type + { + protected: + typedef sprout::tuples::tuple bounds_type; + private: + Functor f_; + bounds_type bound_args_; + protected: + template + Result call(sprout::tuples::tuple&& args, sprout::index_tuple) { + return f_( + sprout::detail::mu::type>() + (sprout::detail::get_bound(bound_args_), args)... + ); + } + template + SPROUT_CONSTEXPR Result call_c(sprout::tuples::tuple&& args, sprout::index_tuple) const { + return f_( + sprout::detail::mu::type const>() + (sprout::detail::get_bound(bound_args_), args)... + ); + } + template + Result call_v(sprout::tuples::tuple&& args, sprout::index_tuple) volatile { + return f_( + sprout::detail::mu::type volatile>() + (sprout::detail::get_bound(bound_args_), args)... + ); + } + template + SPROUT_CONSTEXPR Result call_cv(sprout::tuples::tuple&& args, sprout::index_tuple) const volatile { + return f_( + sprout::detail::mu::type const volatile>() + (sprout::detail::get_bound(bound_args_), args)... + ); + } + public: + template< + typename... Args, sprout::index_t... Indexes + > + static decltype( + std::declval()( + sprout::detail::mu::type>() + (sprout::detail::get_bound(std::declval()), std::declval&>())... + ) + ) + call_(sprout::tuples::tuple&& args, sprout::index_tuple); + template< + typename... Args, sprout::index_t... Indexes + > + static decltype( + std::declval= 0), typename std::add_const::type>::type&>()( + sprout::detail::mu::type const>() + (sprout::detail::get_bound(std::declval()), std::declval&>())... + ) + ) + call_c_(sprout::tuples::tuple&& args, sprout::index_tuple); + template< + typename... Args, sprout::index_t... Indexes + > + static decltype( + std::declval= 0), typename std::add_volatile::type>::type&>()( + sprout::detail::mu::type volatile>() + (sprout::detail::get_bound(std::declval()), std::declval&>())... + ) + ) + call_v_(sprout::tuples::tuple&& args, sprout::index_tuple); + template< + typename... Args, sprout::index_t... Indexes + > + static decltype( + std::declval= 0), typename std::add_cv::type>::type&>()( + sprout::detail::mu::type const volatile>() + (sprout::detail::get_bound(std::declval()), std::declval&>())... + ) + ) + call_cv_(sprout::tuples::tuple&& args, sprout::index_tuple); + public: + template + explicit SPROUT_CONSTEXPR binder_impl(Functor const& f, Args&&... args) + : f_(f) + , bound_args_(sprout::forward(args)...) + {} + binder_impl(binder_impl const&) = default; + }; + } // namespace detail // // binder // @@ -403,99 +494,25 @@ namespace sprout { class binder; template class binder - : public sprout::weak_result_type + : private sprout::detail::binder_impl { private: - typedef binder self_type; - typedef sprout::tuples::tuple bounds_type; - private: - Functor f_; - bounds_type bound_args_; - private: - template - Result call(sprout::tuples::tuple&& args, sprout::index_tuple) { - return f_( - sprout::detail::mu::type>() - (sprout::detail::get_bound(bound_args_), args)... - ); - } - template - SPROUT_CONSTEXPR Result call_c(sprout::tuples::tuple&& args, sprout::index_tuple) const { - return f_( - sprout::detail::mu::type const>() - (sprout::detail::get_bound(bound_args_), args)... - ); - } - template - Result call_v(sprout::tuples::tuple&& args, sprout::index_tuple) volatile { - return f_( - sprout::detail::mu::type volatile>() - (sprout::detail::get_bound(bound_args_), args)... - ); - } - template - SPROUT_CONSTEXPR Result call_cv(sprout::tuples::tuple&& args, sprout::index_tuple) const volatile { - return f_( - sprout::detail::mu::type const volatile>() - (sprout::detail::get_bound(bound_args_), args)... - ); - } - private: - template< - typename... Args, sprout::index_t... Indexes - > - static SPROUT_CONSTEXPR decltype( - std::declval()( - sprout::detail::mu::type>() - (sprout::detail::get_bound(std::declval()), std::declval&>())... - ) - ) - call_(sprout::tuples::tuple&& args, sprout::index_tuple); - template< - typename... Args, sprout::index_t... Indexes - > - static SPROUT_CONSTEXPR decltype( - std::declval= 0), typename std::add_const::type>::type&>()( - sprout::detail::mu::type const>() - (sprout::detail::get_bound(std::declval()), std::declval&>())... - ) - ) - call_c_(sprout::tuples::tuple&& args, sprout::index_tuple); - template< - typename... Args, sprout::index_t... Indexes - > - static SPROUT_CONSTEXPR decltype( - std::declval= 0), typename std::add_volatile::type>::type&>()( - sprout::detail::mu::type volatile>() - (sprout::detail::get_bound(std::declval()), std::declval&>())... - ) - ) - call_v_(sprout::tuples::tuple&& args, sprout::index_tuple); - template< - typename... Args, sprout::index_t... Indexes - > - static SPROUT_CONSTEXPR decltype( - std::declval= 0), typename std::add_cv::type>::type&>()( - sprout::detail::mu::type const volatile>() - (sprout::detail::get_bound(std::declval()), std::declval&>())... - ) - ) - call_cv_(sprout::tuples::tuple&& args, sprout::index_tuple); + typedef sprout::detail::binder_impl impl_type; + typedef typename impl_type::bounds_type bounds_type; public: template explicit SPROUT_CONSTEXPR binder(Functor const& f, Args&&... args) - : f_(f) - , bound_args_(sprout::forward(args)...) + : impl_type(f, sprout::forward(args)...) {} binder(binder const&) = default; template< typename... Args, typename Result = decltype( - call_(std::declval >(), sprout::detail::bound_indexes::make()) + impl_type::template call_(std::declval >(), sprout::detail::bound_indexes::make()) ) > Result operator()(Args&&... args) { - return call( + return impl_type::template call( sprout::tuples::forward_as_tuple(sprout::forward(args)...), sprout::detail::bound_indexes::make() ); @@ -503,11 +520,11 @@ namespace sprout { template< typename... Args, typename Result = decltype( - call_c_(std::declval >(), sprout::detail::bound_indexes::make()) + impl_type::template call_c_(std::declval >(), sprout::detail::bound_indexes::make()) ) > SPROUT_CONSTEXPR Result operator()(Args&&... args) const { - return call_c( + return impl_type::template call_c( sprout::tuples::forward_as_tuple(sprout::forward(args)...), sprout::detail::bound_indexes::make() ); @@ -515,11 +532,11 @@ namespace sprout { template< typename... Args, typename Result = decltype( - call_v_(std::declval >(), sprout::detail::bound_indexes::make()) + impl_type::template call_v_(std::declval >(), sprout::detail::bound_indexes::make()) ) > Result operator()(Args&&... args) volatile { - return call_v( + return impl_type::template call_v( sprout::tuples::forward_as_tuple(sprout::forward(args)...), sprout::detail::bound_indexes::make() ); @@ -527,144 +544,242 @@ namespace sprout { template< typename... Args, typename Result = decltype( - call_cv_(std::declval >(), sprout::detail::bound_indexes::make()) + impl_type::template call_cv_(std::declval >(), sprout::detail::bound_indexes::make()) ) > SPROUT_CONSTEXPR Result operator()(Args&&... args) const volatile { - return call_cv( + return impl_type::template call_cv( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + sprout::detail::bound_indexes::make() + ); + } + }; + // + // cbinder + // + template + class cbinder; + template + class cbinder + : private sprout::detail::binder_impl + { + private: + typedef sprout::detail::binder_impl impl_type; + typedef typename impl_type::bounds_type bounds_type; + public: + template + explicit SPROUT_CONSTEXPR cbinder(Functor const& f, Args&&... args) + : impl_type(f, sprout::forward(args)...) + {} + cbinder(cbinder const&) = default; + template< + typename... Args, + typename Result = decltype( + impl_type::template call_c_(std::declval >(), sprout::detail::bound_indexes::make()) + ) + > + SPROUT_CONSTEXPR Result operator()(Args&&... args) const { + return impl_type::template call_c( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + sprout::detail::bound_indexes::make() + ); + } + template< + typename... Args, + typename Result = decltype( + impl_type::template call_cv_(std::declval >(), sprout::detail::bound_indexes::make()) + ) + > + SPROUT_CONSTEXPR Result operator()(Args&&... args) const volatile { + return impl_type::template call_cv( sprout::tuples::forward_as_tuple(sprout::forward(args)...), sprout::detail::bound_indexes::make() ); } }; + namespace detail { + template + class res_binder_impl; + template + class res_binder_impl { + public: + typedef Result result_type; + protected: + typedef sprout::tuples::tuple bounds_type; + private: + template + struct enable_if_void + : public std::enable_if::value, int> + {}; + template + struct disable_if_void + : public std::enable_if::value, int> + {}; + private: + Functor f_; + sprout::tuples::tuple bound_args_; + protected: + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename disable_if_void::type = 0 + ) + { + return f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename enable_if_void::type = 0 + ) + { + f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); + } + template + SPROUT_CONSTEXPR Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename disable_if_void::type = 0 + ) const + { + return f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename enable_if_void::type = 0 + ) const + { + f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename disable_if_void::type = 0 + ) volatile + { + return f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename enable_if_void::type = 0 + ) volatile + { + f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); + } + template + SPROUT_CONSTEXPR Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename disable_if_void::type = 0 + ) const volatile + { + return f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); + } + template + Result call( + sprout::tuples::tuple&& args, + sprout::index_tuple, + typename enable_if_void::type = 0 + ) const volatile + { + f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); + } + public: + template + explicit res_binder_impl(Functor const& f, Args&&... args) + : f_(f) + , bound_args_(sprout::forward(args)...) + {} + res_binder_impl(res_binder_impl const&) = default; + }; + } // namespace detail // // res_binder // template class res_binder; template - class res_binder { - private: - typedef res_binder self_type; - typedef sprout::tuples::tuple bounds_type; - private: - template - struct enable_if_void - : public std::enable_if::value, int> - {}; - template - struct disable_if_void - : public std::enable_if::value, int> - {}; - private: - Functor f_; - sprout::tuples::tuple bound_args_; - private: - template - Result call( - sprout::tuples::tuple&& args, - sprout::index_tuple, - typename disable_if_void::type = 0 - ) - { - return f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); - } - template - Result call( - sprout::tuples::tuple&& args, - sprout::index_tuple, - typename enable_if_void::type = 0 - ) - { - f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); - } - template - SPROUT_CONSTEXPR Result call( - sprout::tuples::tuple&& args, - sprout::index_tuple, - typename disable_if_void::type = 0 - ) const - { - return f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); - } - template - Result call( - sprout::tuples::tuple&& args, - sprout::index_tuple, - typename enable_if_void::type = 0 - ) const - { - f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); - } - template - Result call( - sprout::tuples::tuple&& args, - sprout::index_tuple, - typename disable_if_void::type = 0 - ) volatile - { - return f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); - } - template - Result call( - sprout::tuples::tuple&& args, - sprout::index_tuple, - typename enable_if_void::type = 0 - ) volatile - { - f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); - } - template - SPROUT_CONSTEXPR Result call( - sprout::tuples::tuple&& args, - sprout::index_tuple, - typename disable_if_void::type = 0 - ) const volatile - { - return f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); - } - template - Result call( - sprout::tuples::tuple&& args, - sprout::index_tuple, - typename enable_if_void::type = 0 - ) const volatile - { - f_(sprout::detail::mu()(sprout::detail::get_bound(bound_args_), args)...); - } + class res_binder + : private sprout::detail::res_binder_impl + { public: typedef Result result_type; + private: + typedef sprout::detail::res_binder_impl impl_type; + typedef typename impl_type::bounds_type bounds_type; + public: template explicit res_binder(Functor const& f, Args&&... args) - : f_(f) - , bound_args_(sprout::forward(args)...) + : impl_type(f, sprout::forward(args)...) {} res_binder(res_binder const&) = default; template result_type operator()(Args&&... args) { - return call( + return impl_type::template call( sprout::tuples::forward_as_tuple(sprout::forward(args)...), sprout::detail::bound_indexes::make() ); } template SPROUT_CONSTEXPR result_type operator()(Args&&... args) const { - return call( + return impl_type::template call( sprout::tuples::forward_as_tuple(sprout::forward(args)...), sprout::detail::bound_indexes::make() ); } template result_type operator()(Args&&... args) volatile { - return call( + return impl_type::template call( sprout::tuples::forward_as_tuple(sprout::forward(args)...), sprout::detail::bound_indexes::make() ); } template SPROUT_CONSTEXPR result_type operator()(Args&&... args) const volatile { - return call( + return impl_type::template call( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + sprout::detail::bound_indexes::make() + ); + } + }; + // + // res_cbinder + // + template + class res_cbinder; + template + class res_cbinder + : private sprout::detail::res_binder_impl + { + public: + typedef Result result_type; + private: + typedef sprout::detail::res_binder_impl impl_type; + typedef typename impl_type::bounds_type bounds_type; + public: + template + explicit SPROUT_CONSTEXPR res_cbinder(Functor const& f, Args&&... args) + : impl_type(f, sprout::forward(args)...) + {} + res_cbinder(res_cbinder const&) = default; + template + SPROUT_CONSTEXPR result_type operator()(Args&&... args) const { + return impl_type::template call( + sprout::tuples::forward_as_tuple(sprout::forward(args)...), + sprout::detail::bound_indexes::make() + ); + } + template + SPROUT_CONSTEXPR result_type operator()(Args&&... args) const volatile { + return impl_type::template call( sprout::tuples::forward_as_tuple(sprout::forward(args)...), sprout::detail::bound_indexes::make() ); @@ -720,12 +835,41 @@ namespace sprout { > >::type {}; + template + struct binder_complete_placeholders_impl< + I, N, Bounds, sprout::cbinder, + typename std::enable_if<(I < sprout::tuples::tuple_size::value)>::type + > + : public std::conditional< + sprout::is_positional_placeholder::type>::value, + sprout::detail::binder_complete_placeholders_impl< + I + 1, N + 1, Bounds, + sprout::cbinder)> + >, + sprout::detail::binder_complete_placeholders_impl< + I + 1, N, Bounds, + sprout::cbinder::type)> + > + >::type + {}; + template + struct binder_complete_placeholders; template - struct binder_complete_placeholders + struct binder_complete_placeholders< + false, Func, BoundArgs... + > : public sprout::detail::binder_complete_placeholders_impl< 0, 0, sprout::types::type_tuple, sprout::binder > {}; + template + struct binder_complete_placeholders< + true, Func, BoundArgs... + > + : public sprout::detail::binder_complete_placeholders_impl< + 0, 0, sprout::types::type_tuple, sprout::cbinder + > + {}; template struct res_binder_complete_placeholders_impl { @@ -756,12 +900,12 @@ namespace sprout { > {}; - template + template struct bind_helper { public: typedef sprout::detail::maybe_wrap_member_pointer::type> maybe_type; typedef typename maybe_type::type func_type; - typedef typename sprout::detail::binder_complete_placeholders::type...>::type type; + typedef typename sprout::detail::binder_complete_placeholders::type...>::type type; }; template struct res_bind_helper { @@ -774,13 +918,22 @@ namespace sprout { // // bind_result - // res_bind_result + // cbind_result // template struct bind_result { public: - typedef typename sprout::detail::bind_helper::type type; + typedef typename sprout::detail::bind_helper::type type; }; + template + struct cbind_result { + public: + typedef typename sprout::detail::bind_helper::type type; + }; + // + // res_bind_result + // res_cbind_result + // template struct res_bind_result { public: @@ -793,7 +946,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::bind_result::type bind(F&& f, BoundArgs&&... args) { - typedef sprout::detail::bind_helper helper_type; + typedef sprout::detail::bind_helper helper_type; typedef typename helper_type::maybe_type maybe_type; typedef typename helper_type::type result_type; return result_type(maybe_type::do_wrap(sprout::forward(f)), sprout::forward(args)...); @@ -811,9 +964,12 @@ namespace sprout { // cbind // template - inline SPROUT_CONSTEXPR typename sprout::detail::bind_helper::type const + inline SPROUT_CONSTEXPR typename sprout::cbind_result::type cbind(F&& f, BoundArgs&&... args) { - return sprout::bind(sprout::forward(f), sprout::forward(args)...); + typedef sprout::detail::bind_helper helper_type; + typedef typename helper_type::maybe_type maybe_type; + typedef typename helper_type::type result_type; + return result_type(maybe_type::do_wrap(sprout::forward(f)), sprout::forward(args)...); } template inline SPROUT_CONSTEXPR typename sprout::detail::res_bind_helper::type const