Title
Allocator requirements should be further minimized
Status
nad
Section
[allocator.requirements]
Submitter
Stephan T. Lavavej

Created on 2013-09-21.00:00:00 last changed 123 months ago

Messages

Date: 2014-02-14.07:07:05

Proposed resolution:

This wording is relative to N3691.

  1. Change in [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 as a ==
    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 of X(b).
     
  2. After [allocator.requirements] p3, add a new paragraph:

    Note B: If Allocator is a class template instantiation of the form SomeAllocator<T, Args>, where Args is zero or more type arguments, and Allocator does not supply a nested type named value_type, the standard allocator_traits template uses T in place of Allocator::value_type by default. For allocator types that are not template instantiations of the above form, no default is provided.

  3. In the example provided in [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>&);
    
  4. Edit [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;
      };
    }
    
  5. At the beginning of [allocator.traits.types], add a new paragraph:

    typedef see below value_type;
    

    Type: Alloc::value_type if such a type exists; otherwise, T if Alloc is a class template instantiation of the form Alloc<T, Args>, where Args is zero or more type arguments; otherwise, the program is ill-formed.

  6. At the end of [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.

Date: 2014-02-14.00:00:00

[ 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.

Date: 2013-09-21.00:00:00

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_referencestd::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.

History
Date User Action Args
2014-02-14 07:07:05adminsetmessages: + msg6853
2014-02-14 07:07:05adminsetstatus: new -> nad
2013-10-09 22:13:25adminsetmessages: + msg6691
2013-09-21 00:00:00admincreate