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 +- template +- constexpr T* addressof(T& r) noexcept; // freestanding +- template +- const T* addressof(const T&&) = delete; // freestanding ++ inline constexpr $unspecified$ addressof; // freestanding + // ... +} +``` +::: + +Change [specialized.addressof]{.sref}: + +::: bq +::: addu +``` +struct $addressof_t$ { // exposition-only + template + constexpr T* operator()(T& r) const noexcept; + template + constexpr T* operator()(const T&&) const = delete; +}; + +inline constexpr $addressof_t$ addressof{}; +``` + +``` +template + constexpr T* $addressof_t$::operator()(T& r) const noexcept; +``` +::: +::: rm +``` +template constexpr T* addressof(T& r) noexcept; +``` +::: +[1]{.pnum} *Returns*: The actual address of the object or function referenced by `r`, even in the presence of an overloaded `operator&`. + +[#]{.pnum} *Remarks*: An expression `addressof(E)` is a constant subexpression ([defns.const.subexpr]) if `E` is an lvalue constant subexpression. +::: + Extend [functional.syn]{.sref} to add the additional function objects: ::: bq @@ -407,6 +461,7 @@ namespace std::placeholders { + constexpr decltype(auto) operator()(Args&&... ) const noexcept; + template + constexpr auto operator[](T&& ) const; ++ constexpr auto operator&() const; + }; $see below$ _1; @@ -453,6 +508,13 @@ auto $placeholder$::operator[](T&& t) const; [#]{.pnum} *Returns*: `bind(subscript(), *this, std::forward(t))`. +``` +template +auto $placeholder$::operator&() const; +``` + +[#]{.pnum} *Returns*: `bind(addressof, *this)`. + {% macro make_binary_operator(op, func) %} ``` template constexpr auto operator{{ op }}(A&& a, B&& b); diff --git a/3171_boost_lambda2/p3171r0.html b/3171_boost_lambda2/p3171r0.html index fdafa608..53823437 100644 --- a/3171_boost_lambda2/p3171r0.html +++ b/3171_boost_lambda2/p3171r0.html @@ -667,121 +667,164 @@

You can see more examples in the [Boost.Lambda2] docs.

2 Proposal

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. +
  3. Come up with a new name for the object, such that std::addressof(x) and maybe std::address_of{}(x) are equivalent.
  4. +
+

We propose the former.

2.1 Implementation Experience

Has been shipping in Boost since 1.77 (August 2021).

2.2 Wording

-

Extend 22.10.2 [functional.syn] to add the additional function objects:

+

Change 20.2.2 [memory.syn]:

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
-
-  // ...
-
-}
+ // ... + // [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 + // ... +}
+ +
+

Change 20.2.11 [specialized.addressof]:

+
+
+
struct addressof_t { // exposition-only
+  template<class T>
+    constexpr T* operator()(T& r) const noexcept;
+  template<class T>
+    constexpr T* operator()(const T&&) const = delete;
+};
+
+inline constexpr addressof_t addressof{};
+
template<clsas T>
+  constexpr T* addressof_t::operator()(T& r) const noexcept;
+
+
+ +
template<class T> constexpr T* addressof(T& r) noexcept;
+ +
+

1 Returns: The actual address of the object or function referenced by r, even in the presence of an overloaded operator&.

+

2 Remarks: An expression addressof(E) is a constant subexpression ([defns.const.subexpr]) if E 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 @@

2.2

Additional operations [additional.operations]

Class subscript [additional.operations.subscript]

-
struct subscript {
-  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 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).

-

Class 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;
 };
-
template<class T> constexpr auto operator()(T&& t) const
-  -> decltype(+std::forward<T>(t));
-

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;
 };
-
template<class T> constexpr auto operator()(T&& t) const
-  -> decltype(*std::forward<T>(t));
-

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;
 };
template<class T> constexpr auto operator()(T&& t) const
-  -> decltype(++std::forward<T>(t));
-

1 Returns: ++std::forward<T>(t).

-

Class decrement [additional.operations.decrement]

-
struct decrement {
+  -> decltype(+std::forward<T>(t));
+

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;
 };
template<class T> constexpr auto operator()(T&& t) const
-  -> decltype(--std::forward<T>(t));
-

1 Returns: --std::forward<T>(t).

-

Class postfix_increment [additional.operations.postfix_increment]

-
struct postfix_increment {
+  -> decltype(*std::forward<T>(t));
+

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;
 };
template<class T> constexpr auto operator()(T&& t) const
-  -> decltype(std::forward<T>(t)++);
-

1 Returns: std::forward<T>(t)++.

-

Class postfix_decrement [additional.operations.postfix_decrement]

-
struct postfix_decrement {
+  -> decltype(++std::forward<T>(t));
+

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;
 };
template<class T> constexpr auto operator()(T&& t) const
-  -> decltype(std::forward<T>(t)--);
-

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));
+
template<class T> constexpr auto operator()(T&& t) const
+  -> decltype(std::forward<T>(t)++);
+

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 {
+
template<class T> constexpr auto operator()(T&& t) const
+  -> decltype(std::forward<T>(t)--);
+

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]

-
struct divides_equal {
+  -> 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));
+    -> 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]

-
struct modulus_equal {
+  -> 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 {
   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]

-
struct bit_and_equal {
+  -> 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]

+
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]

-
struct bit_or_equal {
+  -> 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]

+
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]

-
struct bit_xor_equal {
+  -> 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]

+
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]

-
struct left_shift_equal {
+  -> 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]

+
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]

-
struct right_shift_equal {
+  -> 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]

+
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:

-
- inline constexpr unspecified _1{};
-+ inline constexpr placeholder<1> _1{};
+
- inline constexpr unspecified _1{};
++ inline constexpr placeholder<1> _1{};

If they are not, they are declared as:

-
- extern unspecified _1;
-+ extern placeholder<1> _1;
+
- extern unspecified _1;
++ extern placeholder<1> _1;
-

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].

-
template <int J>
-template <class T>
-auto placeholder<J>::operator[](T&& t) const;
-

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.

-
template<class A, class B> constexpr auto operator+(A&& a, B&& b);
-

9 Returns: bind(plus<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator-(A&& a, B&& b);
-

10 Returns: bind(minus<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator*(A&& a, B&& b);
-

11 Returns: bind(multiplies<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator/(A&& a, B&& b);
-

12 Returns: bind(divides<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator%(A&& a, B&& b);
-

13 Returns: bind(modulus<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A> constexpr auto operator-(A&& a);
-

14 Returns: bind(negate<>(), std::forward<A>(a)).

-
template<class A, class B> constexpr auto operator==(A&& a, B&& b);
-

15 Returns: bind(equal_to<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator!=(A&& a, B&& b);
-

16 Returns: bind(not_equal_to<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator<(A&& a, B&& b);
-

17 Returns: bind(less<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator>(A&& a, B&& b);
-

18 Returns: bind(greater<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator<=(A&& a, B&& b);
-

19 Returns: bind(less_equal<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator>=(A&& a, B&& b);
-

20 Returns: bind(greater_equal<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator<=>(A&& a, B&& b);
-

21 Returns: bind(compare_three_way(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator&&(A&& a, B&& b);
-

22 Returns: bind(logical_and<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator||(A&& a, B&& b);
-

23 Returns: bind(logical_or<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A> constexpr auto operator!(A&& a);
-

24 Returns: bind(logical_not<>(), std::forward<A>(a)).

-
template<class A, class B> constexpr auto operator&(A&& a, B&& b);
-

25 Returns: bind(bit_and<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator|(A&& a, B&& b);
-

26 Returns: bind(bit_or<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator^(A&& a, B&& b);
-

27 Returns: bind(bit_xor<>(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A> constexpr auto operator~(A&& a);
-

28 Returns: bind(bit_not<>(), std::forward<A>(a)).

-
template<class A, class B> constexpr auto operator<<(A&& a, B&& b);
-

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)).

-
template<class A, class B> constexpr auto operator<<(A& a, 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.

-
template<class A, class B> constexpr auto operator>>(A&& a, B&& b);
-

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)).

-
template<class A, class B> constexpr auto operator>>(A& a, 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)).

-
template<class A> constexpr auto operator+(A&& a);
-

38 Returns: bind(unary_plus(), std::forward<A>(a)).

-
template<class A> constexpr auto operator*(A&& a);
-

39 Returns: bind(dereference(), std::forward<A>(a)).

-
template<class A> constexpr auto operator++(A&& a);
-

40 Returns: bind(increment(), std::forward<A>(a)).

-
template<class A> constexpr auto operator--(A&& a);
-

41 Returns: bind(decrement(), std::forward<A>(a)).

-
template<class A> constexpr auto operator++(A&& a, int);
-

42 Returns: bind(postfix_increment(), std::forward<A>(a)).

-
template<class A> constexpr auto operator--(A&& a, int);
-

43 Returns: bind(postfix_decrement(), std::forward<A>(a)).

-
template<class A, class B> constexpr auto operator+=(A&& a, B&& b);
-

44 Returns: bind(plus_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator-=(A&& a, B&& b);
-

45 Returns: bind(minus_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator*=(A&& a, B&& b);
-

46 Returns: bind(multiplies_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator/=(A&& a, B&& b);
-

47 Returns: bind(divides_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator%=(A&& a, B&& b);
-

48 Returns: bind(modulus_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator&=(A&& a, B&& b);
-

49 Returns: bind(bit_and_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator|=(A&& a, B&& b);
-

50 Returns: bind(bit_or_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator^=(A&& a, B&& b);
-

51 Returns: bind(bit_xor_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator<<=(A&& a, B&& b);
-

52 Returns: bind(left_shift_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator>>=(A&& a, B&& b);
-

53 Returns: bind(right_shift_equal(), std::forward<A>(a), std::forward<B>(b)).

-
template<class A, class B> constexpr auto operator->*(A&& a, 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].

+
template <int J>
+template <class T>
+auto placeholder<J>::operator[](T&& t) const;
+

7 Returns: bind(subscript(), *this, std::forward<T>(t)).

+
template <int J>
+auto placeholder<J>::operator&() const;
+

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.

+
template<class A, class B> constexpr auto operator+(A&& a, B&& b);
+

10 Returns: bind(plus<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator-(A&& a, B&& b);
+

11 Returns: bind(minus<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator*(A&& a, B&& b);
+

12 Returns: bind(multiplies<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator/(A&& a, B&& b);
+

13 Returns: bind(divides<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator%(A&& a, B&& b);
+

14 Returns: bind(modulus<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A> constexpr auto operator-(A&& a);
+

15 Returns: bind(negate<>(), std::forward<A>(a)).

+
template<class A, class B> constexpr auto operator==(A&& a, B&& b);
+

16 Returns: bind(equal_to<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator!=(A&& a, B&& b);
+

17 Returns: bind(not_equal_to<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator<(A&& a, B&& b);
+

18 Returns: bind(less<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator>(A&& a, B&& b);
+

19 Returns: bind(greater<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator<=(A&& a, B&& b);
+

20 Returns: bind(less_equal<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator>=(A&& a, B&& b);
+

21 Returns: bind(greater_equal<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator<=>(A&& a, B&& b);
+

22 Returns: bind(compare_three_way(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator&&(A&& a, B&& b);
+

23 Returns: bind(logical_and<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator||(A&& a, B&& b);
+

24 Returns: bind(logical_or<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A> constexpr auto operator!(A&& a);
+

25 Returns: bind(logical_not<>(), std::forward<A>(a)).

+
template<class A, class B> constexpr auto operator&(A&& a, B&& b);
+

26 Returns: bind(bit_and<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator|(A&& a, B&& b);
+

27 Returns: bind(bit_or<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator^(A&& a, B&& b);
+

28 Returns: bind(bit_xor<>(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A> constexpr auto operator~(A&& a);
+

29 Returns: bind(bit_not<>(), std::forward<A>(a)).

+
template<class A, class B> constexpr auto operator<<(A&& a, B&& b);
+

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)).

+
template<class A, class B> constexpr auto operator<<(A& a, 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.

+
template<class A, class B> constexpr auto operator>>(A&& a, B&& b);
+

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)).

+
template<class A, class B> constexpr auto operator>>(A& a, 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)).

+
template<class A> constexpr auto operator+(A&& a);
+

39 Returns: bind(unary_plus(), std::forward<A>(a)).

+
template<class A> constexpr auto operator*(A&& a);
+

40 Returns: bind(dereference(), std::forward<A>(a)).

+
template<class A> constexpr auto operator++(A&& a);
+

41 Returns: bind(increment(), std::forward<A>(a)).

+
template<class A> constexpr auto operator--(A&& a);
+

42 Returns: bind(decrement(), std::forward<A>(a)).

+
template<class A> constexpr auto operator++(A&& a, int);
+

43 Returns: bind(postfix_increment(), std::forward<A>(a)).

+
template<class A> constexpr auto operator--(A&& a, int);
+

44 Returns: bind(postfix_decrement(), std::forward<A>(a)).

+
template<class A, class B> constexpr auto operator+=(A&& a, B&& b);
+

45 Returns: bind(plus_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator-=(A&& a, B&& b);
+

46 Returns: bind(minus_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator*=(A&& a, B&& b);
+

47 Returns: bind(multiplies_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator/=(A&& a, B&& b);
+

48 Returns: bind(divides_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator%=(A&& a, B&& b);
+

49 Returns: bind(modulus_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator&=(A&& a, B&& b);
+

50 Returns: bind(bit_and_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator|=(A&& a, B&& b);
+

51 Returns: bind(bit_or_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator^=(A&& a, B&& b);
+

52 Returns: bind(bit_xor_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator<<=(A&& a, B&& b);
+

53 Returns: bind(left_shift_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator>>=(A&& a, B&& b);
+

54 Returns: bind(right_shift_equal(), std::forward<A>(a), std::forward<B>(b)).

+
template<class A, class B> constexpr auto operator->*(A&& a, 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())