summaryrefslogtreecommitdiff
path: root/include/string
diff options
context:
space:
mode:
Diffstat (limited to 'include/string')
-rw-r--r--include/string170
1 files changed, 106 insertions, 64 deletions
diff --git a/include/string b/include/string
index ba311efa5a31..1bc91ed12492 100644
--- a/include/string
+++ b/include/string
@@ -637,7 +637,7 @@ public:
typedef basic_string __self;
typedef basic_string_view<_CharT, _Traits> __self_view;
typedef _Traits traits_type;
- typedef typename traits_type::char_type value_type;
+ typedef _CharT value_type;
typedef _Allocator allocator_type;
typedef allocator_traits<allocator_type> __alloc_traits;
typedef typename __alloc_traits::size_type size_type;
@@ -648,7 +648,7 @@ public:
typedef typename __alloc_traits::const_pointer const_pointer;
static_assert(is_pod<value_type>::value, "Character type of basic_string must be a POD");
- static_assert((is_same<_CharT, value_type>::value),
+ static_assert((is_same<_CharT, typename traits_type::char_type>::value),
"traits_type::char_type must be the same type as CharT");
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
@@ -775,30 +775,31 @@ public:
_LIBCPP_INLINE_VISIBILITY
basic_string(basic_string&& __str, const allocator_type& __a);
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s);
+ _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s);
_LIBCPP_INLINE_VISIBILITY
- basic_string(const value_type* __s, const allocator_type& __a);
+ basic_string(const _CharT* __s, const _Allocator& __a);
_LIBCPP_INLINE_VISIBILITY
- basic_string(const value_type* __s, size_type __n);
+ basic_string(const _CharT* __s, size_type __n);
_LIBCPP_INLINE_VISIBILITY
- basic_string(const value_type* __s, size_type __n, const allocator_type& __a);
+ basic_string(const _CharT* __s, size_type __n, const _Allocator& __a);
_LIBCPP_INLINE_VISIBILITY
- basic_string(size_type __n, value_type __c);
+ basic_string(size_type __n, _CharT __c);
_LIBCPP_INLINE_VISIBILITY
- basic_string(size_type __n, value_type __c, const allocator_type& __a);
+ basic_string(size_type __n, _CharT __c, const _Allocator& __a);
basic_string(const basic_string& __str, size_type __pos, size_type __n,
- const allocator_type& __a = allocator_type());
+ const _Allocator& __a = _Allocator());
_LIBCPP_INLINE_VISIBILITY
basic_string(const basic_string& __str, size_type __pos,
- const allocator_type& __a = allocator_type());
+ const _Allocator& __a = _Allocator());
template<class _Tp>
- basic_string(const _Tp& __t, size_type __pos, size_type __n,
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ basic_string(const _Tp& __t, size_type __pos, size_type __n,
const allocator_type& __a = allocator_type(),
typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0);
_LIBCPP_INLINE_VISIBILITY explicit
basic_string(__self_view __sv);
_LIBCPP_INLINE_VISIBILITY
- basic_string(__self_view __sv, const allocator_type& __a);
+ basic_string(__self_view __sv, const _Allocator& __a);
template<class _InputIterator>
_LIBCPP_INLINE_VISIBILITY
basic_string(_InputIterator __first, _InputIterator __last);
@@ -807,9 +808,9 @@ public:
basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
_LIBCPP_INLINE_VISIBILITY
- basic_string(initializer_list<value_type> __il);
+ basic_string(initializer_list<_CharT> __il);
_LIBCPP_INLINE_VISIBILITY
- basic_string(initializer_list<value_type> __il, const allocator_type& __a);
+ basic_string(initializer_list<_CharT> __il, const _Allocator& __a);
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
inline ~basic_string();
@@ -927,7 +928,8 @@ public:
basic_string& append(__self_view __sv) { return append(__sv.data(), __sv.size()); }
basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
template <class _Tp>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
@@ -937,9 +939,11 @@ public:
basic_string& append(const value_type* __s);
basic_string& append(size_type __n, value_type __c);
template <class _ForwardIterator>
- inline basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator);
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator);
template<class _InputIterator>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__is_exactly_input_iterator<_InputIterator>::value
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
@@ -952,7 +956,8 @@ public:
return *this;
}
template<class _ForwardIterator>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__is_forward_iterator<_ForwardIterator>::value
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
@@ -988,7 +993,8 @@ public:
#endif
basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
template <class _Tp>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
@@ -998,7 +1004,8 @@ public:
basic_string& assign(const value_type* __s);
basic_string& assign(size_type __n, value_type __c);
template<class _InputIterator>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__is_exactly_input_iterator<_InputIterator>::value
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
@@ -1006,7 +1013,8 @@ public:
>::type
assign(_InputIterator __first, _InputIterator __last);
template<class _ForwardIterator>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__is_forward_iterator<_ForwardIterator>::value
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
@@ -1023,7 +1031,8 @@ public:
_LIBCPP_INLINE_VISIBILITY
basic_string& insert(size_type __pos1, __self_view __sv) { return insert(__pos1, __sv.data(), __sv.size()); }
template <class _Tp>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
@@ -1037,7 +1046,8 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __pos, size_type __n, value_type __c);
template<class _InputIterator>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__is_exactly_input_iterator<_InputIterator>::value
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
@@ -1045,7 +1055,8 @@ public:
>::type
insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
template<class _ForwardIterator>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__is_forward_iterator<_ForwardIterator>::value
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
@@ -1070,7 +1081,8 @@ public:
basic_string& replace(size_type __pos1, size_type __n1, __self_view __sv) { return replace(__pos1, __n1, __sv.data(), __sv.size()); }
basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
template <class _Tp>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
@@ -1090,7 +1102,8 @@ public:
_LIBCPP_INLINE_VISIBILITY
basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
template<class _InputIterator>
- typename enable_if
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ typename enable_if
<
__is_input_iterator<_InputIterator>::value,
basic_string&
@@ -1325,15 +1338,15 @@ private:
__align_it<sizeof(value_type) < __alignment ?
__alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline
void __init(const value_type* __s, size_type __sz, size_type __reserve);
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline
void __init(const value_type* __s, size_type __sz);
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline
void __init(size_type __n, value_type __c);
template <class _InputIterator>
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline
typename enable_if
<
__is_exactly_input_iterator<_InputIterator>::value,
@@ -1342,7 +1355,7 @@ private:
__init(_InputIterator __first, _InputIterator __last);
template <class _ForwardIterator>
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline
typename enable_if
<
__is_forward_iterator<_ForwardIterator>::value,
@@ -1367,12 +1380,28 @@ private:
_LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const basic_string& __str, true_type)
{
- if (__alloc() != __str.__alloc())
+ if (__alloc() == __str.__alloc())
+ __alloc() = __str.__alloc();
+ else
{
- clear();
- shrink_to_fit();
+ if (!__str.__is_long())
+ {
+ clear();
+ shrink_to_fit();
+ __alloc() = __str.__alloc();
+ }
+ else
+ {
+ allocator_type __a = __str.__alloc();
+ pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap());
+ clear();
+ shrink_to_fit();
+ __alloc() = _VSTD::move(__a);
+ __set_long_pointer(__p);
+ __set_long_cap(__str.__get_long_cap());
+ __set_long_size(__str.size());
+ }
}
- __alloc() = __str.__alloc();
}
_LIBCPP_INLINE_VISIBILITY
@@ -1482,7 +1511,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __
#else
_NOEXCEPT
#endif
-: __r_(__a)
+: __r_(__second_tag(), __a)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
@@ -1541,7 +1570,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s)
{
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
__init(__s, traits_type::length(__s));
@@ -1552,8 +1581,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
- : __r_(__a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
+ : __r_(__second_tag(), __a)
{
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
__init(__s, traits_type::length(__s));
@@ -1564,7 +1593,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, c
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n)
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
__init(__s, __n);
@@ -1575,8 +1604,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, s
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
- : __r_(__a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
+ : __r_(__second_tag(), __a)
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
__init(__s, __n);
@@ -1587,7 +1616,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, s
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
- : __r_(__alloc_traits::select_on_container_copy_construction(__str.__alloc()))
+ : __r_(__second_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
{
if (!__str.__is_long())
__r_.first().__r = __str.__r_.first().__r;
@@ -1599,8 +1628,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
}
template <class _CharT, class _Traits, class _Allocator>
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a)
- : __r_(__a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(
+ const basic_string& __str, const allocator_type& __a)
+ : __r_(__second_tag(), __a)
{
if (!__str.__is_long())
__r_.first().__r = __str.__r_.first().__r;
@@ -1634,7 +1664,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
- : __r_(__a)
+ : __r_(__second_tag(), __a)
{
if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
__init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
@@ -1678,7 +1708,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c)
{
__init(__n, __c);
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1688,8 +1718,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_typ
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)
- : __r_(__a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
+ : __r_(__second_tag(), __a)
{
__init(__n, __c);
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1698,9 +1728,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_typ
}
template <class _CharT, class _Traits, class _Allocator>
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n,
- const allocator_type& __a)
- : __r_(__a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
+ size_type __pos, size_type __n,
+ const _Allocator& __a)
+ : __r_(__second_tag(), __a)
{
size_type __str_sz = __str.size();
if (__pos > __str_sz)
@@ -1714,8 +1745,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
- const allocator_type& __a)
- : __r_(__a)
+ const _Allocator& __a)
+ : __r_(__second_tag(), __a)
{
size_type __str_sz = __str.size();
if (__pos > __str_sz)
@@ -1731,13 +1762,13 @@ template <class _Tp>
basic_string<_CharT, _Traits, _Allocator>::basic_string(
const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a,
typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type *)
- : __r_(__a)
+ : __r_(__second_tag(), __a)
{
__self_view __sv = __self_view(__t).substr(__pos, __n);
__init(__sv.data(), __sv.size());
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
-#endif
+#endif
}
template <class _CharT, class _Traits, class _Allocator>
@@ -1752,8 +1783,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv)
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const allocator_type& __a)
- : __r_(__a)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const _Allocator& __a)
+ : __r_(__second_tag(), __a)
{
__init(__sv.data(), __sv.size());
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1835,7 +1866,7 @@ template<class _InputIterator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
const allocator_type& __a)
- : __r_(__a)
+ : __r_(__second_tag(), __a)
{
__init(__first, __last);
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1847,7 +1878,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first,
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)
+basic_string<_CharT, _Traits, _Allocator>::basic_string(
+ initializer_list<_CharT> __il)
{
__init(__il.begin(), __il.end());
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1857,8 +1889,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_t
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)
- : __r_(__a)
+
+basic_string<_CharT, _Traits, _Allocator>::basic_string(
+ initializer_list<_CharT> __il, const _Allocator& __a)
+ : __r_(__second_tag(), __a)
{
__init(__il.begin(), __il.end());
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -2242,7 +2276,9 @@ basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe(
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
if (__n)
{
- if ( __ptr_in_range(&*__first, data(), data() + size()))
+ typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
+ _CharRef __tmp_ref = *__first;
+ if (__ptr_in_range(_VSTD::addressof(__tmp_ref), data(), data() + size()))
{
const basic_string __temp (__first, __last, __alloc());
append(__temp.data(), __temp.size());
@@ -2406,7 +2442,9 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
if (__n)
{
- if ( __ptr_in_range(&*__first, data(), data() + size()))
+ typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
+ _CharRef __tmp_char = *__first;
+ if (__ptr_in_range(_VSTD::addressof(__tmp_char), data(), data() + size()))
{
const basic_string __temp(__first, __last, __alloc());
return insert(__pos, __temp.data(), __temp.data() + __temp.size());
@@ -2526,6 +2564,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_typ
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
+ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
_LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
size_type __sz = size();
@@ -2565,6 +2604,8 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
}
traits_type::move(__p + __pos, __s, __n2);
__finish:
+// __sz += __n2 - __n1; in this and the below function below can cause unsigned integer overflow,
+// but this is a safe operation, so we disable the check.
__sz += __n2 - __n1;
__set_size(__sz);
__invalidate_iterators_past(__sz);
@@ -2578,6 +2619,7 @@ __finish:
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
+ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
size_type __sz = size();
if (__pos > __sz)