HelenOS sources
This source file includes following definitions.
- decltype
- decltype
- decltype
- decltype
- decltype
#ifndef LIBCPP_BITS_FUNCTIONAL_BIND
#define LIBCPP_BITS_FUNCTIONAL_BIND
#include <__bits/functional/function.hpp>
#include <__bits/functional/invoke.hpp>
#include <__bits/functional/reference_wrapper.hpp>
#include <cassert>
#include <tuple>
#include <type_traits>
#include <utility>
namespace std
{
namespace aux
{
template<int N>
struct placeholder_t
{
constexpr placeholder_t() = default;
constexpr placeholder_t(const placeholder_t&) = default;
constexpr placeholder_t(placeholder_t&&) = default;
};
}
template<class T>
struct is_placeholder: integral_constant<int, 0>
{ };
template<int N>
struct is_placeholder<const aux::placeholder_t<N>>
: integral_constant<int, N>
{ };
template<class T>
inline constexpr int is_placeholder_v = is_placeholder<T>::value;
namespace aux
{
template<class, bool = false>
struct bind_conditional_result_type
{ };
template<class R>
struct bind_conditional_result_type<R, true>
{
using result_type = R;
};
template<class, bool, class, class...>
class bind_t;
template<class... Args>
class bind_arg_filter
{
public:
bind_arg_filter(Args&&... args)
: args_{forward<Args>(args)...}
{ }
template<class T>
constexpr decltype(auto) operator[](T&& t)
{
return forward<T>(t);
}
template<int N>
constexpr decltype(auto) operator[](const placeholder_t<N>)
{
return get<N - 1>(args_);
}
template<class T>
constexpr T& operator[](reference_wrapper<T> ref)
{
return ref.get();
}
template<class R, bool B, class F, class... BindArgs>
constexpr decltype(auto) operator[](const bind_t<R, B, F, BindArgs...> b)
{
__unimplemented();
return b;
}
private:
tuple<Args...> args_;
};
template<class R, bool HasResultType, class F, class... Args>
class bind_t: public bind_conditional_result_type<R, HasResultType>
{
public:
template<class G, class... BoundArgs>
constexpr bind_t(G&& g, BoundArgs&&... args)
: func_{forward<F>(g)},
bound_args_{forward<Args>(args)...}
{ }
constexpr bind_t(const bind_t& other) = default;
constexpr bind_t(bind_t&& other) = default;
template<class... ActualArgs>
constexpr decltype(auto) operator()(ActualArgs&&... args)
{
return invoke_(
make_index_sequence<sizeof...(Args)>{},
forward<ActualArgs>(args)...
);
}
private:
function<remove_reference_t<F>> func_;
tuple<decay_t<Args>...> bound_args_;
template<size_t... Is, class... ActualArgs>
constexpr decltype(auto) invoke_(
index_sequence<Is...>, ActualArgs&&... args
)
{
bind_arg_filter<ActualArgs...> filter{forward<ActualArgs>(args)...};
return aux::INVOKE(
func_,
filter[get<Is>(bound_args_)]...
);
}
};
}
template<class T>
struct is_bind_expression: false_type
{ };
template<class R, bool B, class F, class... Args>
struct is_bind_expression<aux::bind_t<R, B, F, Args...>>
: true_type
{ };
template<class F, class... Args>
aux::bind_t<void, false, F, Args...> bind(F&& f, Args&&... args)
{
return aux::bind_t<void, false, F, Args...>{forward<F>(f), forward<Args>(args)...};
}
template<class R, class F, class... Args>
aux::bind_t<R, true, F, Args...> bind(F&& f, Args&&... args)
{
return aux::bind_t<R, true, F, Args...>{forward<F>(f), forward<Args>(args)...};
}
namespace placeholders
{
inline constexpr aux::placeholder_t<1> _1;
inline constexpr aux::placeholder_t<2> _2;
inline constexpr aux::placeholder_t<3> _3;
inline constexpr aux::placeholder_t<4> _4;
inline constexpr aux::placeholder_t<5> _5;
inline constexpr aux::placeholder_t<6> _6;
inline constexpr aux::placeholder_t<7> _7;
inline constexpr aux::placeholder_t<8> _8;
}
}
#endif
HelenOS homepage, sources at GitHub