Edit: /usr/include/boost/hof/placeholders.hpp (13799B)
/*=============================================================================
Copyright (c) 2014 Paul Fultz II
placeholders.h
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)
==============================================================================*/
#ifndef BOOST_HOF_GUARD_FUNCTION_PLACEHOLDERS_H
#define BOOST_HOF_GUARD_FUNCTION_PLACEHOLDERS_H
/// placeholders
/// ============
///
/// Description
/// -----------
///
/// The placeholders provide `std::bind` compatible placeholders that
/// additionally provide basic C++ operators that creates bind expressions.
/// Each bind expression supports `constexpr` function evaluation.
///
/// Synopsis
/// --------
///
/// namespace placeholders {
/// placeholder<1> _1 = {};
/// placeholder<2> _2 = {};
/// placeholder<3> _3 = {};
/// placeholder<4> _4 = {};
/// placeholder<5> _5 = {};
/// placeholder<6> _6 = {};
/// placeholder<7> _7 = {};
/// placeholder<8> _8 = {};
/// placeholder<9> _9 = {};
/// }
///
/// Operators
/// ---------
///
/// * Binary operators: +,-,*,/,%,>>,<<,>,<,<=,>=,==,!=,&,^,|,&&,||
/// * Assign operators: +=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=
/// * Unary operators: !,~,+,-,*,++,--
///
///
/// Example
/// -------
///
/// #include
/// #include
/// using namespace boost::hof;
///
/// int main() {
/// auto sum = _1 + _2;
/// assert(3 == sum(1, 2));
/// }
///
///
/// unamed placeholder
/// ==================
///
/// Description
/// -----------
///
/// The unamed placeholder can be used to build simple functions from C++
/// operators.
///
/// Note: The function produced by the unamed placeholder is not a bind expression.
///
/// Synopsis
/// --------
///
/// namespace placeholders {
/// /* unspecified */ _ = {};
/// }
///
/// Example
/// -------
///
/// #include
/// #include
/// using namespace boost::hof;
///
/// int main() {
/// auto sum = _ + _;
/// assert(3 == sum(1, 2));
/// }
///
#include
#include
#include
#if defined(_MSC_VER) && _MSC_VER >= 1910
#include
#endif
namespace boost { namespace hof { namespace detail {
template
struct simple_placeholder
{};
}}} // namespace boost::hof
namespace std {
template
struct is_placeholder>
: std::integral_constant
{};
}
namespace boost { namespace hof {
#define BOOST_HOF_FOREACH_BINARY_OP(m) \
m(+, add) \
m(-, subtract) \
m(*, multiply) \
m(/, divide) \
m(%, remainder) \
m(>>, shift_right) \
m(<<, shift_left) \
m(>, greater_than) \
m(<, less_than) \
m(<=, less_than_equal) \
m(>=, greater_than_equal) \
m(==, equal) \
m(!=, not_equal) \
m(&, bit_and) \
m(^, xor_) \
m(|, bit_or) \
m(&&, and_) \
m(||, or_)
#define BOOST_HOF_FOREACH_ASSIGN_OP(m) \
m(+=, assign_add) \
m(-=, assign_subtract) \
m(*=, assign_multiply) \
m(/=, assign_divide) \
m(%=, assign_remainder) \
m(>>=, assign_right_shift) \
m(<<=, assign_left_shift) \
m(&=, assign_bit_and) \
m(|=, assign_bit_or) \
m(^=, assign_xor)
#ifndef _MSC_VER
#define BOOST_HOF_FOREACH_UNARY_OP(m) \
m(!, not_) \
m(~, compl_) \
m(+, unary_plus) \
m(-, unary_subtract) \
m(*, dereference) \
m(++, increment) \
m(--, decrement)
#else
#define BOOST_HOF_FOREACH_UNARY_OP(m) \
m(!, not_) \
m(~, compl_) \
m(+, unary_plus) \
m(-, unary_subtract) \
m(*, dereference)
#endif
namespace operators {
struct call
{
template
constexpr auto operator()(F&& f, Ts&&... xs) const BOOST_HOF_RETURNS
(f(BOOST_HOF_FORWARD(Ts)(xs)...));
};
// MSVC 2017 ICEs on && and || in conxtexpr, so we fallback on bitwise operators
#if defined(_MSC_VER) && _MSC_VER >= 1910
#define BOOST_HOF_BINARY_OP_SKIP_and_ ()
#define BOOST_HOF_BINARY_OP_SKIP_or_ ()
struct and_
{
template
constexpr auto operator()(T&& x, U&& y) const
noexcept(noexcept(BOOST_HOF_FORWARD(T)(x) && BOOST_HOF_FORWARD(U)(y)))
-> decltype(BOOST_HOF_FORWARD(T)(x) && BOOST_HOF_FORWARD(U)(y))
{ return BOOST_HOF_FORWARD(T)(x) & BOOST_HOF_FORWARD(U)(y); }
};
struct or_
{
template
constexpr auto operator()(T&& x, U&& y) const
noexcept(noexcept(BOOST_HOF_FORWARD(T)(x) || BOOST_HOF_FORWARD(U)(y)))
-> decltype(BOOST_HOF_FORWARD(T)(x) || BOOST_HOF_FORWARD(U)(y))
{ return BOOST_HOF_FORWARD(T)(x) | BOOST_HOF_FORWARD(U)(y); }
};
#define BOOST_HOF_BINARY_OP_IMPL(op, name) \
struct name \
{ \
template \
BOOST_HOF_USING(ex_failure, decltype(std::declval() op std::declval())); \
struct failure : as_failure {}; \
template \
constexpr auto operator()(T&& x, U&& y) const BOOST_HOF_RETURNS \
(BOOST_HOF_FORWARD(T)(x) op BOOST_HOF_FORWARD(U)(y)); \
};
#define BOOST_HOF_BINARY_OP(op, name) \
BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_PP_CAT(BOOST_HOF_BINARY_OP_SKIP_, name))) \
(BOOST_HOF_PP_EMPTY, BOOST_HOF_BINARY_OP_IMPL)(op, name)
#else
#define BOOST_HOF_BINARY_OP(op, name) \
struct name \
{ \
template \
constexpr auto operator()(T&& x, U&& y) const BOOST_HOF_RETURNS \
(BOOST_HOF_FORWARD(T)(x) op BOOST_HOF_FORWARD(U)(y)); \
};
#endif
BOOST_HOF_FOREACH_BINARY_OP(BOOST_HOF_BINARY_OP)
BOOST_HOF_FOREACH_ASSIGN_OP(BOOST_HOF_BINARY_OP)
#define BOOST_HOF_UNARY_OP(op, name) \
struct name \
{ \
template \
constexpr auto operator()(T&& x) const BOOST_HOF_RETURNS \
(op(BOOST_HOF_FORWARD(T)(x))); \
};
BOOST_HOF_FOREACH_UNARY_OP(BOOST_HOF_UNARY_OP)
}
template
struct placeholder
{
#if BOOST_HOF_HAS_MANGLE_OVERLOAD
template
constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
( boost::hof::lazy(operators::call())(detail::simple_placeholder(), BOOST_HOF_FORWARD(Ts)(xs)...) );
#else
template
struct result_call
{ typedef decltype(boost::hof::lazy(operators::call())(detail::simple_placeholder(), std::declval()...)) type; };
template
constexpr typename result_call::type operator()(Ts&&... xs) const
{ return boost::hof::lazy(operators::call())(detail::simple_placeholder(), BOOST_HOF_FORWARD(Ts)(xs)...); };
#endif
#define BOOST_HOF_PLACEHOLDER_UNARY_OP(op, name) \
constexpr auto operator op () const BOOST_HOF_RETURNS \
( boost::hof::lazy(operators::name())(detail::simple_placeholder()) );
BOOST_HOF_FOREACH_UNARY_OP(BOOST_HOF_PLACEHOLDER_UNARY_OP)
#define BOOST_HOF_PLACEHOLDER_ASSIGN_OP(op, name) \
template \
constexpr auto operator op (T&& x) const BOOST_HOF_RETURNS \
( boost::hof::lazy(operators::name())(detail::simple_placeholder(), BOOST_HOF_FORWARD(T)(x)) );
BOOST_HOF_FOREACH_ASSIGN_OP(BOOST_HOF_PLACEHOLDER_ASSIGN_OP)
};
#if BOOST_HOF_HAS_MANGLE_OVERLOAD
#define BOOST_HOF_PLACEHOLDER_BINARY_OP(op, name) \
template \
constexpr inline auto operator op (const placeholder&, T&& x) BOOST_HOF_RETURNS \
( boost::hof::lazy(operators::name())(detail::simple_placeholder(), BOOST_HOF_FORWARD(T)(x)) ); \
template \
constexpr inline auto operator op (T&& x, const placeholder&) BOOST_HOF_RETURNS \
( boost::hof::lazy(operators::name())(BOOST_HOF_FORWARD(T)(x), detail::simple_placeholder()) ); \
template \
constexpr inline auto operator op (const placeholder&, const placeholder&) BOOST_HOF_RETURNS \
( boost::hof::lazy(operators::name())(detail::simple_placeholder(), detail::simple_placeholder()) );
#else
#define BOOST_HOF_PLACEHOLDER_BINARY_OP(op, name) \
template \
struct result_ ## name \
{ typedef decltype(boost::hof::lazy(operators::name())(std::declval(), std::declval())) type; }; \
template \
constexpr inline typename result_ ## name, T>::type operator op (const placeholder&, T&& x) \
{ return boost::hof::lazy(operators::name())(detail::simple_placeholder(), BOOST_HOF_FORWARD(T)(x)); } \
template \
constexpr inline typename result_ ## name>::type operator op (T&& x, const placeholder&) \
{ return boost::hof::lazy(operators::name())(BOOST_HOF_FORWARD(T)(x), detail::simple_placeholder()); } \
template \
constexpr inline typename result_ ## name, detail::simple_placeholder>::type operator op (const placeholder&, const placeholder&) \
{ return boost::hof::lazy(operators::name())(detail::simple_placeholder(), detail::simple_placeholder()); }
#endif
BOOST_HOF_FOREACH_BINARY_OP(BOOST_HOF_PLACEHOLDER_BINARY_OP)
namespace placeholders {
BOOST_HOF_DECLARE_STATIC_VAR(_1, placeholder<1>);
BOOST_HOF_DECLARE_STATIC_VAR(_2, placeholder<2>);
BOOST_HOF_DECLARE_STATIC_VAR(_3, placeholder<3>);
BOOST_HOF_DECLARE_STATIC_VAR(_4, placeholder<4>);
BOOST_HOF_DECLARE_STATIC_VAR(_5, placeholder<5>);
BOOST_HOF_DECLARE_STATIC_VAR(_6, placeholder<6>);
BOOST_HOF_DECLARE_STATIC_VAR(_7, placeholder<7>);
BOOST_HOF_DECLARE_STATIC_VAR(_8, placeholder<8>);
BOOST_HOF_DECLARE_STATIC_VAR(_9, placeholder<9>);
}
using placeholders::_1;
using placeholders::_2;
using placeholders::_3;
using placeholders::_4;
using placeholders::_5;
using placeholders::_6;
using placeholders::_7;
using placeholders::_8;
using placeholders::_9;
namespace detail {
struct unamed_placeholder
{
template
struct partial_ap
{
T val;
BOOST_HOF_INHERIT_DEFAULT_EMPTY(partial_ap, T)
template
constexpr partial_ap(X&& x, Xs&&... xs) : val(BOOST_HOF_FORWARD(X)(x), BOOST_HOF_FORWARD(Xs)(xs)...)
{}
BOOST_HOF_RETURNS_CLASS(partial_ap);
struct partial_ap_failure
{
template
struct apply
{
template
struct of;
template
struct of
: Failure::template of::type, X>
{};
};
};
struct failure
: failure_map
{};
template
constexpr BOOST_HOF_SFINAE_RESULT(const Invoker&, id_, id_)
operator()(X&& x) const BOOST_HOF_SFINAE_RETURNS
(
Invoker()(BOOST_HOF_CONST_THIS->val, BOOST_HOF_FORWARD(X)(x))
);
};
template
static constexpr partial_ap make_partial_ap(T&& x)
{
return {BOOST_HOF_FORWARD(T)(x)};
}
template
struct left
{
struct failure
: failure_for
{};
template
constexpr BOOST_HOF_SFINAE_RESULT(const Op&, id_, id_)
operator()(T&& val, X&& x) const BOOST_HOF_SFINAE_RETURNS
(Op()(BOOST_HOF_FORWARD(T)(val), BOOST_HOF_FORWARD(X)(x)));
};
template
struct right
{
struct right_failure
{
template
struct apply
{
template
struct of
: Failure::template of
{};
};
};
struct failure
: failure_map
{};
template
constexpr BOOST_HOF_SFINAE_RESULT(const Op&, id_, id_)
operator()(T&& val, X&& x) const BOOST_HOF_SFINAE_RETURNS
(Op()(BOOST_HOF_FORWARD(X)(x), BOOST_HOF_FORWARD(T)(val)));
};
#define BOOST_HOF_UNAMED_PLACEHOLDER_UNARY_OP(op, name) \
constexpr auto operator op () const BOOST_HOF_RETURNS \
( operators::name() );
BOOST_HOF_FOREACH_UNARY_OP(BOOST_HOF_UNAMED_PLACEHOLDER_UNARY_OP)
#define BOOST_HOF_UNAMED_PLACEHOLDER_ASSIGN_OP(op, name) \
template \
constexpr auto operator op (const T& x) const BOOST_HOF_RETURNS \
( partial_ap>(x) );
BOOST_HOF_FOREACH_ASSIGN_OP(BOOST_HOF_UNAMED_PLACEHOLDER_ASSIGN_OP)
};
#define BOOST_HOF_UNAMED_PLACEHOLDER_BINARY_OP(op, name) \
template \
constexpr inline auto operator op (const unamed_placeholder&, const T& x) BOOST_HOF_RETURNS \
( unamed_placeholder::make_partial_ap>(boost::hof::decay(x)) ); \
template \
constexpr inline auto operator op (const T& x, const unamed_placeholder&) BOOST_HOF_RETURNS \
( unamed_placeholder::make_partial_ap>(boost::hof::decay(x)) ); \
constexpr inline auto operator op (const unamed_placeholder&, const unamed_placeholder&) BOOST_HOF_RETURNS \
( operators::name() );
BOOST_HOF_FOREACH_BINARY_OP(BOOST_HOF_UNAMED_PLACEHOLDER_BINARY_OP)
}
namespace placeholders {
BOOST_HOF_DECLARE_STATIC_VAR(_, detail::unamed_placeholder);
}
using placeholders::_;
}} // namespace boost::hof
namespace std {
template
struct is_placeholder>
: std::integral_constant
{};
}
namespace boost {
template
struct is_placeholder;
template
struct is_placeholder>
: std::integral_constant
{};
}
#endif