diff --git a/3171_boost_lambda2/Makefile b/3171_boost_lambda2/Makefile
index 573ba341..dc312ada 100644
--- a/3171_boost_lambda2/Makefile
+++ b/3171_boost_lambda2/Makefile
@@ -1,6 +1,6 @@
p3171r0.html : boost-lambda2.md
-boost-lambda2.md : boost-lambda2.tpl.md
- python render.py > $@
+boost-lambda2.md : boost-lambda2.tpl
+ python render.py $^ > $@
include ../md/mpark-wg21.mk
diff --git a/3171_boost_lambda2/boost-lambda2.tpl.md b/3171_boost_lambda2/boost-lambda2.tpl
similarity index 89%
rename from 3171_boost_lambda2/boost-lambda2.tpl.md
rename to 3171_boost_lambda2/boost-lambda2.tpl
index 9240d5ce..e2fa0e8b 100644
--- a/3171_boost_lambda2/boost-lambda2.tpl.md
+++ b/3171_boost_lambda2/boost-lambda2.tpl
@@ -130,7 +130,14 @@ You can see more examples in the [@Boost.Lambda2] docs.
We propose to solve the issue of missing operator function objects in the standard library, as well as less-than-ergonomic lambda syntax for common predicates, by standardizing Boost.Lambda2. That is not a large proposal. The standard library already provides placeholders, `std::namespace::_1` and friends. The standard library also already provides `std::bind`, which is already implemented in a way that supports composition of bind expressions. All we need to do is add operators.
-We additionally add the missing operator function objects.
+We additionally add the missing operator function objects. Now, most of the missing operator function objects and placeholder operators are easy enough to add, except one: taking the address. `&_1` is a bit squeamish, although this actually seems like justified place to overload this operator. But as far as function objects go, the obvious name for it would be `std::addressof`. But this one already exists as an overloaded function template.
+
+This leaves us with two options:
+
+1. Respecify `std::addressof` as a customziation point object with the same behavior. This would be inconsistent with the other function objects (in all the other cases, we specify a type - `std::compare_three_way` is a type, the proposed `std::subscript` is a type, etc., whereas this would be the only object) and would break attempts to use `addressof` unqualified outside of `namespace std`.
+2. Come up with a new name for the object, such that `std::addressof(x)` and maybe `std::address_of{}(x)` are equivalent.
+
+We propose the former.
## Implementation Experience
@@ -138,6 +145,53 @@ Has been shipping in Boost since 1.77 (August 2021).
## Wording
+Change [memory.syn]{.sref}:
+
+::: bq
+```diff
+namespace std {
+ // ...
+ // [specialized.addressof], addressof
+- templateYou can see more examples in the [Boost.Lambda2] docs.
We propose to solve the issue of missing operator function objects in the standard library, as well as less-than-ergonomic lambda syntax for common predicates, by standardizing Boost.Lambda2. That is not a large proposal. The standard library already provides placeholders, std::namespace::_1
and friends. The standard library also already provides std::bind
, which is already implemented in a way that supports composition of bind expressions. All we need to do is add operators.
We additionally add the missing operator function objects.
+We additionally add the missing operator function objects. Now, most of the missing operator function objects and placeholder operators are easy enough to add, except one: taking the address. &_1
is a bit squeamish, although this actually seems like justified place to overload this operator. But as far as function objects go, the obvious name for it would be std::addressof
. But this one already exists as an overloaded function template.
This leaves us with two options:
+std::addressof
as a customziation point object with the same behavior. This would be inconsistent with the other function objects (in all the other cases, we specify a type - std::compare_three_way
is a type, the proposed std::subscript
is a type, etc., whereas this would be the only object) and would break attempts to use addressof
unqualified outside of namespace std
.std::addressof(x)
and maybe std::address_of{}(x)
are equivalent.We propose the former.
Has been shipping in Boost since 1.77 (August 2021).
Extend 22.10.2 [functional.syn] to add the additional function objects:
+Change 20.2.2 [memory.syn]:
++ ++ // ... + // [specialized.addressof], addressof +- template<class T> +- constexpr T* addressof(T& r) noexcept; // freestanding +- template<class T> +- const T* addressof(const T&&) = delete; // freestanding ++ inline constexpr unspecified addressof; // freestanding + // ... +}namespace std { - - // ... - - // [bitwise.operations], bitwise operations - template<class T = void> struct bit_and; // freestanding - template<class T = void> struct bit_or; // freestanding - template<class T = void> struct bit_xor; // freestanding - template<class T = void> struct bit_not; // freestanding - template<> struct bit_and<void>; // freestanding - template<> struct bit_or<void>; // freestanding - template<> struct bit_xor<void>; // freestanding - template<> struct bit_not<void>; // freestanding - -+ // [additional.operations], additional transparent operations -+ struct subscript; // freestanding -+ struct left_shift; // freestanding -+ struct right_shift; // freestanding -+ struct unary_plus; // freestanding -+ struct dereference; // freestanding -+ struct increment; // freestanding -+ struct decrement; // freestanding -+ struct postfix_increment; // freestanding -+ struct postfix_decrement; // freestanding -+ -+ // [compound.operations], compound assignment operations -+ struct plus_equal; // freestanding -+ struct minus_equal; // freestanding -+ struct multiplies_equal; // freestanding -+ struct divides_equal; // freestanding -+ struct modulus_equal; // freestanding -+ struct bit_and_equal; // freestanding -+ struct bit_or_equal; // freestanding -+ struct bit_xor_equal; // freestanding -+ struct left_shift_equal; // freestanding -+ struct right_shift_equal; // freestanding - - // ... - -}
Change 20.2.11 [specialized.addressof]:
++++ + ++ +1 Returns: The actual address of the object or function referenced by
+r
, even in the presence of an overloadedoperator&
.2 Remarks: An expression
+addressof(E)
is a constant subexpression ([defns.const.subexpr]) ifE
is an lvalue constant subexpression.
Extend 22.10.2 [functional.syn] to add the additional function objects:
+++namespace std { + + // ... + + // [bitwise.operations], bitwise operations + template<class T = void> struct bit_and; // freestanding + template<class T = void> struct bit_or; // freestanding + template<class T = void> struct bit_xor; // freestanding + template<class T = void> struct bit_not; // freestanding + template<> struct bit_and<void>; // freestanding + template<> struct bit_or<void>; // freestanding + template<> struct bit_xor<void>; // freestanding + template<> struct bit_not<void>; // freestanding + ++ // [additional.operations], additional transparent operations ++ struct subscript; // freestanding ++ struct left_shift; // freestanding ++ struct right_shift; // freestanding ++ struct unary_plus; // freestanding ++ struct dereference; // freestanding ++ struct increment; // freestanding ++ struct decrement; // freestanding ++ struct postfix_increment; // freestanding ++ struct postfix_decrement; // freestanding ++ ++ // [compound.operations], compound assignment operations ++ struct plus_equal; // freestanding ++ struct minus_equal; // freestanding ++ struct multiplies_equal; // freestanding ++ struct divides_equal; // freestanding ++ struct modulus_equal; // freestanding ++ struct bit_and_equal; // freestanding ++ struct bit_or_equal; // freestanding ++ struct bit_xor_equal; // freestanding ++ struct left_shift_equal; // freestanding ++ struct right_shift_equal; // freestanding + + // ... + +}
Extend 22.10.2 [functional.syn] to add operators:
-+namespace std { - // ... - namespace placeholders { - // M is the implementation-defined number of placeholders - see below _1; // freestanding - see below _2; // freestanding - . - . - . - see below _M; // freestanding - -+ template<class A, class B> constexpr auto operator+(A&&, B&&); -+ template<class A, class B> constexpr auto operator-(A&&, B&&); -+ template<class A, class B> constexpr auto operator*(A&&, B&&); -+ template<class A, class B> constexpr auto operator/(A&&, B&&); -+ template<class A, class B> constexpr auto operator%(A&&, B&&); -+ template<class A> constexpr auto operator-(A&&); -+ -+ template<class A, class B> constexpr auto operator==(A&&, B&&); -+ template<class A, class B> constexpr auto operator!=(A&&, B&&); -+ template<class A, class B> constexpr auto operator<(A&&, B&&); -+ template<class A, class B> constexpr auto operator>(A&&, B&&); -+ template<class A, class B> constexpr auto operator<=(A&&, B&&); -+ template<class A, class B> constexpr auto operator>=(A&&, B&&); -+ template<class A, class B> constexpr auto operator<=>(A&&, B&&); -+ -+ template<class A, class B> constexpr auto operator&&(A&&, B&&); -+ template<class A, class B> constexpr auto operator||(A&&, B&&); -+ template<class A> constexpr auto operator!(A&&); -+ -+ template<class A, class B> constexpr auto operator&(A&&, B&&); -+ template<class A, class B> constexpr auto operator|(A&&, B&&); -+ template<class A, class B> constexpr auto operator^(A&&, B&&); -+ template<class A> constexpr auto operator~(A&&); -+ -+ template<class A, class B> constexpr auto operator<<(A&&, B&&); -+ template<class A, class B> constexpr auto operator<<(A&, B&&); -+ -+ template<class A, class B> constexpr auto operator>>(A&&, B&&); -+ template<class A, class B> constexpr auto operator>>(A&, B&&); -+ -+ template<class A> constexpr auto operator+(A&&); -+ template<class A> constexpr auto operator*(A&&); -+ template<class A> constexpr auto operator++(A&&); -+ template<class A> constexpr auto operator--(A&&); -+ template<class A> constexpr auto operator++(A&&, int); -+ template<class A> constexpr auto operator--(A&&, int); -+ -+ template<class A, class B> constexpr auto operator+=(A&&, B&&); -+ template<class A, class B> constexpr auto operator-=(A&&, B&&); -+ template<class A, class B> constexpr auto operator*=(A&&, B&&); -+ template<class A, class B> constexpr auto operator/=(A&&, B&&); -+ template<class A, class B> constexpr auto operator%=(A&&, B&&); -+ template<class A, class B> constexpr auto operator&=(A&&, B&&); -+ template<class A, class B> constexpr auto operator|=(A&&, B&&); -+ template<class A, class B> constexpr auto operator^=(A&&, B&&); -+ template<class A, class B> constexpr auto operator<<=(A&&, B&&); -+ template<class A, class B> constexpr auto operator>>=(A&&, B&&); -+ -+ template<class A, class B> constexpr auto operator->*(A&&, B&&); - } - // ... -}
namespace std { + // ... + namespace placeholders { + // M is the implementation-defined number of placeholders + see below _1; // freestanding + see below _2; // freestanding + . + . + . + see below _M; // freestanding + ++ template<class A, class B> constexpr auto operator+(A&&, B&&); ++ template<class A, class B> constexpr auto operator-(A&&, B&&); ++ template<class A, class B> constexpr auto operator*(A&&, B&&); ++ template<class A, class B> constexpr auto operator/(A&&, B&&); ++ template<class A, class B> constexpr auto operator%(A&&, B&&); ++ template<class A> constexpr auto operator-(A&&); ++ ++ template<class A, class B> constexpr auto operator==(A&&, B&&); ++ template<class A, class B> constexpr auto operator!=(A&&, B&&); ++ template<class A, class B> constexpr auto operator<(A&&, B&&); ++ template<class A, class B> constexpr auto operator>(A&&, B&&); ++ template<class A, class B> constexpr auto operator<=(A&&, B&&); ++ template<class A, class B> constexpr auto operator>=(A&&, B&&); ++ template<class A, class B> constexpr auto operator<=>(A&&, B&&); ++ ++ template<class A, class B> constexpr auto operator&&(A&&, B&&); ++ template<class A, class B> constexpr auto operator||(A&&, B&&); ++ template<class A> constexpr auto operator!(A&&); ++ ++ template<class A, class B> constexpr auto operator&(A&&, B&&); ++ template<class A, class B> constexpr auto operator|(A&&, B&&); ++ template<class A, class B> constexpr auto operator^(A&&, B&&); ++ template<class A> constexpr auto operator~(A&&); ++ ++ template<class A, class B> constexpr auto operator<<(A&&, B&&); ++ template<class A, class B> constexpr auto operator<<(A&, B&&); ++ ++ template<class A, class B> constexpr auto operator>>(A&&, B&&); ++ template<class A, class B> constexpr auto operator>>(A&, B&&); ++ ++ template<class A> constexpr auto operator+(A&&); ++ template<class A> constexpr auto operator*(A&&); ++ template<class A> constexpr auto operator++(A&&); ++ template<class A> constexpr auto operator--(A&&); ++ template<class A> constexpr auto operator++(A&&, int); ++ template<class A> constexpr auto operator--(A&&, int); ++ ++ template<class A, class B> constexpr auto operator+=(A&&, B&&); ++ template<class A, class B> constexpr auto operator-=(A&&, B&&); ++ template<class A, class B> constexpr auto operator*=(A&&, B&&); ++ template<class A, class B> constexpr auto operator/=(A&&, B&&); ++ template<class A, class B> constexpr auto operator%=(A&&, B&&); ++ template<class A, class B> constexpr auto operator&=(A&&, B&&); ++ template<class A, class B> constexpr auto operator|=(A&&, B&&); ++ template<class A, class B> constexpr auto operator^=(A&&, B&&); ++ template<class A, class B> constexpr auto operator<<=(A&&, B&&); ++ template<class A, class B> constexpr auto operator>>=(A&&, B&&); ++ ++ template<class A, class B> constexpr auto operator->*(A&&, B&&); + } + // ... +}
Add two new sections after 22.10.11 [bitwise.operations]:
@@ -789,330 +832,334 @@subscript
[additional.operations.subscript]1 Returns: std::forward<T>(t)[std::forward<U>(u)]
.
left_shift
[additional.operations.left_shift]struct left_shift {
- template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) << std::forward<U>(u));
-
- using is_transparent = unspecified;
-};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) << std::forward<U>(u));
1 Returns: std::forward<T>(t) << std::forward<U>(u)
.
right_shift
[additional.operations.right_shift]struct right_shift {
+struct subscript {
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) >> std::forward<U>(u));
+ -> decltype(std::forward<T>(t)[std::forward<U>(u)]);
using is_transparent = unspecified;
};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) >> std::forward<U>(u));
-1 Returns: std::forward<T>(t) >> std::forward<U>(u)
.
-Class unary_plus
[additional.operations.unary_plus]
-struct unary_plus {
- template<class T> constexpr auto operator()(T&& t) const
- -> decltype(+std::forward<T>(t));
+ -> decltype(std::forward<T>(t)[std::forward<U>(u)]);
+1 Returns: std::forward<T>(t)[std::forward<U>(u)]
.
+Class left_shift
[additional.operations.left_shift]
+struct left_shift {
+ template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
+ -> decltype(std::forward<T>(t) << std::forward<U>(u));
using is_transparent = unspecified;
};
-
-1 Returns: +std::forward<T>(t)
.
-Class dereference
[additional.operations.dereference]
-struct dereference {
- template<class T> constexpr auto operator()(T&& t) const
- -> decltype(*std::forward<T>(t));
+template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
+ -> decltype(std::forward<T>(t) << std::forward<U>(u));
+1 Returns: std::forward<T>(t) << std::forward<U>(u)
.
+Class right_shift
[additional.operations.right_shift]
+struct right_shift {
+ template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
+ -> decltype(std::forward<T>(t) >> std::forward<U>(u));
using is_transparent = unspecified;
};
-
-1 Returns: *std::forward<T>(t)
.
-Class increment
[additional.operations.increment]
-struct increment {
+template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
+ -> decltype(std::forward<T>(t) >> std::forward<U>(u));
+1 Returns: std::forward<T>(t) >> std::forward<U>(u)
.
+Class unary_plus
[additional.operations.unary_plus]
+struct unary_plus {
template<class T> constexpr auto operator()(T&& t) const
- -> decltype(++std::forward<T>(t));
+ -> decltype(+std::forward<T>(t));
using is_transparent = unspecified;
};
-1 Returns: ++std::forward<T>(t)
.
-Class decrement
[additional.operations.decrement]
-
+1 Returns: +std::forward<T>(t)
.
+Class dereference
[additional.operations.dereference]
+struct dereference {
template<class T> constexpr auto operator()(T&& t) const
- -> decltype(--std::forward<T>(t));
+ -> decltype(*std::forward<T>(t));
using is_transparent = unspecified;
};
-1 Returns: --std::forward<T>(t)
.
-Class postfix_increment
[additional.operations.postfix_increment]
-
+1 Returns: *std::forward<T>(t)
.
+Class increment
[additional.operations.increment]
+struct increment {
template<class T> constexpr auto operator()(T&& t) const
- -> decltype(std::forward<T>(t)++);
+ -> decltype(++std::forward<T>(t));
using is_transparent = unspecified;
};
-1 Returns: std::forward<T>(t)++
.
-Class postfix_decrement
[additional.operations.postfix_decrement]
-
+1 Returns: ++std::forward<T>(t)
.
+Class decrement
[additional.operations.decrement]
+struct decrement {
template<class T> constexpr auto operator()(T&& t) const
- -> decltype(std::forward<T>(t)--);
+ -> decltype(--std::forward<T>(t));
using is_transparent = unspecified;
};
-1 Returns: std::forward<T>(t)--
.
-Compound assignment operations [compound.operations]
-Class plus_equal
[compound.operations.plus_equal]
-struct plus_equal {
- template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) += std::forward<U>(u));
+ -> decltype(--std::forward<T>(t));
+1 Returns: --std::forward<T>(t)
.
+Class postfix_increment
[additional.operations.postfix_increment]
+struct postfix_increment {
+ template<class T> constexpr auto operator()(T&& t) const
+ -> decltype(std::forward<T>(t)++);
using is_transparent = unspecified;
};
-template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) += std::forward<U>(u));
-1 Returns: std::forward<T>(t) += std::forward<U>(u)
.
-Class minus_equal
[compound.operations.minus_equal]
-struct minus_equal {
- template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) -= std::forward<U>(u));
+
+1 Returns: std::forward<T>(t)++
.
+Class postfix_decrement
[additional.operations.postfix_decrement]
+struct postfix_decrement {
+ template<class T> constexpr auto operator()(T&& t) const
+ -> decltype(std::forward<T>(t)--);
using is_transparent = unspecified;
};
-template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) -= std::forward<U>(u));
-1 Returns: std::forward<T>(t) -= std::forward<U>(u)
.
-Class multiplies_equal
[compound.operations.multiplies_equal]
-struct multiplies_equal {
+
+1 Returns: std::forward<T>(t)--
.
+Compound assignment operations [compound.operations]
+Class plus_equal
[compound.operations.plus_equal]
+struct plus_equal {
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) *= std::forward<U>(u));
+ -> decltype(std::forward<T>(t) += std::forward<U>(u));
using is_transparent = unspecified;
};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) *= std::forward<U>(u));
-1 Returns: std::forward<T>(t) *= std::forward<U>(u)
.
-Class divides_equal
[compound.operations.divides_equal]
-
+1 Returns: std::forward<T>(t) += std::forward<U>(u)
.
+Class minus_equal
[compound.operations.minus_equal]
+struct minus_equal {
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) /= std::forward<U>(u));
+ -> decltype(std::forward<T>(t) -= std::forward<U>(u));
using is_transparent = unspecified;
};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) /= std::forward<U>(u));
-1 Returns: std::forward<T>(t) /= std::forward<U>(u)
.
-Class modulus_equal
[compound.operations.modulus_equal]
-
+1 Returns: std::forward<T>(t) -= std::forward<U>(u)
.
+Class multiplies_equal
[compound.operations.multiplies_equal]
+struct multiplies_equal {
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) %= std::forward<U>(u));
+ -> decltype(std::forward<T>(t) *= std::forward<U>(u));
using is_transparent = unspecified;
};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) %= std::forward<U>(u));
-1 Returns: std::forward<T>(t) %= std::forward<U>(u)
.
-Class bit_and_equal
[compound.operations.bit_and_equal]
-
+1 Returns: std::forward<T>(t) *= std::forward<U>(u)
.
+Class divides_equal
[compound.operations.divides_equal]
+struct divides_equal {
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) &= std::forward<U>(u));
+ -> decltype(std::forward<T>(t) /= std::forward<U>(u));
using is_transparent = unspecified;
};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) &= std::forward<U>(u));
-1 Returns: std::forward<T>(t) &= std::forward<U>(u)
.
-Class bit_or_equal
[compound.operations.bit_or_equal]
-
+1 Returns: std::forward<T>(t) /= std::forward<U>(u)
.
+Class modulus_equal
[compound.operations.modulus_equal]
+struct modulus_equal {
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) |= std::forward<U>(u));
+ -> decltype(std::forward<T>(t) %= std::forward<U>(u));
using is_transparent = unspecified;
};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) |= std::forward<U>(u));
-1 Returns: std::forward<T>(t) |= std::forward<U>(u)
.
-Class bit_xor_equal
[compound.operations.bit_xor_equal]
-
+1 Returns: std::forward<T>(t) %= std::forward<U>(u)
.
+Class bit_and_equal
[compound.operations.bit_and_equal]
+struct bit_and_equal {
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) ^= std::forward<U>(u));
+ -> decltype(std::forward<T>(t) &= std::forward<U>(u));
using is_transparent = unspecified;
};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) ^= std::forward<U>(u));
-1 Returns: std::forward<T>(t) ^= std::forward<U>(u)
.
-Class left_shift_equal
[compound.operations.left_shift_equal]
-
+1 Returns: std::forward<T>(t) &= std::forward<U>(u)
.
+Class bit_or_equal
[compound.operations.bit_or_equal]
+struct bit_or_equal {
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) <<= std::forward<U>(u));
+ -> decltype(std::forward<T>(t) |= std::forward<U>(u));
using is_transparent = unspecified;
};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) <<= std::forward<U>(u));
-1 Returns: std::forward<T>(t) <<= std::forward<U>(u)
.
-Class right_shift_equal
[compound.operations.right_shift_equal]
-
+1 Returns: std::forward<T>(t) |= std::forward<U>(u)
.
+Class bit_xor_equal
[compound.operations.bit_xor_equal]
+struct bit_xor_equal {
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) >>= std::forward<U>(u));
+ -> decltype(std::forward<T>(t) ^= std::forward<U>(u));
using is_transparent = unspecified;
};
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
- -> decltype(std::forward<T>(t) >>= std::forward<U>(u));
-1 Returns: std::forward<T>(t) >>= std::forward<U>(u)
.
+ -> decltype(std::forward<T>(t) ^= std::forward<U>(u));
+1 Returns: std::forward<T>(t) ^= std::forward<U>(u)
.
+Class left_shift_equal
[compound.operations.left_shift_equal]
+struct left_shift_equal {
+ template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
+ -> decltype(std::forward<T>(t) <<= std::forward<U>(u));
+
+ using is_transparent = unspecified;
+};
+template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
+ -> decltype(std::forward<T>(t) <<= std::forward<U>(u));
+1 Returns: std::forward<T>(t) <<= std::forward<U>(u)
.
+Class right_shift_equal
[compound.operations.right_shift_equal]
+struct right_shift_equal {
+ template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
+ -> decltype(std::forward<T>(t) >>= std::forward<U>(u));
+
+ using is_transparent = unspecified;
+};
+template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
+ -> decltype(std::forward<T>(t) >>= std::forward<U>(u));
+1 Returns: std::forward<T>(t) >>= std::forward<U>(u)
.
Extend 22.10.15.5 [func.bind.place]:
-namespace std::placeholders {
- // M is the number of placeholders
-+ template <int J>
-+ struct placeholder { // exposition only
-+ template <class... Args>
-+ constexpr decltype(auto) operator()(Args&&... ) const noexcept;
-+ template <class T>
-+ constexpr auto operator[](T&& ) const;
-+ };
-
- see below _1;
- see below _2;
- .
- .
- .
- see below _M;
-}
+namespace std::placeholders {
+ // M is the number of placeholders
++ template <int J>
++ struct placeholder { // exposition only
++ template <class... Args>
++ constexpr decltype(auto) operator()(Args&&... ) const noexcept;
++ template <class T>
++ constexpr auto operator[](T&& ) const;
++ constexpr auto operator&() const;
++ };
+
+ see below _1;
+ see below _2;
+ .
+ .
+ .
+ see below _M;
+}
-1 The number M
of placeholders is implementation-defined.
-2 All placeholder types meet the Cpp17DefaultConstructible and Cpp17CopyConstructible requirements, and their default constructors and copy/move constructors are constexpr functions that do not throw exceptions. It is implementation-defined whether placeholder types meet the Cpp17CopyAssignable requirements, but if so, their copy assignment operators are constexpr functions that do not throw exceptions.
-3 Placeholders should be defined as:
+1 The number M
of placeholders is implementation-defined.
+2 All placeholder types meet the Cpp17DefaultConstructible and Cpp17CopyConstructible requirements, and their default constructors and copy/move constructors are constexpr functions that do not throw exceptions. It is implementation-defined whether placeholder types meet the Cpp17CopyAssignable requirements, but if so, their copy assignment operators are constexpr functions that do not throw exceptions.
+3 Placeholders should be defined as:
-
+
If they are not, they are declared as:
-
+
-4 Placeholders are freestanding items ([freestanding.item]).
+4 Placeholders are freestanding items ([freestanding.item]).
-template <int J>
-template <class... Args>
-decltype(auto) placeholder<J>::operator()(Args&&... args) const noexcept;
-5 Constraints: sizeof...(Args) >= J
is true
.
-6 Returns: std::forward<Args>(args)...[J - 1]
.
-
-7 Returns: bind(subscript(), *this, std::forward<T>(t))
.
-8 Each operator function declared in this clause is constrained on at least one of the parameters having a type T
which satisfies is_placeholder_v<remove_cvref_t<T>> || is_bind_expression_v<remove_cvref_t<T>>
is true
.
-
-9 Returns: bind(plus<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-10 Returns: bind(minus<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-11 Returns: bind(multiplies<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-12 Returns: bind(divides<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-13 Returns: bind(modulus<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-14 Returns: bind(negate<>(), std::forward<A>(a))
.
-
-15 Returns: bind(equal_to<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-16 Returns: bind(not_equal_to<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-17 Returns: bind(less<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-18 Returns: bind(greater<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-19 Returns: bind(less_equal<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-20 Returns: bind(greater_equal<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-21 Returns: bind(compare_three_way(), std::forward<A>(a), std::forward<B>(b))
.
-
-22 Returns: bind(logical_and<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-23 Returns: bind(logical_or<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-24 Returns: bind(logical_not<>(), std::forward<A>(a))
.
-
-25 Returns: bind(bit_and<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-26 Returns: bind(bit_or<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-27 Returns: bind(bit_xor<>(), std::forward<A>(a), std::forward<B>(b))
.
-
-28 Returns: bind(bit_not<>(), std::forward<A>(a))
.
-
-29 Constraints: is_base_of_v<ios_base, remove_cvref_t<A>>
is false
.
-30 Returns: bind(left_shift(), std::forward<A>(a), std::forward<B>(b))
.
-
-31 Constraints: is_base_of_v<ios_base, remove_cvref_t<A>>
is true
.
-32 Returns: bind(left_shift(), ref(a), std::forward<B>(b))
.
-33 Remarks: This overload allows expressions like std::cout << _1 << '\n'
to work.
-
-34 Constraints: is_base_of_v<ios_base, remove_cvref_t<A>>
is false
.
-35 Returns: bind(right_shift(), std::forward<A>(a), std::forward<B>(b))
.
-
-36 Constraints: is_base_of_v<ios_base, remove_cvref_t<A>>
is true
.
-37 Returns: bind(right_shift(), ref(a), std::forward<B>(b))
.
-
-38 Returns: bind(unary_plus(), std::forward<A>(a))
.
-
-39 Returns: bind(dereference(), std::forward<A>(a))
.
-
-40 Returns: bind(increment(), std::forward<A>(a))
.
-
-41 Returns: bind(decrement(), std::forward<A>(a))
.
-
-42 Returns: bind(postfix_increment(), std::forward<A>(a))
.
-
-43 Returns: bind(postfix_decrement(), std::forward<A>(a))
.
-
-44 Returns: bind(plus_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-45 Returns: bind(minus_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-46 Returns: bind(multiplies_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-47 Returns: bind(divides_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-48 Returns: bind(modulus_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-49 Returns: bind(bit_and_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-50 Returns: bind(bit_or_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-51 Returns: bind(bit_xor_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-52 Returns: bind(left_shift_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-53 Returns: bind(right_shift_equal(), std::forward<A>(a), std::forward<B>(b))
.
-
-54 Returns: bind(std::forward<B>(b), std::forward<A>(a))
.
+template <int J>
+template <class... Args>
+decltype(auto) placeholder<J>::operator()(Args&&... args) const noexcept;
+5 Constraints: sizeof...(Args) >= J
is true
.
+6 Returns: std::forward<Args>(args)...[J - 1]
.
+
+7 Returns: bind(subscript(), *this, std::forward<T>(t))
.
+
+8 Returns: bind(addressof, *this)
.
+9 Each operator function declared in this clause is constrained on at least one of the parameters having a type T
which satisfies is_placeholder_v<remove_cvref_t<T>> || is_bind_expression_v<remove_cvref_t<T>>
is true
.
+
+10 Returns: bind(plus<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+11 Returns: bind(minus<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+12 Returns: bind(multiplies<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+13 Returns: bind(divides<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+14 Returns: bind(modulus<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+15 Returns: bind(negate<>(), std::forward<A>(a))
.
+
+16 Returns: bind(equal_to<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+17 Returns: bind(not_equal_to<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+18 Returns: bind(less<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+19 Returns: bind(greater<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+20 Returns: bind(less_equal<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+21 Returns: bind(greater_equal<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+22 Returns: bind(compare_three_way(), std::forward<A>(a), std::forward<B>(b))
.
+
+23 Returns: bind(logical_and<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+24 Returns: bind(logical_or<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+25 Returns: bind(logical_not<>(), std::forward<A>(a))
.
+
+26 Returns: bind(bit_and<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+27 Returns: bind(bit_or<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+28 Returns: bind(bit_xor<>(), std::forward<A>(a), std::forward<B>(b))
.
+
+29 Returns: bind(bit_not<>(), std::forward<A>(a))
.
+
+30 Constraints: is_base_of_v<ios_base, remove_cvref_t<A>>
is false
.
+31 Returns: bind(left_shift(), std::forward<A>(a), std::forward<B>(b))
.
+
+32 Constraints: is_base_of_v<ios_base, remove_cvref_t<A>>
is true
.
+33 Returns: bind(left_shift(), ref(a), std::forward<B>(b))
.
+34 Remarks: This overload allows expressions like std::cout << _1 << '\n'
to work.
+
+35 Constraints: is_base_of_v<ios_base, remove_cvref_t<A>>
is false
.
+36 Returns: bind(right_shift(), std::forward<A>(a), std::forward<B>(b))
.
+
+37 Constraints: is_base_of_v<ios_base, remove_cvref_t<A>>
is true
.
+38 Returns: bind(right_shift(), ref(a), std::forward<B>(b))
.
+
+39 Returns: bind(unary_plus(), std::forward<A>(a))
.
+
+40 Returns: bind(dereference(), std::forward<A>(a))
.
+
+41 Returns: bind(increment(), std::forward<A>(a))
.
+
+42 Returns: bind(decrement(), std::forward<A>(a))
.
+
+43 Returns: bind(postfix_increment(), std::forward<A>(a))
.
+
+44 Returns: bind(postfix_decrement(), std::forward<A>(a))
.
+
+45 Returns: bind(plus_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+46 Returns: bind(minus_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+47 Returns: bind(multiplies_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+48 Returns: bind(divides_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+49 Returns: bind(modulus_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+50 Returns: bind(bit_and_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+51 Returns: bind(bit_or_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+52 Returns: bind(bit_xor_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+53 Returns: bind(left_shift_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+54 Returns: bind(right_shift_equal(), std::forward<A>(a), std::forward<B>(b))
.
+
+55 Returns: bind(std::forward<B>(b), std::forward<A>(a))
.
3 References
diff --git a/3171_boost_lambda2/render.py b/3171_boost_lambda2/render.py
index c907a314..632b632f 100644
--- a/3171_boost_lambda2/render.py
+++ b/3171_boost_lambda2/render.py
@@ -1,3 +1,4 @@
import jinja2
+import sys
-print(jinja2.Template(open("boost-lambda2.tpl.md").read()).render())
+print(jinja2.Template(open(sys.argv[1]).read()).render())