fix bind for GCC4.7

This commit is contained in:
bolero-MURAKAMI 2013-07-15 16:23:43 +09:00
parent a7def70996
commit 0d51ecff37

View file

@ -396,22 +396,19 @@ namespace sprout {
} }
} // namespace detail } // namespace detail
// namespace detail {
// binder
//
template<typename Signature> template<typename Signature>
class binder; class binder_impl;
template<typename Functor, typename... BoundArgs> template<typename Functor, typename... BoundArgs>
class binder<Functor(BoundArgs...)> class binder_impl<Functor(BoundArgs...)>
: public sprout::weak_result_type<Functor> : public sprout::weak_result_type<Functor>
{ {
private: protected:
typedef binder self_type;
typedef sprout::tuples::tuple<BoundArgs...> bounds_type; typedef sprout::tuples::tuple<BoundArgs...> bounds_type;
private: private:
Functor f_; Functor f_;
bounds_type bound_args_; bounds_type bound_args_;
private: protected:
template<typename Result, typename... Args, sprout::index_t... Indexes> template<typename Result, typename... Args, sprout::index_t... Indexes>
Result call(sprout::tuples::tuple<Args...>&& args, sprout::index_tuple<Indexes...>) { Result call(sprout::tuples::tuple<Args...>&& args, sprout::index_tuple<Indexes...>) {
return f_( return f_(
@ -440,11 +437,11 @@ namespace sprout {
(sprout::detail::get_bound<Indexes, sizeof...(Args)>(bound_args_), args)... (sprout::detail::get_bound<Indexes, sizeof...(Args)>(bound_args_), args)...
); );
} }
private: public:
template< template<
typename... Args, sprout::index_t... Indexes typename... Args, sprout::index_t... Indexes
> >
static SPROUT_CONSTEXPR decltype( static decltype(
std::declval<Functor&>()( std::declval<Functor&>()(
sprout::detail::mu<typename sprout::detail::bound_element<Indexes, bounds_type, sizeof...(Args)>::type>() sprout::detail::mu<typename sprout::detail::bound_element<Indexes, bounds_type, sizeof...(Args)>::type>()
(sprout::detail::get_bound<Indexes, sizeof...(Args)>(std::declval<bounds_type&>()), std::declval<sprout::tuples::tuple<Args...>&>())... (sprout::detail::get_bound<Indexes, sizeof...(Args)>(std::declval<bounds_type&>()), std::declval<sprout::tuples::tuple<Args...>&>())...
@ -454,7 +451,7 @@ namespace sprout {
template< template<
typename... Args, sprout::index_t... Indexes typename... Args, sprout::index_t... Indexes
> >
static SPROUT_CONSTEXPR decltype( static decltype(
std::declval<typename std::enable_if<(sizeof...(Args) >= 0), typename std::add_const<Functor>::type>::type&>()( std::declval<typename std::enable_if<(sizeof...(Args) >= 0), typename std::add_const<Functor>::type>::type&>()(
sprout::detail::mu<typename sprout::detail::bound_element<Indexes, bounds_type, sizeof...(Args)>::type const>() sprout::detail::mu<typename sprout::detail::bound_element<Indexes, bounds_type, sizeof...(Args)>::type const>()
(sprout::detail::get_bound<Indexes, sizeof...(Args)>(std::declval<bounds_type const&>()), std::declval<sprout::tuples::tuple<Args...>&>())... (sprout::detail::get_bound<Indexes, sizeof...(Args)>(std::declval<bounds_type const&>()), std::declval<sprout::tuples::tuple<Args...>&>())...
@ -464,7 +461,7 @@ namespace sprout {
template< template<
typename... Args, sprout::index_t... Indexes typename... Args, sprout::index_t... Indexes
> >
static SPROUT_CONSTEXPR decltype( static decltype(
std::declval<typename std::enable_if<(sizeof...(Args) >= 0), typename std::add_volatile<Functor>::type>::type&>()( std::declval<typename std::enable_if<(sizeof...(Args) >= 0), typename std::add_volatile<Functor>::type>::type&>()(
sprout::detail::mu<typename sprout::detail::bound_element<Indexes, bounds_type, sizeof...(Args)>::type volatile>() sprout::detail::mu<typename sprout::detail::bound_element<Indexes, bounds_type, sizeof...(Args)>::type volatile>()
(sprout::detail::get_bound<Indexes, sizeof...(Args)>(std::declval<bounds_type volatile&>()), std::declval<sprout::tuples::tuple<Args...>&>())... (sprout::detail::get_bound<Indexes, sizeof...(Args)>(std::declval<bounds_type volatile&>()), std::declval<sprout::tuples::tuple<Args...>&>())...
@ -474,7 +471,7 @@ namespace sprout {
template< template<
typename... Args, sprout::index_t... Indexes typename... Args, sprout::index_t... Indexes
> >
static SPROUT_CONSTEXPR decltype( static decltype(
std::declval<typename std::enable_if<(sizeof...(Args) >= 0), typename std::add_cv<Functor>::type>::type&>()( std::declval<typename std::enable_if<(sizeof...(Args) >= 0), typename std::add_cv<Functor>::type>::type&>()(
sprout::detail::mu<typename sprout::detail::bound_element<Indexes, bounds_type, sizeof...(Args)>::type const volatile>() sprout::detail::mu<typename sprout::detail::bound_element<Indexes, bounds_type, sizeof...(Args)>::type const volatile>()
(sprout::detail::get_bound<Indexes, sizeof...(Args)>(std::declval<bounds_type const volatile&>()), std::declval<sprout::tuples::tuple<Args...>&>())... (sprout::detail::get_bound<Indexes, sizeof...(Args)>(std::declval<bounds_type const volatile&>()), std::declval<sprout::tuples::tuple<Args...>&>())...
@ -483,19 +480,39 @@ namespace sprout {
call_cv_(sprout::tuples::tuple<Args...>&& args, sprout::index_tuple<Indexes...>); call_cv_(sprout::tuples::tuple<Args...>&& args, sprout::index_tuple<Indexes...>);
public: public:
template<typename... Args> template<typename... Args>
explicit SPROUT_CONSTEXPR binder(Functor const& f, Args&&... args) explicit SPROUT_CONSTEXPR binder_impl(Functor const& f, Args&&... args)
: f_(f) : f_(f)
, bound_args_(sprout::forward<Args>(args)...) , bound_args_(sprout::forward<Args>(args)...)
{} {}
binder_impl(binder_impl const&) = default;
};
} // namespace detail
//
// binder
//
template<typename Signature>
class binder;
template<typename Functor, typename... BoundArgs>
class binder<Functor(BoundArgs...)>
: private sprout::detail::binder_impl<Functor(BoundArgs...)>
{
private:
typedef sprout::detail::binder_impl<Functor(BoundArgs...)> impl_type;
typedef typename impl_type::bounds_type bounds_type;
public:
template<typename... Args>
explicit SPROUT_CONSTEXPR binder(Functor const& f, Args&&... args)
: impl_type(f, sprout::forward<Args>(args)...)
{}
binder(binder const&) = default; binder(binder const&) = default;
template< template<
typename... Args, typename... Args,
typename Result = decltype( typename Result = decltype(
call_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()) impl_type::template call_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make())
) )
> >
Result operator()(Args&&... args) { Result operator()(Args&&... args) {
return call<Result>( return impl_type::template call<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...), sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make() sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
); );
@ -503,11 +520,11 @@ namespace sprout {
template< template<
typename... Args, typename... Args,
typename Result = decltype( typename Result = decltype(
call_c_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()) impl_type::template call_c_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make())
) )
> >
SPROUT_CONSTEXPR Result operator()(Args&&... args) const { SPROUT_CONSTEXPR Result operator()(Args&&... args) const {
return call_c<Result>( return impl_type::template call_c<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...), sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make() sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
); );
@ -515,11 +532,11 @@ namespace sprout {
template< template<
typename... Args, typename... Args,
typename Result = decltype( typename Result = decltype(
call_v_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()) impl_type::template call_v_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make())
) )
> >
Result operator()(Args&&... args) volatile { Result operator()(Args&&... args) volatile {
return call_v<Result>( return impl_type::template call_v<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...), sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make() sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
); );
@ -527,26 +544,68 @@ namespace sprout {
template< template<
typename... Args, typename... Args,
typename Result = decltype( typename Result = decltype(
call_cv_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()) impl_type::template call_cv_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make())
) )
> >
SPROUT_CONSTEXPR Result operator()(Args&&... args) const volatile { SPROUT_CONSTEXPR Result operator()(Args&&... args) const volatile {
return call_cv<Result>( return impl_type::template call_cv<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
);
}
};
//
// cbinder
//
template<typename Signature>
class cbinder;
template<typename Functor, typename... BoundArgs>
class cbinder<Functor(BoundArgs...)>
: private sprout::detail::binder_impl<Functor(BoundArgs...)>
{
private:
typedef sprout::detail::binder_impl<Functor(BoundArgs...)> impl_type;
typedef typename impl_type::bounds_type bounds_type;
public:
template<typename... Args>
explicit SPROUT_CONSTEXPR cbinder(Functor const& f, Args&&... args)
: impl_type(f, sprout::forward<Args>(args)...)
{}
cbinder(cbinder const&) = default;
template<
typename... Args,
typename Result = decltype(
impl_type::template call_c_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make())
)
>
SPROUT_CONSTEXPR Result operator()(Args&&... args) const {
return impl_type::template call_c<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
);
}
template<
typename... Args,
typename Result = decltype(
impl_type::template call_cv_(std::declval<sprout::tuples::tuple<Args...> >(), sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make())
)
>
SPROUT_CONSTEXPR Result operator()(Args&&... args) const volatile {
return impl_type::template call_cv<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...), sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make() sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
); );
} }
}; };
// namespace detail {
// res_binder
//
template<typename Result, typename Signature> template<typename Result, typename Signature>
class res_binder; class res_binder_impl;
template<typename Result, typename Functor, typename... BoundArgs> template<typename Result, typename Functor, typename... BoundArgs>
class res_binder<Result, Functor(BoundArgs...)> { class res_binder_impl<Result, Functor(BoundArgs...)> {
private: public:
typedef res_binder self_type; typedef Result result_type;
protected:
typedef sprout::tuples::tuple<BoundArgs...> bounds_type; typedef sprout::tuples::tuple<BoundArgs...> bounds_type;
private: private:
template<typename Res> template<typename Res>
@ -560,7 +619,7 @@ namespace sprout {
private: private:
Functor f_; Functor f_;
sprout::tuples::tuple<BoundArgs...> bound_args_; sprout::tuples::tuple<BoundArgs...> bound_args_;
private: protected:
template<typename Res, typename... Args, sprout::index_t... Indexes> template<typename Res, typename... Args, sprout::index_t... Indexes>
Result call( Result call(
sprout::tuples::tuple<Args...>&& args, sprout::tuples::tuple<Args...>&& args,
@ -634,37 +693,93 @@ namespace sprout {
f_(sprout::detail::mu<BoundArgs>()(sprout::detail::get_bound<Indexes, sizeof...(Args)>(bound_args_), args)...); f_(sprout::detail::mu<BoundArgs>()(sprout::detail::get_bound<Indexes, sizeof...(Args)>(bound_args_), args)...);
} }
public: public:
typedef Result result_type;
template<typename... Args> template<typename... Args>
explicit res_binder(Functor const& f, Args&&... args) explicit res_binder_impl(Functor const& f, Args&&... args)
: f_(f) : f_(f)
, bound_args_(sprout::forward<Args>(args)...) , bound_args_(sprout::forward<Args>(args)...)
{} {}
res_binder_impl(res_binder_impl const&) = default;
};
} // namespace detail
//
// res_binder
//
template<typename Result, typename Signature>
class res_binder;
template<typename Result, typename Functor, typename... BoundArgs>
class res_binder<Result, Functor(BoundArgs...)>
: private sprout::detail::res_binder_impl<Result, Functor(BoundArgs...)>
{
public:
typedef Result result_type;
private:
typedef sprout::detail::res_binder_impl<Result, Functor(BoundArgs...)> impl_type;
typedef typename impl_type::bounds_type bounds_type;
public:
template<typename... Args>
explicit res_binder(Functor const& f, Args&&... args)
: impl_type(f, sprout::forward<Args>(args)...)
{}
res_binder(res_binder const&) = default; res_binder(res_binder const&) = default;
template<typename... Args> template<typename... Args>
result_type operator()(Args&&... args) { result_type operator()(Args&&... args) {
return call<Result>( return impl_type::template call<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...), sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make() sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
); );
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR result_type operator()(Args&&... args) const { SPROUT_CONSTEXPR result_type operator()(Args&&... args) const {
return call<Result>( return impl_type::template call<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...), sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make() sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
); );
} }
template<typename... Args> template<typename... Args>
result_type operator()(Args&&... args) volatile { result_type operator()(Args&&... args) volatile {
return call<Result>( return impl_type::template call<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...), sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make() sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
); );
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR result_type operator()(Args&&... args) const volatile { SPROUT_CONSTEXPR result_type operator()(Args&&... args) const volatile {
return call<Result>( return impl_type::template call<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
);
}
};
//
// res_cbinder
//
template<typename Result, typename Signature>
class res_cbinder;
template<typename Result, typename Functor, typename... BoundArgs>
class res_cbinder<Result, Functor(BoundArgs...)>
: private sprout::detail::res_binder_impl<Result, Functor(BoundArgs...)>
{
public:
typedef Result result_type;
private:
typedef sprout::detail::res_binder_impl<Result, Functor(BoundArgs...)> impl_type;
typedef typename impl_type::bounds_type bounds_type;
public:
template<typename... Args>
explicit SPROUT_CONSTEXPR res_cbinder(Functor const& f, Args&&... args)
: impl_type(f, sprout::forward<Args>(args)...)
{}
res_cbinder(res_cbinder const&) = default;
template<typename... Args>
SPROUT_CONSTEXPR result_type operator()(Args&&... args) const {
return impl_type::template call<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
);
}
template<typename... Args>
SPROUT_CONSTEXPR result_type operator()(Args&&... args) const volatile {
return impl_type::template call<Result>(
sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...), sprout::tuples::forward_as_tuple(sprout::forward<Args>(args)...),
sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make() sprout::detail::bound_indexes<bounds_type, sizeof...(Args)>::make()
); );
@ -720,12 +835,41 @@ namespace sprout {
> >
>::type >::type
{}; {};
template<std::size_t I, std::size_t N, typename Bounds, typename Func, typename... As>
struct binder_complete_placeholders_impl<
I, N, Bounds, sprout::cbinder<Func (As...)>,
typename std::enable_if<(I < sprout::tuples::tuple_size<Bounds>::value)>::type
>
: public std::conditional<
sprout::is_positional_placeholder<typename sprout::tuples::tuple_element<I, Bounds>::type>::value,
sprout::detail::binder_complete_placeholders_impl<
I + 1, N + 1, Bounds,
sprout::cbinder<Func (As..., sprout::placeholder<N + 1>)>
>,
sprout::detail::binder_complete_placeholders_impl<
I + 1, N, Bounds,
sprout::cbinder<Func (As..., typename sprout::tuples::tuple_element<I, Bounds>::type)>
>
>::type
{};
template<bool Const, typename Func, typename... BoundArgs>
struct binder_complete_placeholders;
template<typename Func, typename... BoundArgs> template<typename Func, typename... BoundArgs>
struct binder_complete_placeholders struct binder_complete_placeholders<
false, Func, BoundArgs...
>
: public sprout::detail::binder_complete_placeholders_impl< : public sprout::detail::binder_complete_placeholders_impl<
0, 0, sprout::types::type_tuple<BoundArgs...>, sprout::binder<Func ()> 0, 0, sprout::types::type_tuple<BoundArgs...>, sprout::binder<Func ()>
> >
{}; {};
template<typename Func, typename... BoundArgs>
struct binder_complete_placeholders<
true, Func, BoundArgs...
>
: public sprout::detail::binder_complete_placeholders_impl<
0, 0, sprout::types::type_tuple<BoundArgs...>, sprout::cbinder<Func ()>
>
{};
template<std::size_t I, std::size_t N, typename Bounds, typename Binder, typename = void> template<std::size_t I, std::size_t N, typename Bounds, typename Binder, typename = void>
struct res_binder_complete_placeholders_impl { struct res_binder_complete_placeholders_impl {
@ -756,12 +900,12 @@ namespace sprout {
> >
{}; {};
template<typename Func, typename... BoundArgs> template<bool Const, typename Func, typename... BoundArgs>
struct bind_helper { struct bind_helper {
public: public:
typedef sprout::detail::maybe_wrap_member_pointer<typename std::decay<Func>::type> maybe_type; typedef sprout::detail::maybe_wrap_member_pointer<typename std::decay<Func>::type> maybe_type;
typedef typename maybe_type::type func_type; typedef typename maybe_type::type func_type;
typedef typename sprout::detail::binder_complete_placeholders<func_type, typename std::decay<BoundArgs>::type...>::type type; typedef typename sprout::detail::binder_complete_placeholders<Const, func_type, typename std::decay<BoundArgs>::type...>::type type;
}; };
template<typename Result, typename Func, typename... BoundArgs> template<typename Result, typename Func, typename... BoundArgs>
struct res_bind_helper { struct res_bind_helper {
@ -774,13 +918,22 @@ namespace sprout {
// //
// bind_result // bind_result
// res_bind_result // cbind_result
// //
template<typename F, typename... BoundArgs> template<typename F, typename... BoundArgs>
struct bind_result { struct bind_result {
public: public:
typedef typename sprout::detail::bind_helper<F, BoundArgs...>::type type; typedef typename sprout::detail::bind_helper<false, F, BoundArgs...>::type type;
}; };
template<typename F, typename... BoundArgs>
struct cbind_result {
public:
typedef typename sprout::detail::bind_helper<true, F, BoundArgs...>::type type;
};
//
// res_bind_result
// res_cbind_result
//
template<typename R, typename F, typename... BoundArgs> template<typename R, typename F, typename... BoundArgs>
struct res_bind_result { struct res_bind_result {
public: public:
@ -793,7 +946,7 @@ namespace sprout {
template<typename F, typename... BoundArgs> template<typename F, typename... BoundArgs>
inline SPROUT_CONSTEXPR typename sprout::bind_result<F, BoundArgs...>::type inline SPROUT_CONSTEXPR typename sprout::bind_result<F, BoundArgs...>::type
bind(F&& f, BoundArgs&&... args) { bind(F&& f, BoundArgs&&... args) {
typedef sprout::detail::bind_helper<F, BoundArgs...> helper_type; typedef sprout::detail::bind_helper<false, F, BoundArgs...> helper_type;
typedef typename helper_type::maybe_type maybe_type; typedef typename helper_type::maybe_type maybe_type;
typedef typename helper_type::type result_type; typedef typename helper_type::type result_type;
return result_type(maybe_type::do_wrap(sprout::forward<F>(f)), sprout::forward<BoundArgs>(args)...); return result_type(maybe_type::do_wrap(sprout::forward<F>(f)), sprout::forward<BoundArgs>(args)...);
@ -811,9 +964,12 @@ namespace sprout {
// cbind // cbind
// //
template<typename F, typename... BoundArgs> template<typename F, typename... BoundArgs>
inline SPROUT_CONSTEXPR typename sprout::detail::bind_helper<F, BoundArgs...>::type const inline SPROUT_CONSTEXPR typename sprout::cbind_result<F, BoundArgs...>::type
cbind(F&& f, BoundArgs&&... args) { cbind(F&& f, BoundArgs&&... args) {
return sprout::bind(sprout::forward<F>(f), sprout::forward<BoundArgs>(args)...); typedef sprout::detail::bind_helper<true, F, BoundArgs...> 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>(f)), sprout::forward<BoundArgs>(args)...);
} }
template<typename R, typename F, typename... BoundArgs> template<typename R, typename F, typename... BoundArgs>
inline SPROUT_CONSTEXPR typename sprout::detail::res_bind_helper<R, F, BoundArgs...>::type const inline SPROUT_CONSTEXPR typename sprout::detail::res_bind_helper<R, F, BoundArgs...>::type const