Bug 61426 - [C++11] std::deque requires more from allocator than the standard provides.
Summary: [C++11] std::deque requires more from allocator than the standard provides.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-06-05 20:43 UTC by Paul Pluzhnikov
Modified: 2014-09-19 13:19 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Pluzhnikov 2014-06-05 20:43:37 UTC
Google ref: b/15420505

Section 23.3.3.1 of C++11 shows the following typedef members of deque,
among others:

   typedef typename allocator_traits<Allocator>::pointer pointer;
   typedef typename allocator_traits<Allocator>::const_pointer const_pointer;

Table 28 in section 17.6.3.5 shows that the `pointer` and `const_pointer`
members of allocator_traits have defaults, and therefore by the text in
17.6.3.5.2 the allocator type is not required to define these.

We should be able to use a custom allocator type with deque without defining
these. For what it's worth, cppreference.com agrees; it calls them optional
and doesn't include them in its minimal example (grep "SimpleAllocator"):

   http://en.cppreference.com/w/cpp/concept/Allocator

Above allocator works for std::vector and std::map, but not std::deque
(using trunk GCC @r211286).


Test case:

#include <cstddef>

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);

#ifdef REBIND
  template<typename U>
  struct rebind {
    typedef SimpleAllocator<U> other;
  };
#endif

};
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>&);

#include <deque>

typedef std::deque<int, SimpleAllocator<int> > IntDeque;
std::size_t foo(IntDeque& d)
{
  d.push_back(1);
  d.pop_front();
  return d.max_size();
}


/gcc-svn-r211286/bin/g++ -c t.cc -DDEQUE -std=c++11 
In file included from /gcc-svn-r211286/include/c++/4.10.0/deque:64:0,
                 from t.cc:24:
/gcc-svn-r211286/include/c++/4.10.0/bits/stl_deque.h: In instantiation of 'class std::_Deque_base<int, SimpleAllocator<int> >':
/gcc-svn-r211286/include/c++/4.10.0/bits/stl_deque.h:735:11:   required from 'class std::deque<int, SimpleAllocator<int> >'
t.cc:29:4:   required from here
/gcc-svn-r211286/include/c++/4.10.0/bits/stl_deque.h:490:61: error: no class template named 'rebind' in 'struct SimpleAllocator<int>'
       typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
                                                             ^
... many more ...

In addition to 'rebind', 'construct' and 'destroy', std::deque currently
also requires 'pointer', 'const_pointer', 'reference', 'const_reference'
and 'max_size', as can be seen by building with:

/gcc-svn-r211286/bin/g++ -c t.cc -DDEQUE -std=c++11 -DREBIND
Comment 1 Jonathan Wakely 2014-06-05 20:47:17 UTC
Yes, this is well known and documented
Comment 2 Jonathan Wakely 2014-06-05 20:48:16 UTC
std::list and std::string don't meet the C++11 allocator reqs either, please don't report them ;-)
Comment 3 Jonathan Wakely 2014-09-19 13:19:32 UTC
Fixed on trunk.