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_typeIdentical to TSee Note B, below. …a1 == a2boolreturns trueonly 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.
truea1 != a2boolsame as!(a1 == a2)a == bboolsame asa ==
Y::rebind<T>::other(b)a != bboolsame 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:aequals the prior value ofX(b).…
After 16.4.4.6 [allocator.requirements] p3, add a new paragraph:
Note B: If
Allocatoris a class template instantiation of the formSomeAllocator<T, Args>, whereArgsis zero or more type arguments, andAllocatordoes not supply a nested type namedvalue_type, the standardallocator_traitstemplate usesTin place ofAllocator::value_typeby 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;
typedef typename 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_typeif such a type exists; otherwise,TifAllocis a class template instantiation of the formAlloc<T, Args>, whereArgsis 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 == a2if that expression is well-formed; otherwise,true.