From 473c22488bfa8420380f7d6660a60fb695d6dc08 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 18 Nov 2005 11:50:22 +0000 Subject: 2005-11-18 Paolo Carlini * 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@107176 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 40 ++++++ libstdc++-v3/include/bits/cpp_type_traits.h | 20 +++ libstdc++-v3/include/ext/rc_string_base.h | 181 +++++++++++++++------------- libstdc++-v3/include/ext/sso_string_base.h | 45 ++----- libstdc++-v3/include/ext/vstring.h | 3 +- libstdc++-v3/include/ext/vstring.tcc | 24 ---- libstdc++-v3/include/ext/vstring_util.h | 59 +++++++-- 7 files changed, 218 insertions(+), 154 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f6ddc196f86..9b6a0b0a3e0 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,43 @@ +2005-11-18 Paolo Carlini + + * 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 * config/os/bsd/darwin/ppc-extra.ver: New. diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h index f02caab0311..5ac9c98e704 100644 --- a/libstdc++-v3/include/bits/cpp_type_traits.h +++ b/libstdc++-v3/include/bits/cpp_type_traits.h @@ -364,6 +364,26 @@ namespace std }; }; + // + // A stripped-down version of std::tr1::is_empty + // + template + struct __is_empty + { + private: + template + struct __first { }; + template + struct __second + : public _Up { }; + + public: + enum + { + __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>) + }; + }; + } // namespace std #endif //_CPP_TYPE_TRAITS_H diff --git a/libstdc++-v3/include/ext/rc_string_base.h b/libstdc++-v3/include/ext/rc_string_base.h index e462680eddf..58994222eae 100644 --- a/libstdc++-v3/include/ext/rc_string_base.h +++ b/libstdc++-v3/include/ext/rc_string_base.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::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(-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; - - static _Rep_empty& - _S_empty_rep() - { - static _Rep_empty _Empty_rep; - return _Empty_rep; - } + mutable typename _Util_Base::template _Alloc_hider<_Alloc> _M_dataplus; - _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 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 __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 __rc_string_base<_CharT, _Traits, _Alloc>::_Rep_empty + __rc_string_base<_CharT, _Traits, _Alloc>::_S_empty_rep; + template 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(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 @@ -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 __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 __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 __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 template __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 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 + 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 void __rc_string_base<_CharT, _Traits, _Alloc>:: diff --git a/libstdc++-v3/include/ext/sso_string_base.h b/libstdc++-v3/include/ext/sso_string_base.h index c37bd88ca5a..bd29413eb83 100644 --- a/libstdc++-v3/include/ext/sso_string_base.h +++ b/libstdc++-v3/include/ext/sso_string_base.h @@ -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(-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 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() { } + _M_set_leaked() { } void - _M_set_leaked() { } + _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")); diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h index a7741949f64..1aaa87665e7 100644 --- a/libstdc++-v3/include/ext/vstring.h +++ b/libstdc++-v3/include/ext/vstring.h @@ -1214,7 +1214,8 @@ namespace __gnu_cxx * time. */ void - swap(__versa_string& __s); + swap(__versa_string& __s) + { this->_M_swap(__s); } // String operations: /** diff --git a/libstdc++-v3/include/ext/vstring.tcc b/libstdc++-v3/include/ext/vstring.tcc index b8d35e3aceb..76fa96bcbd3 100644 --- a/libstdc++-v3/include/ext/vstring.tcc +++ b/libstdc++-v3/include/ext/vstring.tcc @@ -218,30 +218,6 @@ namespace __gnu_cxx } } - template 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 class _Base> void diff --git a/libstdc++-v3/include/ext/vstring_util.h b/libstdc++-v3/include/ext/vstring_util.h index 38c7c10976a..2a53fbdd4bd 100644 --- a/libstdc++-v3/include/ext/vstring_util.h +++ b/libstdc++-v3/include/ext/vstring_util.h @@ -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 - inline bool - __is_null_p(_Type* __ptr) - { return __ptr == 0; } - - template - inline bool - __is_null_p(_Type) - { return false; } - template 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::__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 + 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 + static bool + _S_is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template + 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 -- cgit v1.2.3