mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-02 08:13:58 +08:00
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>
|
||||
|
||||
* include/bits/locale_facets.tcc (time_get::_M_extract_via_format):
|
||||
|
@ -113,7 +113,9 @@ namespace __gnu_cxx
|
||||
template<typename Allocator>
|
||||
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;
|
||||
|
||||
private:
|
||||
@ -206,17 +208,22 @@ namespace __gnu_cxx
|
||||
template<typename Allocator>
|
||||
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;
|
||||
|
||||
private:
|
||||
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;
|
||||
|
||||
void decode_KVrA(string_type& prefix, string_type& postfix, int cvq,
|
||||
typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
const_reverse_iterator const& iter_array) const;
|
||||
typename qual_vector::
|
||||
const_reverse_iterator const& iter_array) const;
|
||||
|
||||
public:
|
||||
qualifier_list(session<Allocator>& demangler_obj)
|
||||
@ -270,7 +277,7 @@ namespace __gnu_cxx
|
||||
#if _GLIBCXX_DEMANGLER_CWDEBUG
|
||||
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();
|
||||
if (iter != list.M_qualifier_starts.end())
|
||||
{
|
||||
@ -344,7 +351,9 @@ namespace __gnu_cxx
|
||||
class session
|
||||
{
|
||||
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;
|
||||
|
||||
private:
|
||||
@ -361,9 +370,13 @@ namespace __gnu_cxx
|
||||
bool M_name_is_conversion_operator;
|
||||
bool M_template_args_need_space;
|
||||
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;
|
||||
std::vector<substitution_st, Allocator> M_substitutions_pos;
|
||||
std::vector<substitution_st, subst_Allocator> M_substitutions_pos;
|
||||
implementation_details const& M_implementation_details;
|
||||
#if _GLIBCXX_DEMANGLER_CWDEBUG
|
||||
bool M_inside_add_substitution;
|
||||
@ -1690,8 +1703,7 @@ namespace __gnu_cxx
|
||||
void
|
||||
qualifier_list<Allocator>::decode_KVrA(
|
||||
string_type& prefix, string_type& postfix, int cvq,
|
||||
typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
const_reverse_iterator const& iter_array) const
|
||||
typename qual_vector::const_reverse_iterator const& iter_array) const
|
||||
{
|
||||
_GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA");
|
||||
if ((cvq & cvq_K))
|
||||
@ -1703,7 +1715,7 @@ namespace __gnu_cxx
|
||||
if ((cvq & cvq_A))
|
||||
{
|
||||
int n = cvq >> 5;
|
||||
for (typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
for (typename qual_vector::
|
||||
const_reverse_iterator iter = iter_array;
|
||||
iter != M_qualifier_starts.rend(); ++iter)
|
||||
{
|
||||
@ -1744,9 +1756,8 @@ namespace __gnu_cxx
|
||||
{
|
||||
_GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers");
|
||||
int cvq = 0;
|
||||
typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
const_reverse_iterator iter_array;
|
||||
for(typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
typename qual_vector::const_reverse_iterator iter_array;
|
||||
for(typename qual_vector::
|
||||
const_reverse_iterator iter = M_qualifier_starts.rbegin();
|
||||
iter != M_qualifier_starts.rend(); ++iter)
|
||||
{
|
||||
@ -2676,8 +2687,8 @@ namespace __gnu_cxx
|
||||
template<typename Allocator>
|
||||
struct demangle
|
||||
{
|
||||
typedef Allocator allocator_type;
|
||||
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;
|
||||
static string_type symbol(char const* in,
|
||||
demangler::implementation_details const& id);
|
||||
@ -2690,7 +2701,7 @@ namespace __gnu_cxx
|
||||
// Demangle `input' which should be a mangled function name as for
|
||||
// instance returned by nm(1).
|
||||
template<typename Allocator>
|
||||
std::basic_string<char, std::char_traits<char>, Allocator>
|
||||
typename demangle<Allocator>::string_type
|
||||
demangle<Allocator>::symbol(char const* input,
|
||||
demangler::implementation_details const& id)
|
||||
{
|
||||
@ -2741,7 +2752,7 @@ namespace __gnu_cxx
|
||||
// Demangle `input' which must be a zero terminated mangled type
|
||||
// name as for instance returned by std::type_info::name().
|
||||
template<typename Allocator>
|
||||
std::basic_string<char, std::char_traits<char>, Allocator>
|
||||
typename demangle<Allocator>::string_type
|
||||
demangle<Allocator>::type(char const* input,
|
||||
demangler::implementation_details const& id)
|
||||
{
|
||||
|
@ -332,107 +332,12 @@ namespace __gnu_norm
|
||||
return __x + __n;
|
||||
}
|
||||
|
||||
|
||||
/// @if maint Primary default version. @endif
|
||||
/**
|
||||
* @if maint
|
||||
* Deque base class. It has two purposes. First, its constructor
|
||||
* and destructor allocate (but don't initialize) storage. This makes
|
||||
* %exception safety easier. Second, the base class encapsulates all of
|
||||
* the differences between SGI-style allocators and standard-conforming
|
||||
* 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.
|
||||
* Deque base class. This class provides the unified face for %deque's
|
||||
* allocation. This class's constructor and destructor allocate and
|
||||
* deallocate (but do not initialize) storage. This makes %exception
|
||||
* safety easier.
|
||||
*
|
||||
* Nothing in this class ever constructs or destroys an actual Tp element.
|
||||
* (Deque handles that itself.) Only/All memory management is performed
|
||||
@ -441,30 +346,56 @@ namespace __gnu_norm
|
||||
*/
|
||||
template<typename _Tp, typename _Alloc>
|
||||
class _Deque_base
|
||||
: public _Deque_alloc_base<_Tp,_Alloc,
|
||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
||||
: public _Alloc
|
||||
{
|
||||
public:
|
||||
typedef _Deque_alloc_base<_Tp,_Alloc,
|
||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
||||
_Base;
|
||||
typedef typename _Base::allocator_type allocator_type;
|
||||
typedef _Alloc allocator_type;
|
||||
allocator_type get_allocator() const
|
||||
{ return *static_cast<const _Alloc*>(this); }
|
||||
|
||||
typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator;
|
||||
typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
|
||||
|
||||
_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); }
|
||||
_Deque_base(const allocator_type& __a)
|
||||
: _Base(__a), _M_start(), _M_finish() {}
|
||||
: _Alloc(__a), _M_start(), _M_finish() {}
|
||||
~_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:
|
||||
void _M_initialize_map(size_t);
|
||||
void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
|
||||
void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
|
||||
enum { _S_initial_map_size = 8 };
|
||||
|
||||
_Tp** _M_map;
|
||||
size_t _M_map_size;
|
||||
iterator _M_start;
|
||||
iterator _M_finish;
|
||||
};
|
||||
@ -670,9 +601,7 @@ namespace __gnu_norm
|
||||
using _Base::_M_deallocate_map;
|
||||
|
||||
/** @if maint
|
||||
* A total of four data members accumulated down the heirarchy. If the
|
||||
* _Alloc type requires separate instances, then two of them will also be
|
||||
* included in each deque.
|
||||
* A total of four data members accumulated down the heirarchy.
|
||||
* @endif
|
||||
*/
|
||||
using _Base::_M_map;
|
||||
|
@ -202,36 +202,16 @@ namespace __gnu_norm
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// @if maint Primary default version. @endif
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
template<typename _Tp, typename _Allocator, bool _IsStatic>
|
||||
class _List_alloc_base
|
||||
template <typename _Tp, typename _Alloc>
|
||||
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:
|
||||
_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
|
||||
// The stored instance is not actually of "allocator_type"'s type.
|
||||
// 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
|
||||
// List_node<Tp> is being bound instead.
|
||||
//
|
||||
// We put this to the test in get_allocator above; if the two
|
||||
// types are actually different, there had better be a conversion
|
||||
// between them.
|
||||
//
|
||||
// None of the predefined allocators shipped with the library (as
|
||||
// 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;
|
||||
|
||||
// We put this to the test in the constructors and in get_allocator,
|
||||
// where we use conversions between allocator_type and
|
||||
// _Node_Alloc_type. The conversion is required by table 32 in [20.1.5].
|
||||
typedef typename _Alloc::template rebind<_List_node<_Tp> >::other
|
||||
_Node_Alloc_type;
|
||||
|
||||
_List_node<_Tp>*
|
||||
_M_get_node()
|
||||
{ return _Alloc_type::allocate(1); }
|
||||
|
||||
{ return _Node_Alloc_type::allocate(1); }
|
||||
|
||||
void
|
||||
_M_put_node(_List_node<_Tp>* __p)
|
||||
{ _Alloc_type::deallocate(__p, 1); }
|
||||
|
||||
{ _Node_Alloc_type::deallocate(__p, 1); }
|
||||
|
||||
_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:
|
||||
typedef _List_alloc_base<_Tp, _Alloc,
|
||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
||||
_Base;
|
||||
typedef typename _Base::allocator_type allocator_type;
|
||||
|
||||
typedef _Alloc allocator_type;
|
||||
allocator_type get_allocator() const
|
||||
|
||||
{ return allocator_type(*static_cast<const _Node_Alloc_type*>(this)); }
|
||||
|
||||
_List_base(const allocator_type& __a)
|
||||
: _Base(__a)
|
||||
: _Node_Alloc_type(__a)
|
||||
{
|
||||
this->_M_node._M_next = &this->_M_node;
|
||||
this->_M_node._M_prev = &this->_M_node;
|
||||
|
@ -67,70 +67,6 @@
|
||||
|
||||
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
|
||||
* See bits/stl_deque.h's _Deque_base for an explanation.
|
||||
@ -138,20 +74,19 @@ namespace __gnu_norm
|
||||
*/
|
||||
template<typename _Tp, typename _Alloc>
|
||||
struct _Vector_base
|
||||
: public _Vector_alloc_base<_Tp, _Alloc,
|
||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
||||
: public _Alloc
|
||||
{
|
||||
public:
|
||||
typedef _Vector_alloc_base<_Tp, _Alloc,
|
||||
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
|
||||
_Base;
|
||||
typedef typename _Base::allocator_type allocator_type;
|
||||
typedef _Alloc allocator_type;
|
||||
|
||||
allocator_type
|
||||
get_allocator() const { return *static_cast<const _Alloc*>(this); }
|
||||
|
||||
_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)
|
||||
: _Base(__a)
|
||||
: _Alloc(__a)
|
||||
{
|
||||
this->_M_start = this->_M_allocate(__n);
|
||||
this->_M_finish = this->_M_start;
|
||||
@ -161,6 +96,18 @@ namespace __gnu_norm
|
||||
~_Vector_base()
|
||||
{ _M_deallocate(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:
|
||||
/** @if maint
|
||||
* These two functions and three data members are all from the
|
||||
* top-most base class, which varies depending on the type of
|
||||
* %allocator. They should be pretty self-explanatory, as
|
||||
* base class. They should be pretty self-explanatory, as
|
||||
* %vector uses a simple contiguous allocation scheme. @endif
|
||||
*/
|
||||
using _Base::_M_allocate;
|
||||
@ -347,8 +293,7 @@ namespace __gnu_norm
|
||||
}
|
||||
|
||||
/// Get a copy of the memory allocation object.
|
||||
allocator_type
|
||||
get_allocator() const { return _Base::get_allocator(); }
|
||||
using _Base::get_allocator;
|
||||
|
||||
// iterators
|
||||
/**
|
||||
|
@ -77,7 +77,6 @@ using std::size_t;
|
||||
using std::ptrdiff_t;
|
||||
using std::forward_iterator_tag;
|
||||
using std::input_iterator_tag;
|
||||
using std::_Alloc_traits;
|
||||
using std::_Construct;
|
||||
using std::_Destroy;
|
||||
using std::distance;
|
||||
@ -242,10 +241,14 @@ private:
|
||||
typedef _Hashtable_node<_Val> _Node;
|
||||
|
||||
public:
|
||||
typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type;
|
||||
typedef _Alloc allocator_type;
|
||||
allocator_type get_allocator() const { return _M_node_allocator; }
|
||||
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); }
|
||||
void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
|
||||
|
||||
@ -253,7 +256,7 @@ private:
|
||||
hasher _M_hash;
|
||||
key_equal _M_equals;
|
||||
_ExtractKey _M_get_key;
|
||||
vector<_Node*,_Alloc> _M_buckets;
|
||||
_Vector_type _M_buckets;
|
||||
size_type _M_num_elements;
|
||||
|
||||
public:
|
||||
@ -876,8 +879,7 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
if (__num_elements_hint > __old_n) {
|
||||
const size_type __n = _M_next_size(__num_elements_hint);
|
||||
if (__n > __old_n) {
|
||||
vector<_Node*, _All> __tmp(__n, (_Node*)(0),
|
||||
_M_buckets.get_allocator());
|
||||
_Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
|
||||
try {
|
||||
for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
|
||||
_Node* __first = _M_buckets[__bucket];
|
||||
|
Loading…
Reference in New Issue
Block a user