<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<style type="text/css">
pre {margin-left:20pt; }
pre > i {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > i {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
pre > em {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > em {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
body { color: #000000; background-color: #FFFFFF; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5empadding-right: 0.5em; ; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table.header { border: 0px; border-spacing: 0;
  margin-left: 0px; font-style: normal; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;
  padding-left: 0.4em; border: none; 
  padding-right: 0.4em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.4em; border: none;
  padding-right: 0.4em; border: none; }
</style>

<title>Simplified partial function application</title>
</head>

<body>

<table class="header"><tbody>
  <tr>
    <th>Document number:&nbsp;&nbsp;</th><th> </th><td>P0356R5</td>
  </tr>
  <tr>
    <th>Date:&nbsp;&nbsp;</th><th> </th><td>2018-11-09</td>
  </tr>
  <tr>
    <th>Audience:&nbsp;&nbsp;</th><th> </th><td>Library Working Group</td>
  </tr>
  <tr>
    <th>Reply-to:&nbsp;&nbsp;</th><th> </th><td><address>Tomasz Kamiński &lt;tomaszkam at gmail dot com&gt;</address></td>
  </tr>
</tbody></table>

<h1><a name="title">Simplified partial function application</a></h1>

<h2><a name="intro">1. Introduction</a></h2>

<p>This document proposes and introduction of the new library functions for performing partial function
   application and act as replacement for existing <code>std::bind</code>.</p>

<p>This paper addresses <a href="https://issues.isocpp.org/show_bug.cgi?id=40">LEWG Bug 40: variadic bind</a>.</p>

<p>This paper was positively reviewed by LEWG and forwarded to LWG for inclusion into IS during Albuquerque meeting.</p>

<!--h2><a name="toc">Table of contents</a></h2-->

<h2><a name="history">2. Revision history</a></h2>

<h3><a name="history.r0">2.1. Revision 0</a></h3>

<p>This proposal is successor of the <a href="https://wg21.link/n4171">N4171: Parameter group placeholders for bind</a>,
   that was proposing an extension of the existing <code>std::bind</code> to introduce new class of placeholders that would presents group
   of call arguments instead of one.</p>
  
<p>In this paper <code>bind_front</code> is proposed as alternative, that allow user to provide values that will be passed
   as first  arguments to stored callable. The author believes that this solution is in-line with LEWG recommendation for
   the original paper, that suggested to introduce only <code>_all</code> placeholder.</p>

<h3><a name="history.r1">2.2. Revision 1</a></h3>

<ul>
  <li>Removed <code>bind_back</code> function from the scope of the proposal per LEWG guidance. This decision was motivated by lack of
      compelling use cases for this function.</li>
  <li>Described problems caused by silent dropping of output parameters in <a href="#design.placeholders">4.1. No arbitrary argument rearrangements</a>
      section.</li>
  <li>Included proposed wording and feature testing macro.</li>
  <li>Corrected uses of <code>std::result_of</code> in implementation.</li>
</ul>

<h3><a name="history.r2">2.3. Revision 2</a></h3>

<ul>
  <li>Updated wording to <a href="http://wg21.link/n4687">N4687</a> (C++ Working Draft, 2017-07-30).</li>
  <li>Call wrappers now require propagation of the <code>noexcept</code>/<code>constexpr</code> specification.</li>
  <li>Replaced uses of deprecated <code>result_of</code> with <code>invoke_result</code>.</li>
  <li>Reworked wording to reffer to "initialization" instead of "construction" of objects.</li>
  <li>Replaced reference to "objects" to "entities" to cover binding references.</li>
</ul>

<h3><a name="history.r3">2.4. Revision 3</a></h3>

<ul>
  <li>Paper now targets LWG after positive LEWG review.</li>
  <li>Corrected uses of shall in [func.require] paragraph.</li>
  <li>Clarified that call wrappers produced by same specialization are same
      (addressing <a href="https://wg21.link/lwg3023">LWG issue 3023</a>).</li>
  <li>Reverted deprecation wording for <code>bind</code> per LEWG guidance.</li>
</ul>

<h3><a name="history.r4">2.5. Revision 4</a></h3>

<ul>
  <li>Updated wording to <a href="https://wg21.link/n4762">N4762</a> (C++ Working Draft, 2018-07-07).</li>
  <li>Updated reference to <a href="http://wg21.link/p0318r1">P0318: <code>unwrap_ref_decay</code> and <code>unwrap_reference</code></a>.</li>
  <li>Applied wording fixes from Walter E. Brown.</li>
  <li>Removed "shall be a callable object" requirement.</li>
  <li>Removed definition of <em>expression-equivalent</em> (accepted as part of <a href="http://wg21.link/p0898r3">P0898R3: Standard Library Concepts</a>).</li>
  <li>Split "Requires" elements into "Mandates" and "Expects", per <a href="http://wg21.link/p0788r3">P0788R3: Standard Library Specification in a Concepts and Contracts World</a>.</li>
  <li>Changed links to use <a href="https://wg21.link">https://wg21.link</a>.</li>
</ul>

<h3><a name="history.r5">2.6. Revision 5</a></h3>

<ul>
  <li>Applied feedback from LWG review in San Diego.</li>
</ul>


<h2><a name="motivation">3. Motivation and Scope</a></h2>

<p>This paper proposes <code>bind_front</code> function for partial function application for first arguments of the function.
   In other worlds <code>bind_front(f, bound_args...)(call_args...)</code> is equivalent to <code>std::invoke(f, bound_args..., call_args....)</code>.</p>

<p>It is worth to notice that proposed function provides both superset and subset of existing <code>std::bind</code> functionality:
   their support passing variable number of arguments, but does not allow arbitrary reordering or removal of the arguments.
   However author believes that proposed simplified functionality covers most of use cases for original <code>std::bind</code>.</p>

<h3><a name="motivation.arguments-passing">3.1. Passing arguments</a></h3>

<p>Let us consider an example task of writing the functor that will invoke <code>process</code> method on copy of
   <code>strategy</code> object:</p>
<pre>struct Strategy { double process(std:string, std::string, double, double); };
std::unique_ptr&lt;Strategy&gt; createStrategy();</pre>

<p>Firstly, such functor should not cause any additional overhead caused by passing the argument values from the call
   side to the stored callable. To achieve desired effect in case of lambda based solution, we can use forwarding
   reference in combination with variadic number of arguments:</p>
<pre>[s = createStrategy()] (auto&amp;&amp;... args) { return s-&gt;process(std::forward&lt;decltype(args)&gt;(args)...); }</pre>

<p>In case of the functors produced by <code>std::bind</code>, perfect forwarding is used by default for all the call
   arguments that are passed in place of placeholders, so same effect may be achieved using:</p>
<pre>std::bind(&amp;Strategy::process, createStrategy(), _1, _2, _3, _4)</pre>
   
<p>However use of named placeholder requires user to decide on specific number of arguments passed to the function,
   so it  does not support variadic functors and require wrapper code to be adjusted each time when the number of
   arguments accepted by target callable is changed. In addition to that it leads to more subtle and hard to spot
   problems presented in <a href="#design.placeholders">4.1. No arbitrary argument rearrangements</a> section of this paper.</p>
 
<p>In contrast in case of proposed <code>bind_front</code> function, all arguments provided on the call side are
   forwarded to the callable. As consequence the user is not required to manually write boilerplate code for perfect
   forwarding nor are exposed to potential errors caused by use of placeholders:</p>
<pre>bind_front(&amp;Strategy::process, createStrategy())</pre>

<h3><a name="motivation.propagating-constness">3.2. Propagating mutability</a></h3>

<p>In our previous example the strategy object was stored in the callable indirectly by the use of the smart pointer,
   so it mutability was not affected by the functor. However in case of storing object by value we would like to propagate
   constness from the functor. That means for each of the following declarations:</p><p>
</p><pre>auto f = [s = Strategy{}] (auto&amp;&amp;... args) { return s.process(std::forward&lt;decltype(args)&gt;(args)...); }; // 1
auto f = std::bind(&amp;Strategy::process, Strategy{}, _1, _2, _3, _4); // 2
auto f = bind_front(&amp;Strategy::process, Strategy{}); // 3</pre>

<p>Invocation on mutable version of the functor (<code>f</code>) shall invoke <code>process</code> method on mutable object
   (call well-formed), however in case of const qualified one (<code>std::as_const(f)</code>) <code>process</code> method
   shall be invoked on const object (call ill-formed). This functionality is supported both by existing <code>std::bind</code> (2)
   and proposed <code>bind_front</code> (3), however it is not in case of the lambda (1). This is caused by the fact that
   closure created by the lambda has only one overload of the call operator that is const qualified by default.</p>

<p>As consequence, in case of use of lambda based solution, user must decide if he want to pass each object as const 
   and allow only calls on const object, by use of:</p>
<pre>[s = Strategy{}] (auto&amp;&amp;... args) { return s.process(std::forward&lt;decltype(args)&gt;(args)...); };</pre>
<p>Or allow modification of stored objects, but limits calls to non-const functors only:</p>
<pre>[s = Strategy{}] (auto&amp;&amp;... args) mutable { return s.process(std::forward&lt;decltype(args)&gt;(args)...); };</pre>

<p>Same problems may occurs in situation when stored function supports both const and mutable calls via appropriate overloads of 
   <code>operator()</code>. For example in case of following class:</p>
<pre>struct Mapper
{
  auto operator()(int i, int j) -&gt; std::string&amp; { return _mapping[{i, j}]; }
  auto operator()(int i, int j) const -&gt; std::string const&amp; { return _mapping[{i, j}]; }

private:
  std::map&lt;std::pair&lt;int, int&gt;, std::string&gt; _mapping;
};</pre>

<p>Functors produced by <code>std::bind(Mapper{}, 10, _1)</code> and <code>bind_front(Mapper{}, 10)</code> will call
   both const and non-const overloads, depending on their qualification. While in case of lambda, user will need
   to decide to support only one of them, by using one of:</p>
<pre>[m = Mapper{}](int i) -&gt; std::string const&amp; { return m(10, i); }
[m = Mapper{}](int i) mutable -&gt; std::string&amp; { return m(10, i); }</pre>
    

<h3><a name="motivation.preserving-return">3.3. Preserving return type</a></h3>

<p>The reader may notice that lambda functions used in previous section, are explicitly specifying their return type.
   This is caused by the fact that lambda is using the <code>auto</code> deduction for the return type as default.
   As consequence the following slightly changed declaration would return <code>std::string</code> object by value:</p>
<pre>auto fc = [m = Mapper{}](int i) { return m(10, i); };
auto fm = [m = Mapper{}](int i) mutable { return m(10, i); };</pre>

<p>Such slight change of code may lead to various changes in the behaviour of the program. Firstly additional
   copy construction will be invoked, if the object returned by the lambda is captured by reference:</p>
<pre>auto const&amp; s1 = fc(2);
auto const&amp; s2 = fm(2);</pre>
<p>Secondly, the lifetime of object returned from the functor will not longer be tied to the lifetime of the
   <code>Mapper</code> object, which may lead to creation of dangling references:</p>
<pre>auto f = [m = Mapper{}](int i) { return m(i, 10); };
std::string* ps = nullptr;
{
  auto const&amp; s = f(2);
  ps = &amp;s;
}
// *ps is dangling
</pre>
<p>Lastly in case of the mutable version of functor, changing the result of the invocation modifies temporary,
   not the mapped value:</p>
<pre>fm(2) = "something";</pre>

<p>To avoid such problems we may use <code>decltype</code>-based return type deduction, as it is done in case of
   <code>std::bind</code> and proposed <code>bind_front</code>:</p>
<pre>[m = Mapper{}](int i) -&gt; decltype(auto) { return m(i, 10); }</pre>

<h3><a name="motivation.preserving-value-category">3.4. Preserving value category</a></h3>

<p>If we consider following example implementation of the functor that performs memoization of the expensive
   to compute function <code>func</code>:</p>
<pre>struct CachedFunc
{
  std::string const&amp; operator()(int i, int j) &amp;
  {
     key_type key(i, j);

     auto it = _cache.find(key);
     if (it == _cache.end())
       it = _cache.emplace(std::move(key), func(i, j)).first;

     return it-&gt;second;
  } 

private:
  using key_type = std::pair&lt;int, int&gt;;
  std::map&lt;key_type, std::string&gt; _cache;
};</pre>

<p>As we can see <code>CachedFunc::operator()</code> is using reference qualification to limit valid calls only
   to lvalues. Use of this qualification allows us to avoid dangling reference problems, in situation when reference
   returned by temporary <code>CachedFunc</code> object would be used after its destruction. In addition it signals that
   use of <code>CachedFunc</code> makes sense only in situation when it is invoked multiple times and for one-shot invocation
   invoking <code>func</code> directly is more optimal solution.</p>

<p>As in case of the <code>const</code> propagation, we would like to preserve/propagate value category from the functor
   to stored callable. That means that for the following declarations:</p>
<pre>auto f = [cache = CachedFunc{}] (int j) mutable -&gt; std::string&amp; { return cache(10, j); }; // 1
auto f = std::bind(CachedFunc{}, 10, _1); // 2
auto f = bind_front(CachedFunc{}, 10); // 3</pre>
<p>Invocation on the lvalue (<code>f(1)</code>) shall perform call on the lvalue of <code>CachedFunc</code> and be 
   well-formed, while invocation on the rvalue (<code>std::move(f)(1)</code>) shall lead to call on the rvalue and be 
   ill-formed.</p>

<p>Out of discussed options, only proposed <code>bind_front</code> (3) functions are preserving value category. 
   In case of existing <code>std::bind</code> and lambda solutions, the call is always performed on lvalue
   regardless of the category of function object, and essentially bypass reference qualification.</p>

<p>Same problems also occurs in case of the bound arguments, even if the callable does not differentiate between calls
   on lvalues and rvalues. For example if we consider following function declarations</p>
<pre>void foo(std::string&amp;);
auto make_bind(std::string s)       { return std::bind(&amp;foo, s); }
auto make_lambda(std::string s)     { return [s] { return foo(s); }; }
auto make_bind_front(std::string s) { return bind_front(&amp;foo, s); }
</pre>
<p>Invocations in the form <code>make_bind("a")()</code> and <code>make_lambda("a")()</code> are well-formed and are 
   invoking function <code>foo</code> with lvalue reference to de-facto temporary string (member of temporary functor).
   In case of proposed functions, value category of the functor also affects stored arguments and corresponding call
   <code>make_bind_front("a")()</code> is ill-formed.</p>

<h3><a name="motivation.one_shot">3.5. Supporting one-shot invocation</a></h3>

<p>Lack of propagation of the value category in existing partial function application solutions, prevents
   them from supporting functors that allows one-shot invocation via rvalue qualified call operator.
   As consequence for the following declarations:</p>
<pre>struct CallableOnce
{
  void operator()(int) &amp;&amp;;
};

auto make_bind(int i)       { return std::bind(CallableOnce{}, i); }
auto make_lambda(int i)     { return [f = CallableOnce{}, i] { return f(i); }; }
auto make_bind_front(int i) { return bind_front(CallableOnce{}, i); }
</pre>

<p>Only the invocation <code>make_bind_front(1)()</code> is well formed, as the other two (<code>make_bind(1)()</code> 
   and <code>make_lambda(1)()</code>) leads to unsupported call on the lvalue of <code>CallableOnce</code>.</p>

<p>Using a lambda expression it would be possible to work around the problem by explicit use of the 
   <code>std::move</code>:</p>
<pre>[f = CallableOnce{}, i] { return std::move(f)(i); }</pre>
<p>However above code is forcing calls on rvalue of <code>CallableOnce</code>, even if lvalue functor is invoked.
   As consequence multiple calls may be performed on single instance of <code>CallableOnce</code> class.</p>

<p>It is also worth to notice, that one-shot callable functors may also be produced as a result on 
   binding an move-only type. For example in situation when we want to bind arguments to a function <code>consume</code> 
   that accepts <code>std::unique_ptr&lt;Obj&gt;</code> by value:</p>
<pre>struct ConsumeBinder
{
  ConsumeBinder(std::unique_ptr&lt;Obj&gt; p)
    : ptr(std::move(p)) 
  {}

  void operator()() &amp;&amp;
  { return consume(std::move(ptr)); }
  
private:
  std::unique_ptr&lt;Obj&gt; ptr;
};</pre>

<p>In addition support for one-shot invocation is leading to improved performance.
   For example let's consider situation, when we want to bind a vector <code>v</code> as the first argument to the following function:</p>
<pre>void bar(std::vector&lt;int&gt;, int)</pre>
<p>Depending on the scenario, at the point of the call of the bind-wrapper (<code>bw</code>) that we will create, we may want to:</p>
<ul>
  <li>move stored vector to <code>bar</code> function, if <code>bw</code> will be called only once (one-shot)</li>
  <li>copy stored vector to <code>bar</code> function, if <code>bw</code> will be called multiple times</li>
</ul>
<p>Proposed <code>bind_front</code> function support both scenarios, via  rvalue and lvalue overloads of call operator.
   Consequently if <code>bw</code> is created using <code>bind_front(&amp;bar, v)</code>:</p>
<ul>
  <li><code>std::move(bw)(10)</code> will move stored vector (pass as rvalue reference)</li>
  <li><code>bw(10)</code> will copy stored vector (pass as lvalue reference)</li>
</ul>

<h3><a name="motivation.noexcept">3.6. Preserving exception specification</a></h3>

<p>In contrast to existing callable wrappers, proposed <code>bind_front</code> function is required to preserve 
   exception specification of the underlining call operator. This follows recent additions to the language,
   that make the <a href="http://wg21.link/p0012r1">exception specification part of type system</a> and 
   <a href="http://wg21.link/lwg2807"><code>std::invoke</code> conditionally <code>noexcept</code></a> - 
   combination of this changes allowed <code>noexcept</code> specification to be preserved for invocation of function pointers.</p>

<p>Finally, this guarantee is extended also for <code>not_fn</code> function via <a href="#wording.not_fn">alternative
   wording included in the paper.</a></p>
 
<h3><a name="motivation.constexpr">3.7. No compile time evalutation support</a></h3>

<p>Wording included in the paper, requires that the invocation of the functor created via <code>bind_front</code> and
   <code>not_fn</code> will support compile time evaluation, when underlining expression is compile time constant.
   However this requirement is latent, as the underlining <code>std::invoke</code> function is not <code>constexpr</code>
   qualified.</p>

<p>Secondly, the author believes that introduction of the <code>constexpr</code> support for the <code>std::invoke</code>
   is outside of the scope of this paper, as under current direction of <a href="http://wg21.link/cwg1581">CWG issue 1581</a>
   such change would be breaking (<a href="https://bugs.llvm.org/show_bug.cgi?id=23135">example clang bug report</a>).</p>

<h2><a name="design">4. Design Decisions</a></h2>

<p>The section provides rationale for avoiding usage existing <code>std::bind</code> even in the situation
   when proposed new functions does not strictly supersede its functionality.</p>

<h3><a name="design.placeholders">4.1. No arbitrary argument rearrangements</a></h3>

<p>In contrast to the <code>std::bind</code> proposed <code>bind_front</code> does not support rearrangements or
   dropping of the call arguments, that was supported by <code>std::bind</code>.</p>

<p>Firstly, handling of the placeholder was requiring a large amount of the meta-programming, to only determine types
   and values of the argument that will be actually passed to stored callable. However in this case required complexity
   of implementation is not only affecting the vendors, but also leads to unreadable error message produced to the
   user.</p>

<p>Secondly, it allow wrapper created from <code>std::bind</code> to silently drop arguments that are not
   referenced by the placeholders. This functionality may seem to be unharmful, but in case of output parameters
   it prevents certain range of bugs from being detected as compile time. For example following code will silently
   ignore potential error passed to the <code>callback</code> and will cause program to loop infinitely if such
   error is reported:</p> 
<pre>struct InputStream
{
  void read_async(std::size_t count, std::vector&lt;char&gt;&amp; out, 
                  std::function&lt;void(std::error_code)&gt; callback);
};

class DataReader
{
   /* rest of interface */

   void read_remaining()
   { 
      stream.read_async(expected - content.size(), content,
                        std::bind(&amp;DataReader::part_done, this));
   };

   void part_done() 
   {
     if (content.size() &lt; expected)
       read_remaining();
   }

   InputStream stream;
   std::size_t const expected;          
   std::vector&lt;char&gt; content;
};</pre>


<p>Finally, it allows user to write a code that will pass same value to the function multiple times, by repeated use
   of single placeholder, which in case of use of move semantics may lead to passing of unspecified values as arguments.
   For example values of first and second argument are unspecified  in case of following invocation:</p>
<pre>auto f = std::bind(&amp;Strategy::process, createStrategy(), _1, _1, _2, _2);
f(std::string("some_string"), 1);</pre>

<p>Occurrence of such kind of problems depends both of bound arguments passed to the bind and once that are provided on the
   call side. As consequence addressing them, would require introduction of another type of placeholder that would
   pass rvalues as const rvalue reference or additional compile-time logic that will detect duplicated arguments and modify
   their value category. However both solutions would only increase, already large, complexity of implementation and use.</p> 

<h3><a name="design.nested-bind">4.2. No nested <i>bind expressions</i></a></h3>

<p>The proposed function do not give any special meaning to the nested <i>bind expressions</i> (functors produced
   by <code>std::bind</code>) and they are passed directly to the stored callable in case of the invocation.</p>

<p>Firstly, in the author's opinion, use of nested bind leads to unreadable code that are clearly improved by being replaced
   with custom functor, especially in situation when such functor can be created in place using lambda expression.</p>

<p>Secondly, special treatment of nested <i>bind expressions</i> and placeholders hardens the reasoning about behaviour of bind
   expression, by leading to the situations when <code>std::bind(f, a, b, c)()</code> is not invoking <code>f(a, b, c)</code>, 
   despite the user intent. This may occur in situation when type of values passed to <code>std::bind</code> are not known
   by the programmer at point of binding:</p>
<pre>struct apply_twice
{
  template&lt;typename F, typename V&gt;
  auto operator()(F const&amp; f, V const&amp; v) const
    -&gt; decltype(f(f(v)))
  { return f(f(v)); }
};

template&lt;typename F&gt;
auto twicer(F&amp;&amp; f)
{ return std::bind(apply_twice{}, std::forward&lt;F&gt;(f), _1); }

double cust_sqrt(double x) { return std::sqrt(x); }
double cust_pow(double x, double n) { return std::pow(x, n); }
</pre>

<p>Invocation of <code>twicer(&amp;cust_sqrt)(16)</code> is valid and return 2, while <code>twicer(std::bind(&amp;cust_pow, _1, 2))(2))</code>
is invalid.</p>

<h3><a name="design.fixing_bind">4.3. Fixing <code>std::bind</code></a></h3>

<p>Additional motivation for introduction of then new function, is that fixing the problems mentioned above in <code>std::bind</code>
would require introduction of breaking changes to the existing codebase.
 Furthermore such changes would not only take verbose form, when
previously valid code will no longer compile, but may also silently 
change its meaning, by selecting different overload of underlining
functor. The author believes that in such case introduction of new 
functions would be required anyway.</p>

<h2><a name="standard">5. Impact On The Standard</a></h2>

<p>This proposal has no dependencies beyond a C++14 compiler and Standard Library implementation.</p>

<p>Nothing depends on this proposal.</p>


<h2><a name="wording">6. Proposed Wording</a></h2>

<p>The proposed wording changes refer to <a href="https://wg21.link/n4762">N4762</a> (C++ Working Draft, 2018-07-07).</p>

<h3><a name="wording.pfcw">6.1. Definition of <em>perfect forwarding call wrapper</em></a></h3>

<p>This section introduces a <em>perfect forwarding call wrapper</em> concept, that groups a set of common requirements for the call wrapper
   for a stateful callable(s) and collection of bound arguments. This concept is later used to simplify the specification
   of the proposed <code>bind_front</code> and existing <code>not_fn</code> function. In addition it can be extended to cover <code>overload</code>
   function (proposed in <a href="http://wg21.link/p0051r1">P0051: C++ generic <code>overload</code>  function</a>),
   by allowing call wrapper to hold multiple target objects.</p>
  
<p>The definition of the <em>perfect forwarding call wrapper</em> requires the implementation to guarantee that the invocation of the
   wrapper object will be core constant expression and/or <code>noexcept</code> depending on the invoked call expression.
   However, due the fact that both proposed functors are defined in terms of the <code>std::invoke</code> function, this only enforce
   implementation to provide conditional <code>noexcept</code> specification for <code>operator()</code> of the wrapper.</p> 
 
<p>In addition to avoid potential confusion, existing <em>forwarding call wrapper</em> is renamed to <em>argument forwarding call wrapper</em>,
   to better reflect its functionality.</p>

<p>Apply following changes to paragraph [func.def] Definitions:</p>
<blockquote class="std"> 
  <dl class="attribute">
    <dd>A <em>call wrapper type</em> is a type that holds a callable object and supports a call operation that forwards to that object.<p></p></dd>    
    
    <dd>A <em>call wrapper</em> is an object of a call wrapper type.<p></p></dd>

    <dd>A <em>target object</em> is the callable object held by a call wrapper.<p></p></dd>

    <dd><ins>A call wrapper type may additionally hold a sequence of objects, references to functions, and references
             to objects, that may be passed as arguments to the target object.
             These entities are collectively referred to as <em>bound argument entities</em>.</ins><p></p></dd>

    <dd><ins>The target object and bound argument entities of the call wrapper are collectively referred to as <em>state entities</em>.</ins><p></p></dd>
  </dl>
</blockquote>

<p>Apply following changes to paragraph [func.require] Requirement:</p>
<blockquote class="std"> 
  <dl class="attribute">
    <dd>Every call wrapper ([func.def]) <del>shall be</del><ins>is</ins> <em>Cpp17MoveConstructible</em>.

        A<ins>n</ins> <em><ins>argument</ins> forwarding call wrapper</em> is a call wrapper that
        can be called with an arbitrary argument list and delivers the arguments to the wrapped 
	callable object as references. This forwarding step <del>shall ensure that</del><ins>delivers</ins>
	rvalue arguments <del>are delivered</del> as rvalue references and lvalue arguments 
	<del>are delivered </del>as lvalue references.

        A <em>simple call wrapper</em> is a<ins>n argument</ins> forwarding call wrapper that is <em>Cpp17CopyConstructible</em>
        and <em>Cpp17CopyAssignable</em> and whose copy constructor, move constructor, and assignment
        operator do not throw exceptions. 
       
        [ Note: In a typical implementation <ins>argument</ins> forwarding call wrappers
        have an overloaded function call operator of the form
<pre>template&lt;class... UnBoundArgs&gt;
R operator()(UnBoundArgs&amp;&amp;... unbound_args) cv-qual;</pre>
        — end note ].<p></p></dd>

     <dd><ins>A <em>perfect forwarding call wrapper</em> is an argument forwarding call wrapper
         that forwards its state entities to the underlying call expression.
         This forwarding step delivers a state entity of type <code>T</code> as <code><em>cv</em> T&amp;</code>
	 when the call is performed on an lvalue of the call wrapper type and
	 as <code><em>cv</em> T&amp;&amp;</code> otherwise, where <code><em>cv</em></code> represents
         the <em>cv</em>-qualifiers of the call wrapper and where <code><em>cv</em></code> shall be neither
         <code>volatile</code> nor <code>const volatile</code>.</ins><p></p></dd>

     <dd><ins>A <em>call pattern</em> defines the semantics of invoking a perfect forwarding
	  call wrapper.
          A postfix call performed on an perfect forwarding call wrapper is expression-equivalent ([defns.expression-equivalent])
	  to an expression <code>e</code> determined from its call pattern <code>cp</code> by
	  replacing all occurrences of the arguments of the call wrapper and its state entities
          with references as described in the corresponding forwarding steps.</ins><p></p></dd>

    <dd><ins>The copy/move constructor of a perfect forwarding call wrapper has the same apparent
	     semantics as if memberwise copy/move of its state entities were performed ([class.copy.ctor])
         [ Note: This implies that each of the copy/move constructors has the same <em>exception-specification</em> as the
	   corresponding implicit definition and is declared as <code>constexpr</code> if the corresponding implicit definition
           would be considered to be <code>constexpr</code>. - end note. ]
        </ins><p></p></dd>

	<dd><ins>Perfect forwarding call wrappers returned by a given standard library function template have the same type if the 
		 types of their corresponding state entities are the same.<p></p></dd>
  </dl>
</blockquote>

<p>Replace all references to forwarding call wrapper with argument forwarding call wrapper in [func.bind.bind] Function template <code>bind</code>.</p>

<h3><a name="wording.bind_front">6.2. Wording for <code>bind_front</code></a></h3>

<p>After the declaration of <code>not_fn</code> in the section [functional.syn] (Header <code>&lt;functional&gt;</code> synopsis), add:</p>

<blockquote class="stdins"> 

<pre>  // [func.bind_front], <em>binders</em>
  template &lt;class F, class... Args&gt; <em>unspecified</em> bind_front(F&amp;&amp;, Args&amp;&amp;...);
</pre>

</blockquote>

<p>After section [func.not_fn] Function template <code>not_fn</code>, insert a new section.

</p><blockquote class="stdins"> 
<h4><a name="func.bind_front">Function template <code>bind_front</code> <span style="float:right">[func.bind_front]</span></a></h4>

<pre>  template &lt;class F, class... Args&gt;
    <em>unspecified</em> bind_front(F&amp;&amp; f, Args&amp;&amp;... args);
</pre>

  <dl class="attribute">

    <dd>In the text that follows:
    <ul>
      <li><code>g</code> is a value of the result of a <code>bind_front</code> invocation,</li>

      <li><code>FD</code> is the type <code>decay_t&lt;F&gt;</code>,</li>
      <li><code>fd</code> is a target object of <code>g</code> ([func.def])
           of type <code>FD</code>
           initialized with initializer <code>(std::forward&lt;F&gt;(f))</code>,</li>
      <li><code>BoundArgs</code> is a pack of types equivalent to <code><em>DECAY_UNWRAP</em>(Args)...</code>,</li>
      <li><code>bound_args</code> is a pack of bound argument entities of <code>g</code> ([func.def])
           of types <code>BoundArgs...</code> 
           initialized with initializers <code>(std::forward&lt;Args&gt;(args))...</code> respectively,</li>

      <li><code>call_args</code> is an argument pack used in a function call expression of <code>g</code>,</li>
    </ul>
    where <code><em>DECAY_UNWRAP</em>(T)</code> is determined as follows: 
    Let <code>U</code> be <code>decay_t&lt;T&gt;</code>.
    Then <code><em>DECAY_UNWRAP</em>(T)</code> is <code>X&amp;</code> if <code>U</code> equals <code>reference_wrapper&lt;X&gt;</code>,
    otherwise <code><em>DECAY_UNWRAP</em>(T)</code> is <code>U</code>.<p></p></dd>

    <dt>Mandates:</dt> 
    <dd><code>conjunction_v&lt;is_constructible&lt;FD, F&gt;,
                               is_move_constructible&lt;FD&gt;,
                               is_constructible&lt;BoundArgs, Args&gt;...,
                               is_move_constructible&lt;BoundArgs&gt;...&gt;</code>
        shall be <code>true</code>.
    <p></p></dd>


    <dt>Expects:</dt> 
    <dd><code>FD</code> shall meet the requirements of <em>Cpp17MoveConstructible</em>.
        For each <code>Ti</code> in <code>BoundArgs</code>, if <code>Ti</code> is an object type, 
        <code>Ti</code> shall meet the requirements of <em>Cpp17MoveConstructible</em>.
    <p></p></dd>

    <dt>Returns:</dt>
    <dd><p>A perfect forwarding call wrapper <code>g</code> with call pattern <code>invoke(fd, bound_args..., call_args...)</code>.</p></dd>

    <dt>Throws:</dt>
    <dd><p>Any exception thrown by the initialization of the state entities of <code>g</code> ([func.def]).</p></dd>

  </dl>
</blockquote>

<p>Note: This wording can be further simplified by use of <code>unwrap_ref_decay_t</code> from
<a href="http://wg21.link/p0318r1">P0318R1: <code>unwrap_ref_decay</code> and <code>unwrap_reference</code></a> paper.</p>

<h3><a name="wording.not_fn">6.3. Wording for <code>not_fn</code></a></h3>

<p>Change the section [func.not_fn] Function template <code>not_fn</code> to:</p>
<blockquote class="stdins"> 

<pre>  template &lt;class F&gt;
    <em>unspecified</em> not_fn(F&amp;&amp; f);
</pre>

  <dl class="attribute">

    <dd>In the text that follows:
    <ul>
      <li><code>g</code> is a value of the result of a <code>not_fn</code> invocation,</li>

      <li><code>FD</code> is the type <code>decay_t&lt;F&gt;</code>,</li>
      <li><code>fd</code> is a target object of <code>g</code> ([func.def])
           of type <code>FD</code> 
           initialized with initializer <code>(std::forward&lt;F&gt;(f))</code>,</li>
      
      <li><code>call_args</code> is an argument pack used in a function call expression of <code>g</code>.</li>
    </ul><p></p></dd>

    <dt>Mandates:</dt> 
    <dd><code>is_constructible_v&lt;FD, F&gt; &amp;&amp; is_move_constructible_v&lt;FD&gt;</code> shall be <code>true</code>.
    <p></p></dd>

    <dt>Expects:</dt> 
    <dd><code>FD</code> shall meet the requirements of <em>Cpp17MoveConstructible</em>.
    <p></p></dd>

    <dt>Returns:</dt>
    <dd><p>A perfect forwarding call wrapper <code>g</code> with call pattern <code>!invoke(fd, call_args...)</code>.</p></dd>

    <dt>Throws:</dt>
    <dd><p>Any exception thrown by the initialization of <code>fd</code>.</p></dd>

  </dl>
</blockquote>

<h2><a name="feature-testing">7. Feature-testing recommendation</a></h2>

<p>For the purposes of SG10, we recommend the macro name <code>__cpp_lib_bind_front</code> to be defined in the
<code>&lt;functional&gt;</code> header.</p>

<p>Usage example:</p>
<pre>struct Strategy { double process(std:string, std::string, double, double); };

auto bind_to_process(std::unique_ptr&lt;Strategy&gt; ptr)
{
#if __cpp_lib_bind_front
  return std::bind_front(&amp;Strategy::process, std::move(ptr));
#else
  using namespace std::placeholders;
  return std::bind(&amp;Strategy::process, std::move(ptr), _1, _2, _3, _4);
#endif
}</pre>


<h2><a name="implementability">8. Implementability</a></h2>

<p>Example implementation of proposed <code>bind_front</code>:</p>
<pre>template&lt;typename Func, typename BoundArgsTuple, typename... CallArgs&gt;
decltype(auto) bind_front_caller(Func&amp;&amp; func, BoundArgsTuple&amp;&amp; boundArgsTuple, CallArgs&amp;&amp;... callArgs)
{
  return std::apply([&amp;func, &amp;callArgs...](auto&amp;&amp;... boundArgs) -&gt; decltype(auto)
         {
           return std::invoke(std::forward&lt;Func&gt;(func), std::forward&lt;decltype(boundArgs)&gt;(boundArgs)..., std::forward&lt;CallArgs&gt;(callArgs)...);
         }, std::forward&lt;BoundArgsTuple&gt;(boundArgsTuple));
}

template&lt;typename Func, typename... BoundArgs&gt;
class bind_front_t
{
public:
  template&lt;typename F, typename... BA,
           std::enable_if_t&lt;!(sizeof...(BA) == 0 &amp;&amp; std::is_base_of_v&lt;bind_front_t, std::decay_t&lt;F&gt;&gt;), bool&gt; = true&gt;
  explicit bind_front_t(F&amp;&amp; f, BA&amp;&amp;... ba)
    : func(std::forward&lt;F&gt;(f))
    , boundArgs(std::forward&lt;BA&gt;(ba)...)
  {}
    
  template&lt;typename... CallArgs&gt;
  auto operator()(CallArgs&amp;&amp;... callArgs) &amp;
    noexcept(std::is_nothrow_invocable_v&lt;Func&amp;, BoundArgs&amp;..., CallArgs...&gt;)
    -&gt; std::invoke_result_t&lt;Func&amp;, BoundArgs&amp;..., CallArgs...&gt;
  { return bind_front_caller(func, boundArgs, std::forward&lt;CallArgs&gt;(callArgs)...); }

  template&lt;typename... CallArgs&gt;
  auto operator()(CallArgs&amp;&amp;... callArgs) const &amp;
    noexcept(std::is_nothrow_invocable_v&lt;Func const&amp;, BoundArgs const&amp;..., CallArgs...&gt;)
    -&gt; std::invoke_result_t&lt;Func const&amp;, BoundArgs const&amp;..., CallArgs...&gt;
  { return bind_front_caller(func, boundArgs, std::forward&lt;CallArgs&gt;(callArgs)...); }

  template&lt;typename... CallArgs&gt;
  auto operator()(CallArgs&amp;&amp;... callArgs) &amp;&amp;
    noexcept(std::is_nothrow_invocable_v&lt;Func, BoundArgs..., CallArgs...&gt;)
    -&gt; std::invoke_result_t&lt;Func, BoundArgs..., CallArgs...&gt;
  { return bind_front_caller(std::move(func), std::move(boundArgs), std::forward&lt;CallArgs&gt;(callArgs)...); }
    
  template&lt;typename... CallArgs&gt;
  auto operator()(CallArgs&amp;&amp;... callArgs) const &amp;&amp;
    noexcept(std::is_nothrow_invocable_v&lt;Func const, BoundArgs const..., CallArgs...&gt;)
    -&gt; std::invoke_result_t&lt;Func const, BoundArgs const..., CallArgs...&gt;
  { return bind_front_caller(std::move(func), std::move(boundArgs), std::forward&lt;CallArgs&gt;(callArgs)...); }    

private:
  Func func;
  std::tuple&lt;BoundArgs...&gt; boundArgs;
};
    
template&lt;typename Func, typename... BoundArgs&gt;
auto bind_front(Func&amp;&amp; func, BoundArgs&amp;&amp;... boundArgs)
{
  return bind_front_t&lt;std::decay_t&lt;Func&gt;, unwrap_ref_decay_t&lt;BoundArgs&gt;...&gt;{std::forward&lt;Func&gt;(func), std::forward&lt;BoundArgs&gt;(boundArgs)...};
}</pre>

<p>To properly handle <code>std::reference_wrapper</code> in above code, we use <code>decay_unwrap</code> auxilary metafunction from 
<a href="http://wg21.link/p0318r1">P0318R1: <code>unwrap_ref_decay</code> and <code>unwrap_reference</code></a> paper.</p>
<pre>template&lt;typename T&gt;
struct unwrap_ref_decay;

template&lt;typename T&gt;
struct unwrap_ref_decay&lt;std::reference_wrapper&lt;T&gt;&gt;
{
  using type = T&amp;;
};

template&lt;typename T&gt;
struct unwrap_ref_decay
  : std::conditional_t&lt;
      !std::is_same&lt;std::decay_t&lt;T&gt;, T&gt;::value,
      unwrap_ref_decay&lt;std::decay_t&lt;T&gt;&gt;,
      std::decay&lt;T&gt;
   &gt;
{};

template&lt;typename T&gt;
using unwrap_ref_decay_t = typename decay_unwrap&lt;T&gt;::type;</pre>

<h2><a name="acknowledgements">9. Acknowledgements</a></h2>

<p>Daniel Krügler offered tremendous amount of improvements for presented wording.</p>

<p>Marshall Clow for very helpful review of the paper wording.</p> 

<p>Jonathan Wakely, Stephan T. Lavavej, Walter E. Brown, and Johel E. G. Peña offered many useful suggestions and corrections to the proposal.</p>

<p>Casey Carter has created and suggested use of expression-equivalent term in definition of <em>perfect forwarding call wrapper</em>.</p>

<p>Proposed runtime version of <code>bind_front</code> and <code>bind_back</code> are inspired by their compile time counterparts from Eric Niebler's 
  <a href="http://ericniebler.com/2014/11/13/tiny-metaprogramming-library/">Tiny Metaprogramming Library</a>.</p>

<p>Special thanks and recognition goes to Sabre (<a href="http://www.sabre.com/">http://www.sabre.com</a>) for supporting the production of this proposal,
   and for sponsoring author's trip to the Oulu for WG21 meeting.</p>

<h2><a name="literature">10. References</a></h2>

<ol>
  <li>Chris Jefferson, Ville Voutilainen, 
      "Bug 40 - variadic bind" 
      (LEWG Bug 40, <a href="https://issues.isocpp.org/show_bug.cgi?id=40">https://issues.isocpp.org/show_bug.cgi?id=40</a>)</li>

  <li>Mikhail Semenov, 
      "Introducing an optional parameter for mem_fn, which allows to bind an object to its member function" 
      (N3702, <a href="http://wg21.link/n3702">http://wg21.link/n3702</a>)</li>

  <li>Tomasz Kamiński, 
      "Parameter group placeholders for bind"
      (N4171, <a href="http://wg21.link/n4171">http://wg21.link/n4171</a>)</li>

  <li>Jens Maurer,
      "P0012R1: Make exception specifications be part of the type system, version 5" 
      (P0012R1, <a href="http://wg21.link/p0012r1">http://wg21.link/p0012r1</a>)</li>

  <li>Marshall Clow,
      "C++ Standard Library Issues Resolved Directly In Kona" 
      (P0625R0, <a href="http://wg21.link/p0625r0">http://wg21.link/p0625r0</a>)</li>

  <li>William M. Miller,
      "C++ Standard Core Language Active Issues, Revision 97" 
      (<a href="http://wg21.link/cwg1581">http://wg21.link/cwg1581</a>)</li>

  <li>Gonzalo BG,
      "[C++11/14] Body of constexpr function templates instantiated too eagerly in unevaluated operands" 
      (Bug 23135, <a href="https://bugs.llvm.org/show_bug.cgi?id=23135">
                           https://bugs.llvm.org/show_bug.cgi?id=23135</a>)</li>

  <li>Vicente J. Botet Escribá, 
      "C++ generic <code>overload</code> function (Revision 1)" 
      (P0051R1, <a href="http://wg21.link/p0051r1">http://wg21.link/p0051r1</a>)</li>

  <li>Vicente J. Botet Escribá, 
      "<code>unwrap_ref_decay</code> and <code>unwrap_reference</code>" 
      (P0318R1, <a href="http://wg21.link/p0318r1">http://wg21.link/p0318r1</a>)</li>

  <li>Richard Smith,
      "Working Draft, Standard for Programming Language C++"
      (N4762, <a href="https://wg21.link/n4762">https://wg21.link/n4762</a>)</li>

  <li>Casey Carter, Eric Niebler,
      "Standard Library Concepts"
      (P0898R3, <a href="http://wg21.link/p0898r3">http://wg21.link/p0898r3</a>)</li>

  <li>Walter E. Brown,
      "Standard Library Specification in a Concepts and Contracts World"
      (P0788R3, <a href="http://wg21.link/p0788r3">http://wg21.link/p0788r3</a>)</li>
</ol>

</body></html>
