demangle.h: Fix allocator type correctness, i.e.
* include/bits/demangle.h: Fix allocator type correctness, i.e. make sure that when we instantiate a container with a value type and an allocator, the allocator's value type matches the container's. * include/bits/stl_deque.h (_Deque_alloc_base): Eliminate. (_Deque_base): inherit directly from the deque's allocator. Use rebinding instead of _Alloc_traits. Pick up data members from _Deque_alloc_base. * include/bits/stl_list.h (_List_alloc_base): Eliminate. (_List_base): Inherit directly from the list's allocator. Use rebinding instead of _Alloc_traits. Pick up data members from _List_alloc_base. * include/bits/stl_vector.h (_Vector_alloc_base): Eliminate (_Vector_base): Inherit directly from the vector's allocator. Use rebinding instead of _Alloc_traits. Pick up data members from _Vector_alloc_base. * include/ext/hashtable.h: Fix allocator type correctness (the vector of buckets must be passed an allocator for objects of type _Node*). Use rebinding instead of _Alloc_traits. From-SVN: r74787
This commit is contained in:
parent
38700ceee7
commit
8a1d8dd9c8
|
@ -1,3 +1,25 @@
|
||||||
|
2003-12-18 Matt Austern <austern@apple.com>
|
||||||
|
|
||||||
|
* include/bits/demangle.h: Fix allocator type correctness,
|
||||||
|
i.e. make sure that when we instantiate a container with a value
|
||||||
|
type and an allocator, the allocator's value type matches the
|
||||||
|
container's.
|
||||||
|
* include/bits/stl_deque.h (_Deque_alloc_base): Eliminate.
|
||||||
|
(_Deque_base): inherit directly from the deque's allocator. Use
|
||||||
|
rebinding instead of _Alloc_traits. Pick up data members from
|
||||||
|
_Deque_alloc_base.
|
||||||
|
* include/bits/stl_list.h (_List_alloc_base): Eliminate.
|
||||||
|
(_List_base): Inherit directly from the list's allocator. Use
|
||||||
|
rebinding instead of _Alloc_traits. Pick up data members from
|
||||||
|
_List_alloc_base.
|
||||||
|
* include/bits/stl_vector.h (_Vector_alloc_base): Eliminate
|
||||||
|
(_Vector_base): Inherit directly from the vector's allocator. Use
|
||||||
|
rebinding instead of _Alloc_traits. Pick up data members from
|
||||||
|
_Vector_alloc_base.
|
||||||
|
* include/ext/hashtable.h: Fix allocator type correctness (the
|
||||||
|
vector of buckets must be passed an allocator for objects of
|
||||||
|
type _Node*). Use rebinding instead of _Alloc_traits.
|
||||||
|
|
||||||
2003-12-17 Paolo Carlini <pcarlini@suse.de>
|
2003-12-17 Paolo Carlini <pcarlini@suse.de>
|
||||||
|
|
||||||
* include/bits/locale_facets.tcc (time_get::_M_extract_via_format):
|
* include/bits/locale_facets.tcc (time_get::_M_extract_via_format):
|
||||||
|
|
|
@ -113,7 +113,9 @@ namespace __gnu_cxx
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
class qualifier
|
class qualifier
|
||||||
{
|
{
|
||||||
typedef std::basic_string<char, std::char_traits<char>, Allocator>
|
typedef typename Allocator::template rebind<char>::other
|
||||||
|
char_Allocator;
|
||||||
|
typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
|
||||||
string_type;
|
string_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -206,17 +208,22 @@ namespace __gnu_cxx
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
class qualifier_list
|
class qualifier_list
|
||||||
{
|
{
|
||||||
typedef std::basic_string<char, std::char_traits<char>, Allocator>
|
typedef typename Allocator::template rebind<char>::other
|
||||||
|
char_Allocator;
|
||||||
|
typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
|
||||||
string_type;
|
string_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable bool M_printing_suppressed;
|
mutable bool M_printing_suppressed;
|
||||||
std::vector<qualifier<Allocator>, Allocator> M_qualifier_starts;
|
typedef qualifier<Allocator> qual;
|
||||||
|
typedef typename Allocator::template rebind<qual>::other qual_Allocator;
|
||||||
|
typedef std::vector<qual, qual_Allocator> qual_vector;
|
||||||
|
qual_vector M_qualifier_starts;
|
||||||
session<Allocator>& M_demangler;
|
session<Allocator>& M_demangler;
|
||||||
|
|
||||||
void decode_KVrA(string_type& prefix, string_type& postfix, int cvq,
|
void decode_KVrA(string_type& prefix, string_type& postfix, int cvq,
|
||||||
typename std::vector<qualifier<Allocator>, Allocator>::
|
typename qual_vector::
|
||||||
const_reverse_iterator const& iter_array) const;
|
const_reverse_iterator const& iter_array) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
qualifier_list(session<Allocator>& demangler_obj)
|
qualifier_list(session<Allocator>& demangler_obj)
|
||||||
|
@ -270,7 +277,7 @@ namespace __gnu_cxx
|
||||||
#if _GLIBCXX_DEMANGLER_CWDEBUG
|
#if _GLIBCXX_DEMANGLER_CWDEBUG
|
||||||
friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list)
|
friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list)
|
||||||
{
|
{
|
||||||
typename std::vector<qualifier<Allocator>, Allocator>::const_iterator
|
typename qual_vector::const_iterator
|
||||||
iter = list.M_qualifier_starts.begin();
|
iter = list.M_qualifier_starts.begin();
|
||||||
if (iter != list.M_qualifier_starts.end())
|
if (iter != list.M_qualifier_starts.end())
|
||||||
{
|
{
|
||||||
|
@ -344,7 +351,9 @@ namespace __gnu_cxx
|
||||||
class session
|
class session
|
||||||
{
|
{
|
||||||
friend class qualifier_list<Allocator>;
|
friend class qualifier_list<Allocator>;
|
||||||
typedef std::basic_string<char, std::char_traits<char>, Allocator>
|
typedef typename Allocator::template rebind<char>::other
|
||||||
|
char_Allocator;
|
||||||
|
typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
|
||||||
string_type;
|
string_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -361,9 +370,13 @@ namespace __gnu_cxx
|
||||||
bool M_name_is_conversion_operator;
|
bool M_name_is_conversion_operator;
|
||||||
bool M_template_args_need_space;
|
bool M_template_args_need_space;
|
||||||
string_type M_function_name;
|
string_type M_function_name;
|
||||||
std::vector<int, Allocator> M_template_arg_pos;
|
typedef typename Allocator::template rebind<int>::other
|
||||||
|
int_Allocator;
|
||||||
|
typedef typename Allocator::template rebind<substitution_st>::other
|
||||||
|
subst_Allocator;
|
||||||
|
std::vector<int, int_Allocator> M_template_arg_pos;
|
||||||
int M_template_arg_pos_offset;
|
int M_template_arg_pos_offset;
|
||||||
std::vector<substitution_st, Allocator> M_substitutions_pos;
|
std::vector<substitution_st, subst_Allocator> M_substitutions_pos;
|
||||||
implementation_details const& M_implementation_details;
|
implementation_details const& M_implementation_details;
|
||||||
#if _GLIBCXX_DEMANGLER_CWDEBUG
|
#if _GLIBCXX_DEMANGLER_CWDEBUG
|
||||||
bool M_inside_add_substitution;
|
bool M_inside_add_substitution;
|
||||||
|
@ -1690,8 +1703,7 @@ namespace __gnu_cxx
|
||||||
void
|
void
|
||||||
qualifier_list<Allocator>::decode_KVrA(
|
qualifier_list<Allocator>::decode_KVrA(
|
||||||
string_type& prefix, string_type& postfix, int cvq,
|
string_type& prefix, string_type& postfix, int cvq,
|
||||||
typename std::vector<qualifier<Allocator>, Allocator>::
|
typename qual_vector::const_reverse_iterator const& iter_array) const
|
||||||
const_reverse_iterator const& iter_array) const
|
|
||||||
{
|
{
|
||||||
_GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA");
|
_GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA");
|
||||||
if ((cvq & cvq_K))
|
if ((cvq & cvq_K))
|
||||||
|
@ -1703,7 +1715,7 @@ namespace __gnu_cxx
|
||||||
if ((cvq & cvq_A))
|
if ((cvq & cvq_A))
|
||||||
{
|
{
|
||||||
int n = cvq >> 5;
|
int n = cvq >> 5;
|
||||||
for (typename std::vector<qualifier<Allocator>, Allocator>::
|
for (typename qual_vector::
|
||||||
const_reverse_iterator iter = iter_array;
|
const_reverse_iterator iter = iter_array;
|
||||||
iter != M_qualifier_starts.rend(); ++iter)
|
iter != M_qualifier_starts.rend(); ++iter)
|
||||||
{
|
{
|
||||||
|
@ -1744,9 +1756,8 @@ namespace __gnu_cxx
|
||||||
{
|
{
|
||||||
_GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers");
|
_GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers");
|
||||||
int cvq = 0;
|
int cvq = 0;
|
||||||
typename std::vector<qualifier<Allocator>, Allocator>::
|
typename qual_vector::const_reverse_iterator iter_array;
|
||||||
const_reverse_iterator iter_array;
|
for(typename qual_vector::
|
||||||
for(typename std::vector<qualifier<Allocator>, Allocator>::
|
|
||||||
const_reverse_iterator iter = M_qualifier_starts.rbegin();
|
const_reverse_iterator iter = M_qualifier_starts.rbegin();
|
||||||
iter != M_qualifier_starts.rend(); ++iter)
|
iter != M_qualifier_starts.rend(); ++iter)
|
||||||
{
|
{
|
||||||
|
@ -2676,8 +2687,8 @@ namespace __gnu_cxx
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
struct demangle
|
struct demangle
|
||||||
{
|
{
|
||||||
typedef Allocator allocator_type;
|
typedef typename Allocator::template rebind<char>::other char_Allocator;
|
||||||
typedef std::basic_string<char, std::char_traits<char>, Allocator>
|
typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
|
||||||
string_type;
|
string_type;
|
||||||
static string_type symbol(char const* in,
|
static string_type symbol(char const* in,
|
||||||
demangler::implementation_details const& id);
|
demangler::implementation_details const& id);
|
||||||
|
@ -2690,7 +2701,7 @@ namespace __gnu_cxx
|
||||||
// Demangle `input' which should be a mangled function name as for
|
// Demangle `input' which should be a mangled function name as for
|
||||||
// instance returned by nm(1).
|
// instance returned by nm(1).
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
std::basic_string<char, std::char_traits<char>, Allocator>
|
typename demangle<Allocator>::string_type
|
||||||
demangle<Allocator>::symbol(char const* input,
|
demangle<Allocator>::symbol(char const* input,
|
||||||
demangler::implementation_details const& id)
|
demangler::implementation_details const& id)
|
||||||
{
|
{
|
||||||
|
@ -2741,7 +2752,7 @@ namespace __gnu_cxx
|
||||||
// Demangle `input' which must be a zero terminated mangled type
|
// Demangle `input' which must be a zero terminated mangled type
|
||||||
// name as for instance returned by std::type_info::name().
|
// name as for instance returned by std::type_info::name().
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
std::basic_string<char, std::char_traits<char>, Allocator>
|
typename demangle<Allocator>::string_type
|
||||||
demangle<Allocator>::type(char const* input,
|
demangle<Allocator>::type(char const* input,
|
||||||
demangler::implementation_details const& id)
|
demangler::implementation_details const& id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -332,107 +332,12 @@ namespace __gnu_norm
|
||||||
return __x + __n;
|
return __x + __n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @if maint Primary default version. @endif
|
|
||||||
/**
|
/**
|
||||||
* @if maint
|
* @if maint
|
||||||
* Deque base class. It has two purposes. First, its constructor
|
* Deque base class. This class provides the unified face for %deque's
|
||||||
* and destructor allocate (but don't initialize) storage. This makes
|
* allocation. This class's constructor and destructor allocate and
|
||||||
* %exception safety easier. Second, the base class encapsulates all of
|
* deallocate (but do not initialize) storage. This makes %exception
|
||||||
* the differences between SGI-style allocators and standard-conforming
|
* safety easier.
|
||||||
* allocators. (See allocator.h for more on this topic.) There are two
|
|
||||||
* versions: this ordinary one, and the space-saving specialization for
|
|
||||||
* instanceless allocators.
|
|
||||||
* @endif
|
|
||||||
*/
|
|
||||||
template<typename _Tp, typename _Alloc, bool __is_static>
|
|
||||||
class _Deque_alloc_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
|
|
||||||
allocator_type get_allocator() const { return _M_node_allocator; }
|
|
||||||
|
|
||||||
_Deque_alloc_base(const allocator_type& __a)
|
|
||||||
: _M_node_allocator(__a), _M_map_allocator(__a),
|
|
||||||
_M_map(0), _M_map_size(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
|
|
||||||
_Map_allocator_type;
|
|
||||||
|
|
||||||
_Tp*
|
|
||||||
_M_allocate_node()
|
|
||||||
{
|
|
||||||
return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_M_deallocate_node(_Tp* __p)
|
|
||||||
{
|
|
||||||
_M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
|
|
||||||
}
|
|
||||||
|
|
||||||
_Tp**
|
|
||||||
_M_allocate_map(size_t __n)
|
|
||||||
{ return _M_map_allocator.allocate(__n); }
|
|
||||||
|
|
||||||
void
|
|
||||||
_M_deallocate_map(_Tp** __p, size_t __n)
|
|
||||||
{ _M_map_allocator.deallocate(__p, __n); }
|
|
||||||
|
|
||||||
allocator_type _M_node_allocator;
|
|
||||||
_Map_allocator_type _M_map_allocator;
|
|
||||||
_Tp** _M_map;
|
|
||||||
size_t _M_map_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @if maint Specialization for instanceless allocators. @endif
|
|
||||||
template<typename _Tp, typename _Alloc>
|
|
||||||
class _Deque_alloc_base<_Tp, _Alloc, true>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
|
|
||||||
allocator_type get_allocator() const { return allocator_type(); }
|
|
||||||
|
|
||||||
_Deque_alloc_base(const allocator_type&)
|
|
||||||
: _M_map(0), _M_map_size(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef typename _Alloc_traits<_Tp,_Alloc>::_Alloc_type _Node_alloc_type;
|
|
||||||
typedef typename _Alloc_traits<_Tp*,_Alloc>::_Alloc_type _Map_alloc_type;
|
|
||||||
|
|
||||||
_Tp*
|
|
||||||
_M_allocate_node()
|
|
||||||
{
|
|
||||||
return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_M_deallocate_node(_Tp* __p)
|
|
||||||
{
|
|
||||||
_Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
|
|
||||||
}
|
|
||||||
|
|
||||||
_Tp**
|
|
||||||
_M_allocate_map(size_t __n)
|
|
||||||
{ return _Map_alloc_type::allocate(__n); }
|
|
||||||
|
|
||||||
void
|
|
||||||
_M_deallocate_map(_Tp** __p, size_t __n)
|
|
||||||
{ _Map_alloc_type::deallocate(__p, __n); }
|
|
||||||
|
|
||||||
_Tp** _M_map;
|
|
||||||
size_t _M_map_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @if maint
|
|
||||||
* Deque base class. Using _Alloc_traits in the instantiation of the parent
|
|
||||||
* class provides the compile-time dispatching mentioned in the parent's
|
|
||||||
* docs. This class provides the unified face for %deque's allocation.
|
|
||||||
*
|
*
|
||||||
* Nothing in this class ever constructs or destroys an actual Tp element.
|
* Nothing in this class ever constructs or destroys an actual Tp element.
|
||||||
* (Deque handles that itself.) Only/All memory management is performed
|
* (Deque handles that itself.) Only/All memory management is performed
|
||||||
|
@ -441,30 +346,56 @@ namespace __gnu_norm
|
||||||
*/
|
*/
|
||||||
template<typename _Tp, typename _Alloc>
|
template<typename _Tp, typename _Alloc>
|
||||||
class _Deque_base
|
class _Deque_base
|
||||||
: public _Deque_alloc_base<_Tp,_Alloc,
|
: public _Alloc
|
||||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef _Deque_alloc_base<_Tp,_Alloc,
|
typedef _Alloc allocator_type;
|
||||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
allocator_type get_allocator() const
|
||||||
_Base;
|
{ return *static_cast<const _Alloc*>(this); }
|
||||||
typedef typename _Base::allocator_type allocator_type;
|
|
||||||
typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator;
|
typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator;
|
||||||
typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
|
typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
|
||||||
|
|
||||||
_Deque_base(const allocator_type& __a, size_t __num_elements)
|
_Deque_base(const allocator_type& __a, size_t __num_elements)
|
||||||
: _Base(__a), _M_start(), _M_finish()
|
: _Alloc(__a), _M_start(), _M_finish()
|
||||||
{ _M_initialize_map(__num_elements); }
|
{ _M_initialize_map(__num_elements); }
|
||||||
_Deque_base(const allocator_type& __a)
|
_Deque_base(const allocator_type& __a)
|
||||||
: _Base(__a), _M_start(), _M_finish() {}
|
: _Alloc(__a), _M_start(), _M_finish() {}
|
||||||
~_Deque_base();
|
~_Deque_base();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
|
||||||
|
_Map_alloc_type _M_get_map_allocator() const
|
||||||
|
{ return _Map_alloc_type(this->get_allocator()); }
|
||||||
|
|
||||||
|
_Tp*
|
||||||
|
_M_allocate_node()
|
||||||
|
{
|
||||||
|
return _Alloc::allocate(__deque_buf_size(sizeof(_Tp)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_M_deallocate_node(_Tp* __p)
|
||||||
|
{
|
||||||
|
_Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
|
||||||
|
}
|
||||||
|
|
||||||
|
_Tp**
|
||||||
|
_M_allocate_map(size_t __n)
|
||||||
|
{ return _M_get_map_allocator().allocate(__n); }
|
||||||
|
|
||||||
|
void
|
||||||
|
_M_deallocate_map(_Tp** __p, size_t __n)
|
||||||
|
{ _M_get_map_allocator().deallocate(__p, __n); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _M_initialize_map(size_t);
|
void _M_initialize_map(size_t);
|
||||||
void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
|
void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
|
||||||
void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
|
void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
|
||||||
enum { _S_initial_map_size = 8 };
|
enum { _S_initial_map_size = 8 };
|
||||||
|
|
||||||
|
_Tp** _M_map;
|
||||||
|
size_t _M_map_size;
|
||||||
iterator _M_start;
|
iterator _M_start;
|
||||||
iterator _M_finish;
|
iterator _M_finish;
|
||||||
};
|
};
|
||||||
|
@ -670,9 +601,7 @@ namespace __gnu_norm
|
||||||
using _Base::_M_deallocate_map;
|
using _Base::_M_deallocate_map;
|
||||||
|
|
||||||
/** @if maint
|
/** @if maint
|
||||||
* A total of four data members accumulated down the heirarchy. If the
|
* A total of four data members accumulated down the heirarchy.
|
||||||
* _Alloc type requires separate instances, then two of them will also be
|
|
||||||
* included in each deque.
|
|
||||||
* @endif
|
* @endif
|
||||||
*/
|
*/
|
||||||
using _Base::_M_map;
|
using _Base::_M_map;
|
||||||
|
|
|
@ -202,36 +202,16 @@ namespace __gnu_norm
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// @if maint Primary default version. @endif
|
|
||||||
/**
|
/**
|
||||||
* @if maint
|
* @if maint
|
||||||
* See bits/stl_deque.h's _Deque_alloc_base for an explanation.
|
* See bits/stl_deque.h's _Deque_base for an explanation.
|
||||||
* @endif
|
* @endif
|
||||||
*/
|
*/
|
||||||
template<typename _Tp, typename _Allocator, bool _IsStatic>
|
template <typename _Tp, typename _Alloc>
|
||||||
class _List_alloc_base
|
class _List_base
|
||||||
|
: public _Alloc::template rebind<_List_node<_Tp> >::other
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
|
|
||||||
allocator_type;
|
|
||||||
|
|
||||||
allocator_type
|
|
||||||
get_allocator() const { return _M_node_allocator; }
|
|
||||||
|
|
||||||
_List_alloc_base(const allocator_type& __a)
|
|
||||||
: _M_node_allocator(__a)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
_List_node<_Tp>*
|
|
||||||
_M_get_node()
|
|
||||||
{ return _M_node_allocator.allocate(1); }
|
|
||||||
|
|
||||||
void
|
|
||||||
_M_put_node(_List_node<_Tp>* __p)
|
|
||||||
{ _M_node_allocator.deallocate(__p, 1); }
|
|
||||||
|
|
||||||
// NOTA BENE
|
// NOTA BENE
|
||||||
// The stored instance is not actually of "allocator_type"'s type.
|
// The stored instance is not actually of "allocator_type"'s type.
|
||||||
// Instead we rebind the type to Allocator<List_node<Tp>>, which
|
// Instead we rebind the type to Allocator<List_node<Tp>>, which
|
||||||
|
@ -240,69 +220,29 @@ namespace __gnu_norm
|
||||||
// larger), and specializations on Tp may go unused because
|
// larger), and specializations on Tp may go unused because
|
||||||
// List_node<Tp> is being bound instead.
|
// List_node<Tp> is being bound instead.
|
||||||
//
|
//
|
||||||
// We put this to the test in get_allocator above; if the two
|
// We put this to the test in the constructors and in get_allocator,
|
||||||
// types are actually different, there had better be a conversion
|
// where we use conversions between allocator_type and
|
||||||
// between them.
|
// _Node_Alloc_type. The conversion is required by table 32 in [20.1.5].
|
||||||
//
|
typedef typename _Alloc::template rebind<_List_node<_Tp> >::other
|
||||||
// None of the predefined allocators shipped with the library (as
|
_Node_Alloc_type;
|
||||||
// of 3.1) use this instantiation anyhow; they're all
|
|
||||||
// instanceless.
|
|
||||||
typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
|
|
||||||
_M_node_allocator;
|
|
||||||
|
|
||||||
_List_node_base _M_node;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @if maint Specialization for instanceless allocators. @endif
|
|
||||||
template<typename _Tp, typename _Allocator>
|
|
||||||
class _List_alloc_base<_Tp, _Allocator, true>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
|
|
||||||
allocator_type;
|
|
||||||
|
|
||||||
allocator_type
|
|
||||||
get_allocator() const { return allocator_type(); }
|
|
||||||
|
|
||||||
_List_alloc_base(const allocator_type&)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// See comment in primary template class about why this is safe for the
|
|
||||||
// standard predefined classes.
|
|
||||||
typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type
|
|
||||||
_Alloc_type;
|
|
||||||
|
|
||||||
_List_node<_Tp>*
|
_List_node<_Tp>*
|
||||||
_M_get_node()
|
_M_get_node()
|
||||||
{ return _Alloc_type::allocate(1); }
|
{ return _Node_Alloc_type::allocate(1); }
|
||||||
|
|
||||||
void
|
void
|
||||||
_M_put_node(_List_node<_Tp>* __p)
|
_M_put_node(_List_node<_Tp>* __p)
|
||||||
{ _Alloc_type::deallocate(__p, 1); }
|
{ _Node_Alloc_type::deallocate(__p, 1); }
|
||||||
|
|
||||||
_List_node_base _M_node;
|
_List_node_base _M_node;
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @if maint
|
|
||||||
* See bits/stl_deque.h's _Deque_base for an explanation.
|
|
||||||
* @endif
|
|
||||||
*/
|
|
||||||
template <typename _Tp, typename _Alloc>
|
|
||||||
class _List_base
|
|
||||||
: public _List_alloc_base<_Tp, _Alloc,
|
|
||||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
typedef _List_alloc_base<_Tp, _Alloc,
|
typedef _Alloc allocator_type;
|
||||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
allocator_type get_allocator() const
|
||||||
_Base;
|
|
||||||
typedef typename _Base::allocator_type allocator_type;
|
{ return allocator_type(*static_cast<const _Node_Alloc_type*>(this)); }
|
||||||
|
|
||||||
_List_base(const allocator_type& __a)
|
_List_base(const allocator_type& __a)
|
||||||
: _Base(__a)
|
: _Node_Alloc_type(__a)
|
||||||
{
|
{
|
||||||
this->_M_node._M_next = &this->_M_node;
|
this->_M_node._M_next = &this->_M_node;
|
||||||
this->_M_node._M_prev = &this->_M_node;
|
this->_M_node._M_prev = &this->_M_node;
|
||||||
|
|
|
@ -67,70 +67,6 @@
|
||||||
|
|
||||||
namespace __gnu_norm
|
namespace __gnu_norm
|
||||||
{
|
{
|
||||||
/// @if maint Primary default version. @endif
|
|
||||||
/**
|
|
||||||
* @if maint
|
|
||||||
* See bits/stl_deque.h's _Deque_alloc_base for an explanation.
|
|
||||||
* @endif
|
|
||||||
*/
|
|
||||||
template<typename _Tp, typename _Allocator, bool _IsStatic>
|
|
||||||
class _Vector_alloc_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
|
|
||||||
allocator_type;
|
|
||||||
|
|
||||||
allocator_type
|
|
||||||
get_allocator() const { return _M_data_allocator; }
|
|
||||||
|
|
||||||
_Vector_alloc_base(const allocator_type& __a)
|
|
||||||
: _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
allocator_type _M_data_allocator;
|
|
||||||
_Tp* _M_start;
|
|
||||||
_Tp* _M_finish;
|
|
||||||
_Tp* _M_end_of_storage;
|
|
||||||
|
|
||||||
_Tp*
|
|
||||||
_M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); }
|
|
||||||
|
|
||||||
void
|
|
||||||
_M_deallocate(_Tp* __p, size_t __n)
|
|
||||||
{ if (__p) _M_data_allocator.deallocate(__p, __n); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @if maint Specialization for instanceless allocators. @endif
|
|
||||||
template<typename _Tp, typename _Allocator>
|
|
||||||
class _Vector_alloc_base<_Tp, _Allocator, true>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
|
|
||||||
allocator_type;
|
|
||||||
|
|
||||||
allocator_type
|
|
||||||
get_allocator() const { return allocator_type(); }
|
|
||||||
|
|
||||||
_Vector_alloc_base(const allocator_type&)
|
|
||||||
: _M_start(0), _M_finish(0), _M_end_of_storage(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
_Tp* _M_start;
|
|
||||||
_Tp* _M_finish;
|
|
||||||
_Tp* _M_end_of_storage;
|
|
||||||
|
|
||||||
typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
|
|
||||||
|
|
||||||
_Tp*
|
|
||||||
_M_allocate(size_t __n) { return _Alloc_type::allocate(__n); }
|
|
||||||
|
|
||||||
void
|
|
||||||
_M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n);}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @if maint
|
* @if maint
|
||||||
* See bits/stl_deque.h's _Deque_base for an explanation.
|
* See bits/stl_deque.h's _Deque_base for an explanation.
|
||||||
|
@ -138,20 +74,19 @@ namespace __gnu_norm
|
||||||
*/
|
*/
|
||||||
template<typename _Tp, typename _Alloc>
|
template<typename _Tp, typename _Alloc>
|
||||||
struct _Vector_base
|
struct _Vector_base
|
||||||
: public _Vector_alloc_base<_Tp, _Alloc,
|
: public _Alloc
|
||||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef _Vector_alloc_base<_Tp, _Alloc,
|
typedef _Alloc allocator_type;
|
||||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
|
||||||
_Base;
|
allocator_type
|
||||||
typedef typename _Base::allocator_type allocator_type;
|
get_allocator() const { return *static_cast<const _Alloc*>(this); }
|
||||||
|
|
||||||
_Vector_base(const allocator_type& __a)
|
_Vector_base(const allocator_type& __a)
|
||||||
: _Base(__a) { }
|
: _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
|
||||||
|
|
||||||
_Vector_base(size_t __n, const allocator_type& __a)
|
_Vector_base(size_t __n, const allocator_type& __a)
|
||||||
: _Base(__a)
|
: _Alloc(__a)
|
||||||
{
|
{
|
||||||
this->_M_start = this->_M_allocate(__n);
|
this->_M_start = this->_M_allocate(__n);
|
||||||
this->_M_finish = this->_M_start;
|
this->_M_finish = this->_M_start;
|
||||||
|
@ -161,6 +96,18 @@ namespace __gnu_norm
|
||||||
~_Vector_base()
|
~_Vector_base()
|
||||||
{ _M_deallocate(this->_M_start,
|
{ _M_deallocate(this->_M_start,
|
||||||
this->_M_end_of_storage - this->_M_start); }
|
this->_M_end_of_storage - this->_M_start); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
_Tp* _M_start;
|
||||||
|
_Tp* _M_finish;
|
||||||
|
_Tp* _M_end_of_storage;
|
||||||
|
|
||||||
|
_Tp*
|
||||||
|
_M_allocate(size_t __n) { return _Alloc::allocate(__n); }
|
||||||
|
|
||||||
|
void
|
||||||
|
_M_deallocate(_Tp* __p, size_t __n)
|
||||||
|
{ if (__p) _Alloc::deallocate(__p, __n); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,8 +156,7 @@ namespace __gnu_norm
|
||||||
protected:
|
protected:
|
||||||
/** @if maint
|
/** @if maint
|
||||||
* These two functions and three data members are all from the
|
* These two functions and three data members are all from the
|
||||||
* top-most base class, which varies depending on the type of
|
* base class. They should be pretty self-explanatory, as
|
||||||
* %allocator. They should be pretty self-explanatory, as
|
|
||||||
* %vector uses a simple contiguous allocation scheme. @endif
|
* %vector uses a simple contiguous allocation scheme. @endif
|
||||||
*/
|
*/
|
||||||
using _Base::_M_allocate;
|
using _Base::_M_allocate;
|
||||||
|
@ -347,8 +293,7 @@ namespace __gnu_norm
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a copy of the memory allocation object.
|
/// Get a copy of the memory allocation object.
|
||||||
allocator_type
|
using _Base::get_allocator;
|
||||||
get_allocator() const { return _Base::get_allocator(); }
|
|
||||||
|
|
||||||
// iterators
|
// iterators
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -77,7 +77,6 @@ using std::size_t;
|
||||||
using std::ptrdiff_t;
|
using std::ptrdiff_t;
|
||||||
using std::forward_iterator_tag;
|
using std::forward_iterator_tag;
|
||||||
using std::input_iterator_tag;
|
using std::input_iterator_tag;
|
||||||
using std::_Alloc_traits;
|
|
||||||
using std::_Construct;
|
using std::_Construct;
|
||||||
using std::_Destroy;
|
using std::_Destroy;
|
||||||
using std::distance;
|
using std::distance;
|
||||||
|
@ -242,10 +241,14 @@ private:
|
||||||
typedef _Hashtable_node<_Val> _Node;
|
typedef _Hashtable_node<_Val> _Node;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type;
|
typedef _Alloc allocator_type;
|
||||||
allocator_type get_allocator() const { return _M_node_allocator; }
|
allocator_type get_allocator() const { return _M_node_allocator; }
|
||||||
private:
|
private:
|
||||||
typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator;
|
typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
|
||||||
|
typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
|
||||||
|
typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
|
||||||
|
|
||||||
|
_Node_Alloc _M_node_allocator;
|
||||||
_Node* _M_get_node() { return _M_node_allocator.allocate(1); }
|
_Node* _M_get_node() { return _M_node_allocator.allocate(1); }
|
||||||
void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
|
void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
|
||||||
|
|
||||||
|
@ -253,7 +256,7 @@ private:
|
||||||
hasher _M_hash;
|
hasher _M_hash;
|
||||||
key_equal _M_equals;
|
key_equal _M_equals;
|
||||||
_ExtractKey _M_get_key;
|
_ExtractKey _M_get_key;
|
||||||
vector<_Node*,_Alloc> _M_buckets;
|
_Vector_type _M_buckets;
|
||||||
size_type _M_num_elements;
|
size_type _M_num_elements;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -876,8 +879,7 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||||
if (__num_elements_hint > __old_n) {
|
if (__num_elements_hint > __old_n) {
|
||||||
const size_type __n = _M_next_size(__num_elements_hint);
|
const size_type __n = _M_next_size(__num_elements_hint);
|
||||||
if (__n > __old_n) {
|
if (__n > __old_n) {
|
||||||
vector<_Node*, _All> __tmp(__n, (_Node*)(0),
|
_Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
|
||||||
_M_buckets.get_allocator());
|
|
||||||
try {
|
try {
|
||||||
for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
|
for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
|
||||||
_Node* __first = _M_buckets[__bucket];
|
_Node* __first = _M_buckets[__bucket];
|
||||||
|
|
Loading…
Reference in New Issue