// Components for manipulating sequences of characters -*- C++ -*-
// Copyright (C) 1997-2019 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/basic_string.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{string}
*/
//
// ISO C++ 14882: 21 Strings library
//
#ifndef _BASIC_STRING_H
#define _BASIC_STRING_H 1
#pragma GCC system_header
#include <ext/atomicity.h>
#include <ext/alloc_traits.h>
#include <debug/debug.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif
#if __cplusplus >= 201703L
# include <string_view>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if _GLIBCXX_USE_CXX11_ABI
_GLIBCXX_BEGIN_NAMESPACE_CXX11
/**
* @class basic_string basic_string.h <string>
* @brief Managing sequences of characters and character-like objects.
*
* @ingroup strings
* @ingroup sequences
*
* @tparam _CharT Type of character
* @tparam _Traits Traits for character type, defaults to
* char_traits<_CharT>.
* @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
*
* Meets the requirements of a <a href="tables.html#65">container</a>, a
* <a href="tables.html#66">reversible container</a>, and a
* <a href="tables.html#67">sequence</a>. Of the
* <a href="tables.html#68">optional sequence requirements</a>, only
* @c push_back, @c at, and @c %array access are supported.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string
{
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
rebind<_CharT>::other _Char_alloc_type;
typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
// Types:
public:
typedef _Traits traits_type;
typedef typename _Traits::char_type value_type;
typedef _Char_alloc_type allocator_type;
typedef typename _Alloc_traits::size_type size_type;
typedef typename _Alloc_traits::difference_type difference_type;
typedef typename _Alloc_traits::reference reference;
typedef typename _Alloc_traits::const_reference const_reference;
typedef typename _Alloc_traits::pointer pointer;
typedef typename _Alloc_traits::const_pointer const_pointer;
typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
/// Value returned by various member functions when they fail.
static const size_type npos = static_cast<size_type>(-1);
protected:
// type used for positions in insert, erase etc.
#if __cplusplus < 201103L
typedef iterator __const_iterator;
#else
typedef const_iterator __const_iterator;
#endif
private:
#if __cplusplus >= 201703L
// A helper type for avoiding boiler-plate.
typedef basic_string_view<_CharT, _Traits> __sv_type;
template<typename _Tp, typename _Res>
using _If_sv = enable_if_t<
__and_<is_convertible<const _Tp&, __sv_type>,
__not_<is_convertible<const _Tp*, const basic_string*>>,
__not_<is_convertible<const _Tp&, const _CharT*>>>::value,
_Res>;
// Allows an implicit conversion to __sv_type.
static __sv_type
_S_to_string_view(__sv_type __svt) noexcept
{ return __svt; }
// Wraps a string_view by explicit conversion and thus
// allows to add an internal constructor that does not
// participate in overload resolution when a string_view
// is provided.
struct __sv_wrapper
{
explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { }
__sv_type _M_sv;
};
/**
* @brief Only internally used: Construct string from a string view
* wrapper.
* @param __svw string view wrapper.
* @param __a Allocator to use.
*/
explicit
basic_string(__sv_wrapper __svw, const _Alloc& __a)
: basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { }
#endif
// Use empty-base optimization: http://www.cantrip.org/emptyopt.html
struct _Alloc_hider : allocator_type // TODO check __is_final
{
#if __cplusplus < 201103L
_Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc())
: allocator_type(__a), _M_p(__dat) { }
#else
_Alloc_hider(pointer __dat, const _Alloc& __a)
: allocator_type(__a), _M_p(__dat) { }
_Alloc_hider(pointer __dat, _Alloc&& __a = _Alloc())
: allocator_type(std::move(__a)), _M_p(__dat) { }
#endif
pointer _M_p; // The actual data.
};
_Alloc_hider _M_dataplus;
size_type _M_string_length;
enum { _S_local_capacity = 15 / sizeof(_CharT) };
union
{
_CharT _M_local_buf[_S_local_capacity + 1];
size_type _M_allocated_capacity;
};
void
_M_data(pointer __p)
{ _M_dataplus._M_p = __p; }
void
_M_length(size_type __length)
{ _M_string_length = __length; }
pointer
_M_data() const
{ return _M_dataplus._M_p; }
pointer
_M_local_data()
{
#if __cplusplus >= 201103L
return std::pointer_traits<pointer>::pointer_to(*_M_local_buf);
#else
return pointer(_M_local_buf);
#endif
}
const_pointer
_M_local_data() const
{
#if __cplusplus >= 201103L
return std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf);
#else
return const_pointer(_M_local_buf);
#endif
}
void
_M_capacity(size_type __capacity)
{ _M_allocated_capacity = __capacity; }
void
_M_set_length(size_type __n)
{
_M_length(__n);
traits_type::assign(_M_data()[__n], _CharT());
}
bool
_M_is_local() const
{ return _M_data() == _M_local_data(); }
// Create & Destroy
pointer
_M_create(size_type&, size_type);
void
_M_dispose()
{
if (!_M_is_local())
_M_destroy(_M_allocated_capacity);
}
void
_M_destroy(size_type __size) throw()
{ _Alloc_traits::deallocate(_M_get_allocator(), _M_data(), __size + 1); }
// _M_construct_aux is used to implement the 21.3.1 para 15 which
// requires special behaviour if _InIterator is an integral type
template<typename _InIterator>
void
_M_construct_aux(_InIterator __beg, _InIterator __end,
std::__false_type)
{
typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
_M_construct(__beg, __end, _Tag());
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause
template<typename _Integer>
void
_M_construct_aux(_Integer __beg, _Integer __end, std::__true_type)
{ _M_construct_aux_2(static_cast<size_type>(__beg), __end); }
void
_M_construct_aux_2(size_type