mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-11 08:49:40 +08:00
rc_string_base.h (__rc_string_base<>::_Rep): Avoid the anonymous struct extension, adjust everywhere.
2005-11-18 Paolo Carlini <pcarlini@suse.de> * include/ext/rc_string_base.h (__rc_string_base<>::_Rep): Avoid the anonymous struct extension, adjust everywhere. * include/ext/rc_string_base.h (__rc_string_base<>::_S_empty_rep()): Just use a static member. (__rc_string_base<>::__rc_string_base(), _S_construct): Adjust. * include/ext/rc_string_base.h (__rc_string_base<>::_Rep): Use anonymous union together with _CharT to fix alignment issues, rebind to _Rep and rename _Raw_alloc to _Rep_alloc_type. (__rc_string_base<>::_Rep::_S_create, _M_destroy): Adjust consistently. * include/ext/vstring_util.h (__is_null_p): Move inside struct __vstring_utility as static _S_is_null_pointer. * include/ext/sso_string.h (__sso_string_base<>::_M_construct(std::forward_iterator_tag): Adjust. * include/ext/rc_string_base.h (__rc_string_base<>::_S_construct(std::forward_iterator_tag): Likewise. Implement Option 3 of DR 431 for ext/vstring - both available bases. * include/bits/cpp_type_traits.h (struct __is_empty): Add. * include/ext/vstring.h (__versa_string<>::swap): Delegate to this->_M_swap. * include/ext/vstring.tcc (__versa_string<>::swap): Remove. * include/ext/vstring_util.h (struct __vstring_utility<>): Add struct _Alloc_hider<>, augmented of allocator swapping facility, specialized to nop for empty allocators. * include/ext/rc_string_base.h (__rc_string_base<>::_M_swap): Use it. (__rc_string_base<>::_M_is_leaked, _M_set_sharable): Change to private. * include/ext/sso_string_base.h (__sso_string_base<>::_M_swap): Likewise. (__sso_string_base<>::_M_is_leaked, _M_set_sharable): Remove, unused. * include/ext/rc_string_base.h (__rc_string_base<>::_M_data(_CharT*): Return void. * include/ext/sso_string_base.h (__sso_string_base<>::_M_data(_CharT*): Likewise. From-SVN: r107176
This commit is contained in:
parent
e0709888ef
commit
7697e6c66a
@ -1,3 +1,43 @@
|
||||
2005-11-18 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
* include/ext/rc_string_base.h (__rc_string_base<>::_Rep): Avoid the
|
||||
anonymous struct extension, adjust everywhere.
|
||||
|
||||
* include/ext/rc_string_base.h (__rc_string_base<>::_S_empty_rep()):
|
||||
Just use a static member.
|
||||
(__rc_string_base<>::__rc_string_base(), _S_construct): Adjust.
|
||||
|
||||
* include/ext/rc_string_base.h (__rc_string_base<>::_Rep): Use anonymous
|
||||
union together with _CharT to fix alignment issues, rebind to _Rep and
|
||||
rename _Raw_alloc to _Rep_alloc_type.
|
||||
(__rc_string_base<>::_Rep::_S_create, _M_destroy): Adjust consistently.
|
||||
|
||||
* include/ext/vstring_util.h (__is_null_p): Move inside struct
|
||||
__vstring_utility as static _S_is_null_pointer.
|
||||
* include/ext/sso_string.h
|
||||
(__sso_string_base<>::_M_construct(std::forward_iterator_tag): Adjust.
|
||||
* include/ext/rc_string_base.h
|
||||
(__rc_string_base<>::_S_construct(std::forward_iterator_tag): Likewise.
|
||||
|
||||
Implement Option 3 of DR 431 for ext/vstring - both available bases.
|
||||
* include/bits/cpp_type_traits.h (struct __is_empty): Add.
|
||||
* include/ext/vstring.h (__versa_string<>::swap): Delegate to
|
||||
this->_M_swap.
|
||||
* include/ext/vstring.tcc (__versa_string<>::swap): Remove.
|
||||
* include/ext/vstring_util.h (struct __vstring_utility<>): Add struct
|
||||
_Alloc_hider<>, augmented of allocator swapping facility, specialized
|
||||
to nop for empty allocators.
|
||||
* include/ext/rc_string_base.h (__rc_string_base<>::_M_swap): Use it.
|
||||
(__rc_string_base<>::_M_is_leaked, _M_set_sharable): Change to private.
|
||||
* include/ext/sso_string_base.h (__sso_string_base<>::_M_swap):
|
||||
Likewise.
|
||||
(__sso_string_base<>::_M_is_leaked, _M_set_sharable): Remove, unused.
|
||||
|
||||
* include/ext/rc_string_base.h (__rc_string_base<>::_M_data(_CharT*):
|
||||
Return void.
|
||||
* include/ext/sso_string_base.h (__sso_string_base<>::_M_data(_CharT*):
|
||||
Likewise.
|
||||
|
||||
2005-11-17 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* config/os/bsd/darwin/ppc-extra.ver: New.
|
||||
|
@ -364,6 +364,26 @@ namespace std
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// A stripped-down version of std::tr1::is_empty
|
||||
//
|
||||
template<typename _Tp>
|
||||
struct __is_empty
|
||||
{
|
||||
private:
|
||||
template<typename>
|
||||
struct __first { };
|
||||
template<typename _Up>
|
||||
struct __second
|
||||
: public _Up { };
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
__value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif //_CPP_TYPE_TRAITS_H
|
||||
|
@ -92,8 +92,8 @@ namespace __gnu_cxx
|
||||
typedef typename _Traits::char_type value_type;
|
||||
typedef _Alloc allocator_type;
|
||||
|
||||
typedef typename __vstring_utility<_CharT, _Traits, _Alloc>::
|
||||
_CharT_alloc_type _CharT_alloc_type;
|
||||
typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base;
|
||||
typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type;
|
||||
typedef typename _CharT_alloc_type::size_type size_type;
|
||||
|
||||
private:
|
||||
@ -107,16 +107,25 @@ namespace __gnu_cxx
|
||||
// -1: leaked, one reference, no ref-copies allowed, non-const.
|
||||
// 0: one reference, non-const.
|
||||
// n>0: n + 1 references, operations require a lock, const.
|
||||
// 4. All fields==0 is an empty string, given the extra storage
|
||||
// 4. All fields == 0 is an empty string, given the extra storage
|
||||
// beyond-the-end for a null terminator; thus, the shared
|
||||
// empty string representation needs no constructor.
|
||||
struct _Rep
|
||||
{
|
||||
size_type _M_length;
|
||||
size_type _M_capacity;
|
||||
_Atomic_word _M_refcount;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
size_type _M_length;
|
||||
size_type _M_capacity;
|
||||
_Atomic_word _M_refcount;
|
||||
} _M_info;
|
||||
|
||||
// Only for alignment purposes.
|
||||
_CharT _M_align;
|
||||
};
|
||||
|
||||
typedef typename _Alloc::template rebind<size_type>::other _Raw_alloc;
|
||||
typedef typename _Alloc::template rebind<_Rep>::other _Rep_alloc_type;
|
||||
|
||||
_CharT*
|
||||
_M_refdata() throw()
|
||||
@ -125,15 +134,15 @@ namespace __gnu_cxx
|
||||
_CharT*
|
||||
_M_refcopy() throw()
|
||||
{
|
||||
__atomic_add(&_M_refcount, 1);
|
||||
__atomic_add(&_M_info._M_refcount, 1);
|
||||
return _M_refdata();
|
||||
} // XXX MT
|
||||
|
||||
void
|
||||
_M_set_length(size_type __n)
|
||||
{
|
||||
_M_refcount = 0; // One reference.
|
||||
_M_length = __n;
|
||||
_M_info._M_refcount = 0; // One reference.
|
||||
_M_info._M_length = __n;
|
||||
// grrr. (per 21.3.4)
|
||||
// You cannot leave those LWG people alone for a second.
|
||||
traits_type::assign(_M_refdata()[__n], _CharT());
|
||||
@ -150,11 +159,14 @@ namespace __gnu_cxx
|
||||
_M_clone(const _Alloc&, size_type __res = 0);
|
||||
};
|
||||
|
||||
struct _Rep_empty : _Rep
|
||||
struct _Rep_empty
|
||||
: public _Rep
|
||||
{
|
||||
_CharT _M_terminal;
|
||||
_CharT _M_terminal;
|
||||
};
|
||||
|
||||
static _Rep_empty _S_empty_rep;
|
||||
|
||||
// The maximum number of individual char_type elements of an
|
||||
// individual string is determined by _S_max_size. This is the
|
||||
// value that will be returned by max_size(). (Whereas npos
|
||||
@ -169,28 +181,12 @@ namespace __gnu_cxx
|
||||
enum { _S_max_size = (((static_cast<size_type>(-1) - sizeof(_Rep))
|
||||
/ sizeof(_CharT)) - 1) / 4 };
|
||||
|
||||
// Use empty-base optimization: http://www.cantrip.org/emptyopt.html
|
||||
struct _Alloc_hider : _Alloc
|
||||
{
|
||||
_Alloc_hider(_CharT* __dat, const _Alloc& __a)
|
||||
: _Alloc(__a), _M_p(__dat) { }
|
||||
|
||||
_CharT* _M_p; // The actual data.
|
||||
};
|
||||
|
||||
// Data Member (private):
|
||||
mutable _Alloc_hider _M_dataplus;
|
||||
mutable typename _Util_Base::template _Alloc_hider<_Alloc> _M_dataplus;
|
||||
|
||||
static _Rep_empty&
|
||||
_S_empty_rep()
|
||||
{
|
||||
static _Rep_empty _Empty_rep;
|
||||
return _Empty_rep;
|
||||
}
|
||||
|
||||
_CharT*
|
||||
void
|
||||
_M_data(_CharT* __p)
|
||||
{ return (_M_dataplus._M_p = __p); }
|
||||
{ _M_dataplus._M_p = __p; }
|
||||
|
||||
_Rep*
|
||||
_M_rep() const
|
||||
@ -206,15 +202,23 @@ namespace __gnu_cxx
|
||||
void
|
||||
_M_dispose(const _Alloc& __a)
|
||||
{
|
||||
if (__exchange_and_add(&_M_rep()->_M_refcount, -1) <= 0)
|
||||
if (__exchange_and_add(&_M_rep()->_M_info._M_refcount, -1) <= 0)
|
||||
_M_rep()->_M_destroy(__a);
|
||||
} // XXX MT
|
||||
|
||||
bool
|
||||
_M_is_leaked() const
|
||||
{ return _M_rep()->_M_info._M_refcount < 0; }
|
||||
|
||||
void
|
||||
_M_set_sharable()
|
||||
{ _M_rep()->_M_info._M_refcount = 0; }
|
||||
|
||||
void
|
||||
_M_leak_hard();
|
||||
|
||||
// _S_construct_aux is used to implement the 21.3.1 para 15 which
|
||||
// requires special behaviour if _InIter is an integral type
|
||||
// requires special behaviour if _InIterator is an integral type
|
||||
template<class _InIterator>
|
||||
static _CharT*
|
||||
_S_construct_aux(_InIterator __beg, _InIterator __end,
|
||||
@ -266,31 +270,19 @@ namespace __gnu_cxx
|
||||
|
||||
size_type
|
||||
_M_length() const
|
||||
{ return _M_rep()->_M_length; }
|
||||
{ return _M_rep()->_M_info._M_length; }
|
||||
|
||||
size_type
|
||||
_M_capacity() const
|
||||
{ return _M_rep()->_M_capacity; }
|
||||
{ return _M_rep()->_M_info._M_capacity; }
|
||||
|
||||
bool
|
||||
_M_is_shared() const
|
||||
{ return _M_rep()->_M_refcount > 0; }
|
||||
|
||||
bool
|
||||
_M_is_leaked() const
|
||||
{ return _M_rep()->_M_refcount < 0; }
|
||||
|
||||
void
|
||||
_M_set_sharable()
|
||||
{ _M_rep()->_M_refcount = 0; }
|
||||
{ return _M_rep()->_M_info._M_refcount > 0; }
|
||||
|
||||
void
|
||||
_M_set_leaked()
|
||||
{ _M_rep()->_M_refcount = -1; }
|
||||
|
||||
void
|
||||
_M_set_length(size_type __n)
|
||||
{ _M_rep()->_M_set_length(__n); }
|
||||
{ _M_rep()->_M_info._M_refcount = -1; }
|
||||
|
||||
void
|
||||
_M_leak() // for use in begin() & non-const op[]
|
||||
@ -299,8 +291,12 @@ namespace __gnu_cxx
|
||||
_M_leak_hard();
|
||||
}
|
||||
|
||||
void
|
||||
_M_set_length(size_type __n)
|
||||
{ _M_rep()->_M_set_length(__n); }
|
||||
|
||||
__rc_string_base()
|
||||
: _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
|
||||
: _M_dataplus(_Alloc(), _S_empty_rep._M_refcopy()) { }
|
||||
|
||||
__rc_string_base(const _Alloc& __a);
|
||||
|
||||
@ -310,7 +306,7 @@ namespace __gnu_cxx
|
||||
|
||||
template<typename _InputIterator>
|
||||
__rc_string_base(_InputIterator __beg, _InputIterator __end,
|
||||
const _Alloc& __a);
|
||||
const _Alloc& __a);
|
||||
|
||||
~__rc_string_base()
|
||||
{ _M_dispose(_M_get_allocator()); }
|
||||
@ -320,12 +316,7 @@ namespace __gnu_cxx
|
||||
{ return _M_dataplus; }
|
||||
|
||||
void
|
||||
_M_swap(__rc_string_base& __rcs)
|
||||
{
|
||||
_CharT* __tmp = _M_data();
|
||||
_M_data(__rcs._M_data());
|
||||
__rcs._M_data(__tmp);
|
||||
}
|
||||
_M_swap(__rc_string_base& __rcs);
|
||||
|
||||
void
|
||||
_M_assign(const __rc_string_base& __rcs);
|
||||
@ -337,6 +328,10 @@ namespace __gnu_cxx
|
||||
_M_mutate(size_type __pos, size_type __len1, size_type __len2);
|
||||
};
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep_empty
|
||||
__rc_string_base<_CharT, _Traits, _Alloc>::_S_empty_rep;
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep*
|
||||
__rc_string_base<_CharT, _Traits, _Alloc>::_Rep::
|
||||
@ -388,8 +383,8 @@ namespace __gnu_cxx
|
||||
// plus sizeof(size_type) - 1 to upper round to a size multiple
|
||||
// of sizeof(size_type).
|
||||
// Whew. Seemingly so needy, yet so elemental.
|
||||
size_type __size = ((__capacity + 1) * sizeof(_CharT) + sizeof(_Rep)
|
||||
+ sizeof(size_type) - 1);
|
||||
size_type __size = ((__capacity + 1) * sizeof(_CharT)
|
||||
+ 2 * sizeof(_Rep) - 1);
|
||||
|
||||
const size_type __adj_size = __size + __malloc_header_size;
|
||||
if (__adj_size > __pagesize && __capacity > __old_capacity)
|
||||
@ -399,16 +394,14 @@ namespace __gnu_cxx
|
||||
// Never allocate a string bigger than _S_max_size.
|
||||
if (__capacity > size_type(_S_max_size))
|
||||
__capacity = size_type(_S_max_size);
|
||||
__size = ((__capacity + 1) * sizeof(_CharT) + sizeof(_Rep)
|
||||
+ sizeof(size_type) - 1);
|
||||
__size = (__capacity + 1) * sizeof(_CharT) + 2 * sizeof(_Rep) - 1;
|
||||
}
|
||||
|
||||
// NB: Might throw, but no worries about a leak, mate: _Rep()
|
||||
// does not throw.
|
||||
void* __place = _Raw_alloc(__alloc).allocate(__size
|
||||
/ sizeof(size_type));
|
||||
_Rep *__p = new (__place) _Rep;
|
||||
__p->_M_capacity = __capacity;
|
||||
_Rep* __place = _Rep_alloc_type(__alloc).allocate(__size / sizeof(_Rep));
|
||||
_Rep* __p = new (__place) _Rep;
|
||||
__p->_M_info._M_capacity = __capacity;
|
||||
return __p;
|
||||
}
|
||||
|
||||
@ -417,10 +410,9 @@ namespace __gnu_cxx
|
||||
__rc_string_base<_CharT, _Traits, _Alloc>::_Rep::
|
||||
_M_destroy(const _Alloc& __a) throw ()
|
||||
{
|
||||
const size_type __size = ((_M_capacity + 1) * sizeof(_CharT)
|
||||
+ sizeof(_Rep) + sizeof(size_type) - 1);
|
||||
_Raw_alloc(__a).deallocate(reinterpret_cast<size_type*>(this),
|
||||
__size / sizeof(size_type));
|
||||
const size_type __size = ((_M_info._M_capacity + 1) * sizeof(_CharT)
|
||||
+ 2 * sizeof(_Rep) - 1);
|
||||
_Rep_alloc_type(__a).deallocate(this, __size / sizeof(_Rep));
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
@ -429,41 +421,40 @@ namespace __gnu_cxx
|
||||
_M_clone(const _Alloc& __alloc, size_type __res)
|
||||
{
|
||||
// Requested capacity of the clone.
|
||||
const size_type __requested_cap = _M_length + __res;
|
||||
_Rep* __r = _Rep::_S_create(__requested_cap, _M_capacity, __alloc);
|
||||
const size_type __requested_cap = _M_info._M_length + __res;
|
||||
_Rep* __r = _Rep::_S_create(__requested_cap, _M_info._M_capacity,
|
||||
__alloc);
|
||||
|
||||
if (_M_length)
|
||||
_S_copy(__r->_M_refdata(), _M_refdata(), _M_length);
|
||||
if (_M_info._M_length)
|
||||
_S_copy(__r->_M_refdata(), _M_refdata(), _M_info._M_length);
|
||||
|
||||
__r->_M_set_length(_M_length);
|
||||
__r->_M_set_length(_M_info._M_length);
|
||||
return __r->_M_refdata();
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
__rc_string_base<_CharT, _Traits, _Alloc>::
|
||||
__rc_string_base(const _Alloc& __a)
|
||||
: _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) { }
|
||||
: _M_dataplus(__a, _S_construct(size_type(), _CharT(), __a)) { }
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
__rc_string_base<_CharT, _Traits, _Alloc>::
|
||||
__rc_string_base(const __rc_string_base& __rcs)
|
||||
: _M_dataplus(__rcs._M_grab(_Alloc(__rcs._M_get_allocator()),
|
||||
__rcs._M_get_allocator()),
|
||||
__rcs._M_get_allocator()) { }
|
||||
: _M_dataplus(__rcs._M_get_allocator(),
|
||||
__rcs._M_grab(_Alloc(__rcs._M_get_allocator()),
|
||||
__rcs._M_get_allocator())) { }
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
__rc_string_base<_CharT, _Traits, _Alloc>::
|
||||
__rc_string_base(size_type __n, _CharT __c, const _Alloc& __a)
|
||||
: _M_dataplus(_S_construct(__n, __c, __a), __a)
|
||||
{ }
|
||||
: _M_dataplus(__a, _S_construct(__n, __c, __a)) { }
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
template<typename _InputIterator>
|
||||
__rc_string_base<_CharT, _Traits, _Alloc>::
|
||||
__rc_string_base(_InputIterator __beg, _InputIterator __end,
|
||||
const _Alloc& __a)
|
||||
: _M_dataplus(_S_construct(__beg, __end, __a), __a)
|
||||
{ }
|
||||
: _M_dataplus(__a, _S_construct(__beg, __end, __a)) { }
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
void
|
||||
@ -487,7 +478,7 @@ namespace __gnu_cxx
|
||||
std::input_iterator_tag)
|
||||
{
|
||||
if (__beg == __end && __a == _Alloc())
|
||||
return _S_empty_rep()._M_refcopy();
|
||||
return _S_empty_rep._M_refcopy();
|
||||
|
||||
// Avoid reallocation for common case.
|
||||
_CharT __buf[128];
|
||||
@ -532,10 +523,10 @@ namespace __gnu_cxx
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
if (__beg == __end && __a == _Alloc())
|
||||
return _S_empty_rep()._M_refcopy();
|
||||
return _S_empty_rep._M_refcopy();
|
||||
|
||||
// NB: Not required, but considered best practice.
|
||||
if (__builtin_expect(__is_null_p(__beg) && __beg != __end, 0))
|
||||
if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0))
|
||||
std::__throw_logic_error(__N("__rc_string_base::"
|
||||
"_S_construct NULL not valid"));
|
||||
|
||||
@ -560,7 +551,7 @@ namespace __gnu_cxx
|
||||
_S_construct(size_type __n, _CharT __c, const _Alloc& __a)
|
||||
{
|
||||
if (__n == 0 && __a == _Alloc())
|
||||
return _S_empty_rep()._M_refcopy();
|
||||
return _S_empty_rep._M_refcopy();
|
||||
|
||||
// Check for out_of_range and length_error exceptions.
|
||||
_Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
|
||||
@ -571,6 +562,24 @@ namespace __gnu_cxx
|
||||
return __r->_M_refdata();
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
void
|
||||
__rc_string_base<_CharT, _Traits, _Alloc>::
|
||||
_M_swap(__rc_string_base& __rcs)
|
||||
{
|
||||
if (_M_is_leaked())
|
||||
_M_set_sharable();
|
||||
if (__rcs._M_is_leaked())
|
||||
__rcs._M_set_sharable();
|
||||
|
||||
_CharT* __tmp = _M_data();
|
||||
_M_data(__rcs._M_data());
|
||||
__rcs._M_data(__tmp);
|
||||
|
||||
// NB: Implement Option 3 of DR 431 (see N1599).
|
||||
_M_dataplus._M_alloc_swap(__rcs._M_dataplus);
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
void
|
||||
__rc_string_base<_CharT, _Traits, _Alloc>::
|
||||
|
@ -47,8 +47,8 @@ namespace __gnu_cxx
|
||||
typedef typename _Traits::char_type value_type;
|
||||
typedef _Alloc allocator_type;
|
||||
|
||||
typedef typename __vstring_utility<_CharT, _Traits, _Alloc>::
|
||||
_CharT_alloc_type _CharT_alloc_type;
|
||||
typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base;
|
||||
typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type;
|
||||
typedef typename _CharT_alloc_type::size_type size_type;
|
||||
|
||||
private:
|
||||
@ -66,18 +66,9 @@ namespace __gnu_cxx
|
||||
enum { _S_max_size = (((static_cast<size_type>(-1)
|
||||
/ sizeof(_CharT)) - 1) / 4) };
|
||||
|
||||
// Use empty-base optimization: http://www.cantrip.org/emptyopt.html
|
||||
struct _Alloc_hider : _Alloc
|
||||
{
|
||||
_Alloc_hider(const _Alloc& __a, _CharT* __ptr)
|
||||
: _Alloc(__a), _M_p(__ptr) { }
|
||||
|
||||
_CharT* _M_p; // The actual data.
|
||||
};
|
||||
|
||||
// Data Members (private):
|
||||
_Alloc_hider _M_dataplus;
|
||||
size_type _M_string_length;
|
||||
typename _Util_Base::template _Alloc_hider<_Alloc> _M_dataplus;
|
||||
size_type _M_string_length;
|
||||
|
||||
enum { _S_local_capacity = 15 };
|
||||
|
||||
@ -87,9 +78,9 @@ namespace __gnu_cxx
|
||||
size_type _M_allocated_capacity;
|
||||
};
|
||||
|
||||
_CharT*
|
||||
void
|
||||
_M_data(_CharT* __p)
|
||||
{ return (_M_dataplus._M_p = __p); }
|
||||
{ _M_dataplus._M_p = __p; }
|
||||
|
||||
void
|
||||
_M_length(size_type __length)
|
||||
@ -118,7 +109,7 @@ namespace __gnu_cxx
|
||||
_M_destroy(size_type) throw();
|
||||
|
||||
// _M_construct_aux is used to implement the 21.3.1 para 15 which
|
||||
// requires special behaviour if _InIter is an integral type
|
||||
// requires special behaviour if _InIterator is an integral type
|
||||
template<class _InIterator>
|
||||
void
|
||||
_M_construct_aux(_InIterator __beg, _InIterator __end, __false_type)
|
||||
@ -181,28 +172,19 @@ namespace __gnu_cxx
|
||||
_M_is_shared() const
|
||||
{ return false; }
|
||||
|
||||
bool
|
||||
_M_is_leaked() const
|
||||
{ return false; }
|
||||
|
||||
void
|
||||
_M_set_sharable() { }
|
||||
|
||||
void
|
||||
_M_set_leaked() { }
|
||||
|
||||
void
|
||||
_M_leak() { }
|
||||
|
||||
void
|
||||
_M_set_length(size_type __n)
|
||||
{
|
||||
_M_length(__n);
|
||||
// grrr. (per 21.3.4)
|
||||
// You cannot leave those LWG people alone for a second.
|
||||
traits_type::assign(_M_data()[__n], _CharT());
|
||||
}
|
||||
|
||||
void
|
||||
_M_leak() { }
|
||||
|
||||
__sso_string_base()
|
||||
: _M_dataplus(_Alloc(), _M_local_data)
|
||||
{ _M_set_length(0); }
|
||||
@ -248,6 +230,9 @@ namespace __gnu_cxx
|
||||
__sso_string_base<_CharT, _Traits, _Alloc>::
|
||||
_M_swap(__sso_string_base& __rcs)
|
||||
{
|
||||
// NB: Implement Option 3 of DR 431 (see N1599).
|
||||
_M_dataplus._M_alloc_swap(__rcs._M_dataplus);
|
||||
|
||||
if (_M_is_local())
|
||||
if (__rcs._M_is_local())
|
||||
{
|
||||
@ -325,9 +310,6 @@ namespace __gnu_cxx
|
||||
// The below implements an exponential growth policy, necessary to
|
||||
// meet amortized linear time requirements of the library: see
|
||||
// http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
|
||||
// It's active for allocations requiring an amount of memory above
|
||||
// system pagesize. This is consistent with the requirements of the
|
||||
// standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
|
||||
if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
|
||||
__capacity = 2 * __old_capacity;
|
||||
|
||||
@ -373,7 +355,6 @@ namespace __gnu_cxx
|
||||
_M_construct(_InIterator __beg, _InIterator __end,
|
||||
std::input_iterator_tag)
|
||||
{
|
||||
// Avoid reallocation for common case.
|
||||
size_type __len = 0;
|
||||
size_type __capacity = size_type(_S_local_capacity);
|
||||
|
||||
@ -418,7 +399,7 @@ namespace __gnu_cxx
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
// NB: Not required, but considered best practice.
|
||||
if (__builtin_expect(__is_null_p(__beg) && __beg != __end, 0))
|
||||
if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0))
|
||||
std::__throw_logic_error(__N("__sso_string_base::"
|
||||
"_M_construct NULL not valid"));
|
||||
|
||||
|
@ -1214,7 +1214,8 @@ namespace __gnu_cxx
|
||||
* time.
|
||||
*/
|
||||
void
|
||||
swap(__versa_string& __s);
|
||||
swap(__versa_string& __s)
|
||||
{ this->_M_swap(__s); }
|
||||
|
||||
// String operations:
|
||||
/**
|
||||
|
@ -218,30 +218,6 @@ namespace __gnu_cxx
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc,
|
||||
template <typename, typename, typename> class _Base>
|
||||
void
|
||||
__versa_string<_CharT, _Traits, _Alloc, _Base>::
|
||||
swap(__versa_string& __s)
|
||||
{
|
||||
if (this->_M_is_leaked())
|
||||
this->_M_set_sharable();
|
||||
if (__s._M_is_leaked())
|
||||
__s._M_set_sharable();
|
||||
if (this->get_allocator() == __s.get_allocator())
|
||||
this->_M_swap(__s);
|
||||
// The code below can usually be optimized away.
|
||||
else
|
||||
{
|
||||
const __versa_string __tmp1(_M_ibegin(), _M_iend(),
|
||||
__s.get_allocator());
|
||||
const __versa_string __tmp2(__s._M_ibegin(), __s._M_iend(),
|
||||
this->get_allocator());
|
||||
*this = __tmp2;
|
||||
__s = __tmp1;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc,
|
||||
template <typename, typename, typename> class _Base>
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Versatile string utilities -*- C++ -*-
|
||||
// Versatile string utility -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
//
|
||||
@ -47,16 +47,6 @@
|
||||
|
||||
namespace __gnu_cxx
|
||||
{
|
||||
template<typename _Type>
|
||||
inline bool
|
||||
__is_null_p(_Type* __ptr)
|
||||
{ return __ptr == 0; }
|
||||
|
||||
template<typename _Type>
|
||||
inline bool
|
||||
__is_null_p(_Type)
|
||||
{ return false; }
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
struct __vstring_utility
|
||||
{
|
||||
@ -92,6 +82,53 @@ namespace __gnu_cxx
|
||||
__rc_string_base> >
|
||||
__const_rc_iterator;
|
||||
|
||||
// NB: When the allocator is empty, deriving from it saves space
|
||||
// (http://www.cantrip.org/emptyopt.html). We do that anyway for
|
||||
// consistency.
|
||||
template<typename _Alloc1, bool = std::__is_empty<_Alloc1>::__value>
|
||||
struct _Alloc_hider
|
||||
: public _Alloc1
|
||||
{
|
||||
_Alloc_hider(const _Alloc1& __a, _CharT* __ptr)
|
||||
: _Alloc1(__a), _M_p(__ptr) { }
|
||||
|
||||
void
|
||||
_M_alloc_swap(_Alloc_hider& __ah)
|
||||
{
|
||||
// Implement Option 3 of DR 431 (see N1599).
|
||||
// Precondition: swappable allocators.
|
||||
_Alloc1& __this = static_cast<_Alloc1&>(*this);
|
||||
_Alloc1& __that = static_cast<_Alloc1&>(__ah);
|
||||
if (__this != __that)
|
||||
swap(__this, __that);
|
||||
}
|
||||
|
||||
_CharT* _M_p; // The actual data.
|
||||
};
|
||||
|
||||
template<typename _Alloc1>
|
||||
struct _Alloc_hider<_Alloc1, true>
|
||||
: public _Alloc1
|
||||
{
|
||||
_Alloc_hider(const _Alloc1& __a, _CharT* __ptr)
|
||||
: _Alloc1(__a), _M_p(__ptr) { }
|
||||
|
||||
void _M_alloc_swap(_Alloc_hider&) { }
|
||||
|
||||
_CharT* _M_p; // The actual data.
|
||||
};
|
||||
|
||||
// For use in _M_construct (_S_construct) forward_iterator_tag.
|
||||
template<typename _Type>
|
||||
static bool
|
||||
_S_is_null_pointer(_Type* __ptr)
|
||||
{ return __ptr == 0; }
|
||||
|
||||
template<typename _Type>
|
||||
static bool
|
||||
_S_is_null_pointer(_Type)
|
||||
{ return false; }
|
||||
|
||||
// When __n = 1 way faster than the general multichar
|
||||
// traits_type::copy/move/assign.
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user