Title
Swappable requirements need updating
Status
cd1
Section
[utility.arg.requirements]
Submitter
Howard Hinnant

Created on 2007-05-04.00:00:00 last changed 164 months ago

Messages

Date: 2010-10-21.18:28:33

Proposed resolution:

Change [utility.arg.requirements]:

-1- The template definitions in the C++ Standard Library refer to various named requirements whose details are set out in tables 31-38. In these tables, T is a type to be supplied by a C++ program instantiating a template; a, b, and c are values of type const T; s and t are modifiable lvalues of type T; u is a value of type (possibly const) T; and rv is a non-const rvalue of type T.

Table 37: Swappable requirements [swappable]
expressionreturn typepost-condition
swap(s,t)void t has the value originally held by u, and u has the value originally held by t

The Swappable requirement is met by satisfying one or more of the following conditions:

  • T is Swappable if T satisfies the CopyConstructible MoveConstructible requirements (Table 34 33) and the CopyAssignable MoveAssignable requirements (Table 36 35);
  • T is Swappable if a namespace scope function named swap exists in the same namespace as the definition of T, such that the expression swap(t,u) is valid and has the semantics described in this table.
Date: 2007-05-04.00:00:00

The current Swappable is:

Table 37: Swappable requirements [swappable]
expressionreturn typepost-condition
swap(s,t)voidt has the value originally held by u, and u has the value originally held by t

The Swappable requirement is met by satisfying one or more of the following conditions:

  • T is Swappable if T satisfies the CopyConstructible requirements (Table 34) and the CopyAssignable requirements (Table 36);
  • T is Swappable if a namespace scope function named swap exists in the same namespace as the definition of T, such that the expression swap(t,u) is valid and has the semantics described in this table.

With the passage of rvalue reference into the language, Swappable needs to be updated to require only MoveConstructible and MoveAssignable. This is a minimum.

Additionally we may want to support proxy references such that the following code is acceptable:

namespace Mine {

template <class T>
struct proxy {...};

template <class T>
struct proxied_iterator
{
   typedef T value_type;
   typedef proxy<T> reference;
   reference operator*() const;
   ...
};

struct A
{
   // heavy type, has an optimized swap, maybe isn't even copyable or movable, just swappable
   void swap(A&);
   ...
};

void swap(A&, A&);
void swap(proxy<A>, A&);
void swap(A&, proxy<A>);
void swap(proxy<A>, proxy<A>);

}  // Mine

...

Mine::proxied_iterator<Mine::A> i(...)
Mine::A a;
swap(*i1, a);

I.e. here is a call to swap which the user enables swapping between a proxy to a class and the class itself. We do not need to anything in terms of implementation except not block their way with overly constrained concepts. That is, the Swappable concept should be expanded to allow swapping between two different types for the case that one is binding to a user-defined swap.

History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg3392
2007-05-04 00:00:00admincreate