<HTML><HEAD><TITLE>N1673=04-0113, Unifying TR1 Function Object Type Specifications</TITLE></HEAD><BODY>

<CENTER>
<H1><A NAME="Unifying TR1 Function Object Type Specifications">Unifying TR1 Function Object Type Specifications</A></H1>
</CENTER>

<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT"><B><I>Document number:</I></B></TD>
<TD>&nbsp; N1673=04-0113</TD>
</TR>
<TR>
<TD ALIGN="RIGHT"><B><I>Date:</I></B></TD>
<TD>&nbsp; September 10, 2004</TD>
</TR>
<TR>
<TD ALIGN="RIGHT"><B><I>Project:</I></B></TD>
<TD>&nbsp; Programming Language C++</TD>
</TR>
<TR>
<TD ALIGN="RIGHT"><B><I>Reference:</I></B></TD>
<TD>&nbsp; ISO/IEC IS 14882:2003(E)</TD>
</TR>
<TR>
<TD ALIGN="RIGHT"><B><I>Reply to:</I></B></TD>
<TD>&nbsp; Pete Becker</TD>
</TR>
<TR>
<TD></TD>
<TD>&nbsp; Dinkumware, Ltd.</TD>
</TR>
<TR>
<TD></TD>
<TD>&nbsp; petebecker@acm.org</TD>
</TR>
<TR>
<TD></TD>
<TD>&nbsp; Peter Dimov</TD>
</TR>
<TR>
<TD></TD>
<TD>&nbsp; pdimov@mmltd.net</TD>
</TR>
</TABLE>
<BR CLEAR="ALL">

<HR>

<P><B><CODE><A HREF="#Introduction">Introduction</A>
&#183; <A HREF="#Framework Overview">Framework Overview</A>
&#183; <A HREF="#Summary of Proposed Changes">Summary of Proposed Changes</A>
&#183; <A HREF="#Open Issues">Open Issues</A>
&#183; <A HREF="#Proposed Changes">Proposed Changes</A>
</CODE></B></P>

<HR>

<H2><A NAME="Introduction">Introduction</A></H2>

<P>Technical Report 1 introduces four templates for types whose instances
can act as function objects. These templates were written by various people
at various times and with somewhat different goals. They have much in
common, however, and their specifications can be simplified by providing
a set of shared definitions that support a uniform conceptual framework.
This paper defines such a framework and applies it to the TR1 specifications
for <CODE>reference_wrapper</CODE>, <CODE>function</CODE>,
<CODE>mem_fn</CODE>, and <CODE>bind</CODE>.</P>

<H2><A NAME="Framework Overview">Framework Overview</A></H2>

<P>Roughly speaking, TR1 defines templates for creating function objects that,
when called, forward to other function objects. That formulation is muddled,
however, because the two uses of the term &quot;function objects&quot;
mean two somewhat different things. We introduce several technical terms to
provide a more precise vocabulary:</P>

<UL>
<LI>A <I>callable type</I> is a pointer to function, a pointer to member function,
a pointer to member data<SUP><FONT SIZE=-1><A HREF="#fn1">1</A></FONT></SUP>,
or a class type whose objects can appear immediately to the left of a function
call operator<SUP><FONT SIZE=-1><A HREF="#fn2">2</A></FONT></SUP>.</LI>

<LI>A <I>callable object</I> is an object of a callable type.</LI>

<LI>A <I>call wrapper</I> is an object that holds a callable
object, known as its <I>target object</I>. It provides a call operation
which applies its argument list to the target object in a way that is determined
by the type of the target object.</LI>
</UL>

<P>TR1 provides four different kinds of call wrappers: objects of type
<CODE>reference_wrapper&lt;T&gt;</CODE> where <CODE>T</CODE> is
a callable type; objects of type <CODE>function&lt;F&gt;</CODE>;
objects returned by calls to the template function
<CODE>mem_fn</CODE>; and objects returned by calls to the template
function <CODE>bind</CODE>.</P>

<H2><A NAME="Summary of Proposed Changes">Summary of Proposed Changes</A></H2>

<P>The proposed changes add the framework sketched above to TR1 and rewrite the
specifications of <CODE>reference_wrapper</CODE>, <CODE>function</CODE>,
<CODE>mem_fn</CODE>, and <CODE>bind</CODE> in terms
of that framework. Most of the changes are intended to change only the way that
the specification is expressed. A few changes, however, are changes in the
requirements. These changes are:</P>

<UL>
<LI>The possibility of specifying the return type when bind is applied to
a pointer to member.</LI>
<LI>The appendix &quot;Implementation quantities&quot; is explicitly marked
&quot;(informative)&quot;, which is consistent with the C++ standard.</LI>
<LI>The various limits on the number of arguments have been consolidated. This
supersedes the proposed resolution to issue 10.14.</LI>
</UL>

<H2><A NAME="Open Issues">Open Issues</A></H2>

<P>For easier presentation, some of the proposed changes assume particular
resolutions to open TR issues, as listed below. In this paper we take no position
on how these issues should be resolved.</P>

<UL>
<LI>The presentation of reference_wrapper is written as if reference_wrapper can
be instantiated for pointers to member data (issue 10.22).</LI>
<LI>The existence and definition of <CODE>result_type</CODE> in a call wrapper
that holds a pointer to member data.</LI>
</UL>

<H2><A NAME="Proposed Changes">Proposed Changes</A></H2>

<H3>Overall changes</H3>

<P>Add a new subclause, "Definitions", to the beginning of [tr.func]:</P>

<BLOCKQUOTE>
The following definitions shall apply to this clause:
</BLOCKQUOTE>

<BLOCKQUOTE>
A <B><A NAME="call signature">call signature</A></B> is the name of a
return type followed by a parenthesized comma-separated list of zero or more
argument types.
</BLOCKQUOTE>

<BLOCKQUOTE>
A <B><A NAME="call wrapper">call wrapper</A></B> is an object
of a call wrapper type.
</BLOCKQUOTE>

<BLOCKQUOTE>
A <B><A NAME="call wrapper type">call wrapper type</A></B> is a type that holds
a callable object and supports a call operation that forwards to that object.
</BLOCKQUOTE>

<BLOCKQUOTE>
A <B><A NAME="callable object">callable object</A></B> is an object of a
callable type.
</BLOCKQUOTE>

<BLOCKQUOTE>
A <B><A NAME="callable type">callable type</A></B> is a pointer to function,
a pointer to member function, a pointer to member data, or a class type whose
objects can appear immediately to the left of a function call operator.
</BLOCKQUOTE>

<BLOCKQUOTE>
A <B><A NAME="target object">target object</A></B> is the callable object
held by a call wrapper object.
</BLOCKQUOTE>

<P>Add a new subclause, "Requirements", after [tr.func.syn]:</P>

<BLOCKQUOTE>
Define <I><A NAME="INVOKE">INVOKE</A></I>(f, t1, t2, ..., tN) as follows:

<UL>
<LI><CODE>(t1.*f)(t2, ..., tN)</CODE> when <CODE>f</CODE> is a pointer to a
member function of a class <CODE>T</CODE> and <CODE>t1</CODE> is an object
of type <CODE>T</CODE> or a reference to an object of type <CODE>T</CODE>
or a reference to an object of a type derived from <CODE>T</CODE>;</LI>
<LI><CODE>((*t1).*f)(t2, ..., tN)</CODE> when </CODE>f</CODE> is a pointer to
a member function of a class <CODE>T</CODE> and <CODE>t1</CODE> is not one of
the types described in the previous item;</LI>
<LI><CODE>t1.*f</CODE> when <CODE>f</CODE> is a pointer to
member data of a class <CODE>T</CODE> and <CODE>t1</CODE> is an object
of type <CODE>T</CODE> or a reference to an object of type <CODE>T</CODE>
or a reference to an object of a type derived from <CODE>T</CODE>;</LI>
<LI><CODE>(*t1).*f</CODE> when </CODE>f</CODE> is a pointer to
member data of a class <CODE>T</CODE> and <CODE>t1</CODE> is not one of
the types described in the previous item;</LI>
<LI><CODE>f(t1, t2, ..., tN)</CODE> in all other cases.</LI>
</UL>
</BLOCKQUOTE>

<BLOCKQUOTE>
Define <I>INVOKE</I>(f, t1, t2, ..., tN, R) as <I>INVOKE</I>(f, t1, t2, ..., tN)
implicitly converted to <CODE>R</CODE>.
</BLOCKQUOTE>

<BLOCKQUOTE>
If a <A HREF="#call wrapper">call wrapper</A> has a
<B><A NAME="weak result type">weak result type</A></B> the type of its
member type <CODE>result_type</CODE> is based on the type <CODE>T</CODE> of the wrapper's
<A HREF="#target object">target object</A>:

<UL>
<LI>if <CODE>T</CODE> is a pointer to function, <CODE>result_type</CODE> shall
be a synonym for the return type of <CODE>T</CODE>;</LI>
<LI>if <CODE>T</CODE> is a pointer to member function, <CODE>result_type</CODE>
shall be a synonym for the return type of <CODE>T</CODE>;</LI>
<LI>if <CODE>T</CODE> is a pointer to member data, <CODE>result_type</CODE>
shall be a synonym for the declared type of the data
member;<SUP><FONT SIZE=-1><A HREF="#fn3">3</A></FONT></SUP></LI>
<LI>if <CODE>T</CODE> is a class type with a member type <CODE>result_type</CODE>,
then <CODE>result_type</CODE> shall be a synonym for <CODE>T::result_type</CODE>;</LI>
<LI>otherwise <CODE>result_type</CODE> shall not be defined.</LI>
</UL>
</BLOCKQUOTE>

<BLOCKQUOTE>
Every <A HREF="#call wrapper">call wrapper</A> shall be CopyConstructible.
A <B><A NAME="simple call wrapper">simple call wrapper</A></B> is a call wrapper
that is Assignable and whose copy constructor and assignment operator do not
throw exceptions.
A <B><A NAME="forwarding call wrapper">forwarding call wrapper</A></B> is a
call wrapper that can be called with an argument list <CODE>t1, t2, ..., tN</CODE>
where each <CODE>ti</CODE> is an lvalue. The effect of calling a forwarding call
wrapper with one or more arguments that are rvalues is implementation defined.
[Note: in a typical implementation forwarding call wrappers have overloaded
function call operators of the form

<PRE>    template&lt;class T1, class T2, ..., class TN&gt;
    <I>R</I> operator()(T1&amp; t1, T2&amp; t2, ..., TN&amp; tN) <I>cv-qual</I>;</PRE>

-- end note]
</BLOCKQUOTE>

<H3>Changes to <CODE>reference_wrapper</CODE></H3>

<P>In [tr.util.refwrp.refwrp], remove paragraph 2 and its three bullet items
and replace them with:</P>

<BLOCKQUOTE>
<CODE>reference_wrapper</CODE> has a <A HREF="#weak result type">weak result type</A>.
</BLOCKQUOTE>

<P>Remove both paragraphs of [tr.util.refwrp.invoke] and replace them with:</P>

<BLOCKQUOTE>
<I>Returns</I>: <CODE><A HREF="#INVOKE">INVOKE</A>(get(), a1, a2, ..., aN)</CODE>
</BLOCKQUOTE>

<H3>Changes to <CODE>function</CODE></H3>

<P>Remove paragraphs 1, 2, and 3 from [tr.func.wrap.func].</P>

<P>After the template definition in [tr.func.wrap.func] add the following:</P>

<BLOCKQUOTE>
The <CODE>function</CODE> class template provides polymorphic wrappers that
generalize the notion of a function pointer. Wrappers can store, copy, and call
arbitrary <A HREF="#callable object">callable objects</A>, given a
<A HREF="#call signature">call signature</A>, allowing functions to be first-class
objects.
</BLOCKQUOTE>

<BLOCKQUOTE>
A function object <CODE>f</CODE> of type <CODE>F</CODE> is Callable for argument
types <CODE>T1, T2, ..., TN</CODE> and a return type <CODE>R</CODE>, if, given
lvalues <CODE>t1, t2, ..., tN</CODE> of types <CODE>T1, T2, ..., TN</CODE>,
respectively, <CODE><A HREF="#INVOKE">INVOKE</A>(f, t1, t2, ..., tN)</CODE> is
well-formed and, if <CODE>R</CODE> is not <CODE>void</CODE>, convertible to
<CODE>R</CODE>.
</BLOCKQUOTE>


<BLOCKQUOTE>
The <CODE>function</CODE> class template is a <A HREF="#call wrapper">call wrapper</A>
whose <A HREF="#call signature">call signature</A> is <CODE>R(T1, T2, ..., TN)</CODE>.
</BLOCKQUOTE>

<P>Remove paragraphs 1 and 2 of [tr.func.wrap.func.inv] and replace them with:</P>

<BLOCKQUOTE>
<I>Effects</I>: <CODE><A HREF="#INVOKE">INVOKE</A>(f, t1, t2, ..., tN, R)</CODE>,
where <CODE>f</CODE> is the <A HREF="#target object">target object</A> of
<CODE>*this</CODE>.
</BLOCKQUOTE>

<BLOCKQUOTE>
<I>Returns</I>: nothing, if <CODE>R</CODE> is <CODE>void</CODE>, otherwise
the return value of <CODE>INVOKE(f, t1, t2, ..., tN, R)</CODE>.
</BLOCKQUOTE>


<H3>Changes to <CODE>mem_fn</CODE></H3>

<P>Replace [tr.func.memfn] with:</P>

<PRE>    template&lt;class R, class T&gt;
    <I>unspecified</I> mem_fn(R T::*pm);</PRE>

<BLOCKQUOTE>
<I>Returns</I>: a <A HREF="#simple call wrapper">simple call wrapper</A>
<CODE>f</CODE> such that the expression <CODE>f(t, a2, ..., aN)</CODE> is
equivalent to <CODE><A HREF="#INVOKE">INVOKE</A>(pm, t, a2, ..., aN)</CODE>.
<CODE>f</CODE> shall have a nested type <CODE>result_type</CODE> that is a
synonym for the return type of <CODE>pm</CODE> when <CODE>pm</CODE> is a
pointer to member function, or a synonym for <CODE>R</CODE> or for
<CODE>R const&amp;</CODE> otherwise<SUP><FONT SIZE=-1><A HREF="#fn3">3</A></FONT></SUP>.
</BLOCKQUOTE>

<BLOCKQUOTE>
<I>Throws</I>: nothing.
</BLOCKQUOTE>

<BLOCKQUOTE>
<I>Notes</I>: implementations may implement <CODE>mem_fn</CODE> as a set of
overloaded function templates.
</BLOCKQUOTE>


<H3>Changes to <CODE>bind</CODE></H3>

<P>Replace [tr.func.bind.bind] with:</P>

<PRE>    template&lt;class F, class T1, class T2, ...., class TN&gt;
    <I>unspecified</I> bind(F f, T1 t1, T2 t2, ..., TN tN);</PRE>

<BLOCKQUOTE>
<P><EM>Requires:</EM>&nbsp; <CODE>F</CODE> and <CODE>Ti</CODE> shall be
<CODE>CopyConstructible</CODE>. <CODE>INVOKE(f, w1, w2, ..., wN)</CODE> shall be a
valid expression for some values <CODE>w1, w2, ..., wN</CODE>.</P>

<P><EM>Returns:</EM> A forwarding call wrapper <CODE>g</CODE> with a
    <A HREF="#weak result type">weak result type</A>. The effect of
    <CODE>g(u1, u2, ..., uM)</CODE> shall be
    <CODE><A HREF="#INVOKE">INVOKE</A>(f, v1, v2, ..., vN, result_of&lt;F
    <EM>cv </EM>(V1, V2, ..., VN)&gt;::type)</CODE>, where
    <CODE><EM>cv</EM></CODE> are the cv-qualifiers of <CODE>g</CODE> and
    the values and types of the <A HREF="#bound arguments">bound arguments</A>
    <CODE>v1, v2, ..., vN</CODE> are determined as specified below.</P>
</BLOCKQUOTE>

<PRE>    template&lt;class R, class F, class T1, class T2, ...., class TN&gt;
    <I>unspecified</I> bind(F f, T1 t1, T2 t2, ..., TN tN);</PRE>

<BLOCKQUOTE>
<P><EM>Requires:</EM>&nbsp; <CODE>F</CODE> and <CODE>Ti</CODE> shall be
    <CODE>CopyConstructible</CODE>. <CODE>INVOKE(f, w1, w2, ..., wN)</CODE> shall be
    a valid expression for some values <CODE>w1, w2, ..., wN</CODE>.</P>
<P><EM>Returns:</EM> A forwarding call wrapper <CODE>g</CODE> with a nested
    type <CODE>result_type</CODE> defined as a synonym for <CODE>R</CODE>.
    The effect of <CODE>g(u1, u2, ..., uM)</CODE> shall be
    <CODE><A HREF="#INVOKE">INVOKE</A>(f, v1, v2, ..., vN, R)</CODE>, where
    the values and types of the <A HREF="#bound arguments">bound arguments</A>
    <CODE>v1, v2, ..., vN</CODE> are determined as specified below.</P>
</BLOCKQUOTE>

<BLOCKQUOTE>
<P>The values of the <B><A NAME="bound arguments">bound arguments</A></B> <CODE>v1, 
    v2, ..., vN</CODE> and their corresponding types <CODE>V1, V2, ..., VN</CODE>
	depend on the type of the corresponding argument <CODE>ti</CODE> of type
	<CODE>Ti</CODE>	in the call to <CODE>bind</CODE> and the cv-qualifiers
    <EM>cv</EM> of the call wrapper <CODE>g</CODE> as follows:</P>

<UL>
	<LI>
		if <CODE>ti</CODE> is of type <CODE>reference_wrapper&lt;T&gt;</CODE> the 
		argument is <CODE>ti.get()</CODE> and its type <CODE>Vi</CODE> is
		<CODE>T&amp;</CODE>;
	<LI>
		if the value of <CODE>std::tr1::is_bind_expression&lt;Ti&gt;::value</CODE>
		is <CODE>true</CODE> the argument is <CODE>ti(u1, u2, ..., uM)</CODE>
		and its type <CODE>Vi</CODE> is <CODE>result_of&lt;Ti <EM>cv </EM>(U1&amp;,
		U2&amp;, ..., UM&amp;)&gt;::type</CODE>;
	<LI>
		if the value <CODE>j</CODE> of
		<CODE>std::tr1::is_placeholder&lt;Ti&gt;::value</CODE> is not zero the
		argument is <CODE>uj</CODE> and its type <CODE>Vi</CODE> is
		<CODE>Uj&amp;</CODE>;
	<LI>
		otherwise the value is <CODE>ti</CODE> and its type <CODE>Vi</CODE> is
		<CODE>Ti <EM>cv</EM> &amp;</CODE>.</LI>
</UL>
</BLOCKQUOTE>


<H3>Changes to <I>Implementation quantities</I></H3>

<P>Change the title of [tr.limits] to:</P>

<BLOCKQUOTE>
Annex A (informative) Implementation quantities
</BLOCKQUOTE>

<P>Change the text of [tr.limits] to the following:</P>

<BLOCKQUOTE>
<CODE>N<SUB>max</SUB></CODE>, the maximum number of arguments that can be forwarded
by the <A HREF="#call wrapper">call wrappers</A> defined in [tr.util.refwrap],
[tr.func.memfn], [tr.func.bin], [tr.func.wrap], and the maximum number of
argument types that can be passed in the argument to <CODE>result_of</CODE>
([tr.func.ret]), is implementation defined. The value of <CODE>N<SUB>max</SUB></CODE>
should be at least 10.
</BLOCKQUOTE>

<BLOCKQUOTE>
The number of distinct placeholders is implementation defined. The number should be
at least 10.
</BLOCKQUOTE>

<BLOCKQUOTE>
The maximum number of elements in one <CODE>tuple</CODE> type (clause [tr.tuple])
is implementation defined. The value should be at least 10.
</BLOCKQUOTE>

<HR>

<P><B><A NAME="fn1">1</A></B>. A pointer to member data cannot, of course,
be &quot;called&quot; in the usual sense.</P>

<P><B><A NAME="fn2">2</A></B>. Such a type often has a member <CODE>operator()</CODE>,
but in some cases it can omit that member and provide a conversion to a
pointer to function.</P>

<P><B><A NAME="fn3">3</A></B>. This requirement should be changed to reflect
the resolution of issue 10.24. (This footnote is not intended to be part of
TR1)</P>

<HR>

<P>Portions of this document are derived from work copyright &#169; 2004 by
Dinkumware, Ltd. All such material is made available for standardization purposes
only, and its inclusion does not waive the rights of Dinkumware, Ltd. under
applicable copyright laws.</P>

</BODY></HTML>
