This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/61426] New: [C++11] std::deque requires more from allocator than the standard provides.


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61426

            Bug ID: 61426
           Summary: [C++11] std::deque requires more from allocator than
                    the standard provides.
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ppluzhnikov at google dot com

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]