12#ifndef GMP_META_NAMED_OPERATOR_HPP_
13#define GMP_META_NAMED_OPERATOR_HPP_
37template<
typename...
Ts>
39 std::tuple<
Ts...> values;
41 template<
typename...
Us>
42 requires std::constructible_from<std::tuple<
Ts...>,
Us&&...>
43 constexpr explicit value_holder(
Us&&...
us)
57using named_operator_lhs_storage_t = std::conditional_t<
58 std::is_lvalue_reference_v<T>, T, std::remove_cvref_t<T>>;
73template<
typename Lhs,
typename Func>
79 std::forward<Lhs>(
lhs),
80 std::get<0>(std::move(
holder.values))
99template<
typename Lhs,
typename Func,
typename Rhs>
100 requires std::invocable<Func&&, Lhs, Rhs&&>
103 return std::invoke(std::move(
func), std::forward<Lhs>(
lhs), std::forward<Rhs>(
rhs));
106#define GMP_DEFINE_NAMED_OPERATOR_PAIR(pair) \
107 template<typename Lhs, typename Func> \
108 requires std::movable<Func> \
109 constexpr auto operator GMP_GET_TUPLE(0, pair) (Lhs&& lhs, ::gmp::detail::value_holder<Func> holder) { \
110 return ::gmp::detail::bind_named_operator(std::forward<Lhs>(lhs), std::move(holder)); \
113 template<typename Lhs, typename Func, typename Rhs> \
114 requires std::invocable<Func&&, Lhs, Rhs&&> \
115 constexpr decltype(auto) operator GMP_GET_TUPLE(1, pair) ( \
116 ::gmp::detail::value_holder<Lhs, Func>&& holder, Rhs&& rhs) { \
117 return ::gmp::detail::invoke_named_operator(std::move(holder), std::forward<Rhs>(rhs)); \
120#define GMP_TO_PAIR(x) (x, x),
121#define GMP_TO_PAIRS(...) GMP_REMOVE_TRAILING_COMMA(GMP_FOR_EACH(GMP_TO_PAIR, __VA_ARGS__))
123#define GMP_GENERATE_NAMED_OPERATOR_PAIRS(...) \
124 GMP_FOR_EACH(GMP_DEFINE_NAMED_OPERATOR_PAIR, __VA_ARGS__)
125#define GMP_GENERATE_NAMED_OPERATOR_IDENTICAL_PAIRS(...) \
126 _GMP_GENERATE_NAMED_OPERATOR_IDENTICAL_PAIRS_MSVC_COMPAT(GMP_TO_PAIRS(__VA_ARGS__))
127#define _GMP_GENERATE_NAMED_OPERATOR_IDENTICAL_PAIRS_MSVC_COMPAT(...) \
128 GMP_FOR_EACH(GMP_DEFINE_NAMED_OPERATOR_PAIR, __VA_ARGS__)
130#ifndef GMP_DISABLE_DEFAULT_NAMED_OPERATORS
135#undef _GMP_GENERATE_NAMED_OPERATOR_IDENTICAL_PAIRS_MSVC_COMPAT
136#undef GMP_GENERATE_NAMED_OPERATOR_IDENTICAL_PAIRS
137#undef GMP_GENERATE_NAMED_OPERATOR_PAIRS
140#undef GMP_DEFINE_NAMED_OPERATOR_PAIR
184template<
typename Func>
187 using func_type = std::remove_cvref_t<Func>;
189 return detail::value_holder<func_type>(std::forward<Func>(
f));
constexpr auto make_named_operator(Func &&f)
Create a token that lets a callable be used as a named infix operator.
#define GMP_GENERATE_NAMED_OPERATOR_IDENTICAL_PAIRS(...)
#define GMP_GENERATE_NAMED_OPERATOR_PAIRS(...)