Section: 16.4.4.6 [allocator.requirements] Status: NAD Submitter: Stephan T. Lavavej Opened: 2013-09-21 Last modified: 2016-01-28
Priority: 2
View other active issues in [allocator.requirements].
View all other issues in [allocator.requirements].
View all issues with NAD status.
Discussion:
C++11's minimized allocator requirements are great, but they're still requiring more things from users than absolutely necessary.
They require X::value_type
, but that can be deduced from SomeAllocator<T, Args>
.
They require a1 == a2
, but that could default to true
as most allocators are stateless.
They require a1 != a2
, but if we start requiring STL implementations to go through allocator_traits
to provide an op==
default, we won't need to require op!=
from users at all. (std::allocator
,
of course, would continue to provide op!=
. Note that this is analogous to reference
/const_reference
—
std::allocator
still provides them, but we don't require them from users, and in fact we don't require them to be
consistent or meaningful if present.)
They require a == b
and a != b
. This requirement was not present in C++98/03, it is not necessary
(a == b
is always required to be equivalent to rebind-then-compare), and STL implementations don't even need
to compare allocators of different types directly.
[2014-02-14 Issaquah: Close as NAD]
Different vendors rely on each of the different elements suggested to be removed.
While value_type
my be deduced as suggested, far too much wording relies on it being available,
and the standard churn is likely to be much harder than presented here.
Proposed resolution:
This wording is relative to N3691.
Change in 16.4.4.6 [allocator.requirements], Table 28 — "Allocator requirements" as indicated:
Table 28 — Allocator requirements (continued) Expression Return type Assertion/note pre-/post-condition Default …
X::value_type
Identical to T
See Note B, below. …
a1 == a2
bool
returns true
only if storage
allocated from each can be
deallocated via the other.
operator==
shall be reflexive,
symmetric, and transitive, and
shall not exit via an exception.
true
a1 != a2
bool
same as!(a1 == a2)
a == b
bool
same asa ==
Y::rebind<T>::other(b)a != b
bool
same as!(a == b)
…
X a(b);
Shall not exit via an exception.
post:Y(a) == b
,a == X(b)
…
X a(move(b));
Shall not exit via an exception.
post:a
equals the prior value ofX(b)
.…
After 16.4.4.6 [allocator.requirements] p3, add a new paragraph:
Note B: If
Allocator
is a class template instantiation of the formSomeAllocator<T, Args>
, whereArgs
is zero or more type arguments, andAllocator
does not supply a nested type namedvalue_type
, the standardallocator_traits
template usesT
in place ofAllocator::value_type
by default. For allocator types that are not template instantiations of the above form, no default is provided.
In the example provided in 16.4.4.6 [allocator.requirements]/5, delete as indicated:
template <class Tp> struct SimpleAllocator {typedef Tp value_type;SimpleAllocator(ctor args); template <class T> SimpleAllocator(const SimpleAllocator<T>& other); Tp *allocate(std::size_t n); void deallocate(Tp *p, std::size_t n); };template <class T, class U> bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&); template <class T, class U> bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
Edit 20.2.9 [allocator.traits]p1, class template allocator_traits
synopsis, as indicated:
namespace std { template <class Alloc> struct allocator_traits { typedef Alloc allocator_type; typedeftypename Alloc::value_typesee below value_type; […] static Alloc select_on_container_copy_construction(const Alloc& rhs); static bool equal(const Alloc& a1, const Alloc& a2) noexcept; }; }
At the beginning of 20.2.9.2 [allocator.traits.types], add a new paragraph:
typedef see below value_type;Type:
Alloc::value_type
if such a type exists; otherwise,T
ifAlloc
is a class template instantiation of the formAlloc<T, Args>
, whereArgs
is zero or more type arguments; otherwise, the program is ill-formed.
At the end of 20.2.9.3 [allocator.traits.members], add a new paragraph:
static bool equal(const Alloc& a1, const Alloc& a2) noexcept;-?- Returns:
a1 == a2
if that expression is well-formed; otherwise,true
.