// Versatile string -*- C++ -*-
// Copyright (C) 2005, 2006, 2007, 2008, 2009 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 ext/vstring.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _VSTRING_H
#define _VSTRING_H 1
#pragma GCC system_header
#include <initializer_list>
#include <ext/vstring_util.h>
#include <ext/rc_string_base.h>
#include <ext/sso_string_base.h>
#if __google_stl_debug_string && !defined(_GLIBCXX_DEBUG)
# undef _GLIBCXX_DEBUG_ASSERT
# undef _GLIBCXX_DEBUG_PEDASSERT
// Perform additional checks (but only in this file).
# define _GLIBCXX_DEBUG_ASSERT(_Condition) \
if (! (_Condition)) { \
char buf[512]; \
__builtin_snprintf(buf, sizeof(buf), \
"%s:%d: %s: Assertion '%s' failed.\n", \
__FILE__, __LINE__, __func__, # _Condition); \
std::__throw_runtime_error(buf); \
}
# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) _GLIBCXX_DEBUG_ASSERT(_Condition)
#endif
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
/**
* @class __versa_string vstring.h
* @brief Managing sequences of characters and character-like objects.
*/
// Template class __versa_string
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
class __versa_string
: private _Base<_CharT, _Traits, _Alloc>
{
typedef _Base<_CharT, _Traits, _Alloc> __vstring_base;
typedef typename __vstring_base::_CharT_alloc_type _CharT_alloc_type;
// Types:
public:
typedef _Traits traits_type;
typedef typename _Traits::char_type value_type;
typedef _Alloc allocator_type;
typedef typename _CharT_alloc_type::size_type size_type;
typedef typename _CharT_alloc_type::difference_type difference_type;
typedef typename _CharT_alloc_type::reference reference;
typedef typename _CharT_alloc_type::const_reference const_reference;
typedef typename _CharT_alloc_type::pointer pointer;
typedef typename _CharT_alloc_type::const_pointer const_pointer;
typedef __gnu_cxx::__normal_iterator<pointer, __versa_string> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, __versa_string>
const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
// Data Member (public):
/// Value returned by various member functions when they fail.
static const size_type npos = static_cast<size_type>(-1);
private:
size_type
_M_check(size_type __pos, const char* __s) const
{
if (__pos > this->size())
std::__throw_out_of_range(__N(__s));
return __pos;
}
void
_M_check_length(size_type __n1, size_type __n2, const char* __s) const
{
if (this->max_size() - (this->size() - __n1) < __n2)
std::__throw_length_error(__N(__s));
}
// NB: _M_limit doesn't check for a bad __pos value.
size_type
_M_limit(size_type __pos, size_type __off) const
{
const bool __testoff = __off < this->size() - __pos;
return __testoff ? __off : this->size() - __pos;
}
// True if _Rep and source do not overlap.
bool
_M_disjunct(const _CharT* __s) const
{
return (std::less<const _CharT*>()(__s, this->_M_data())
|| std::less<const _CharT*>()(this->_M_data()
+ this->size(), __s));
}
// For the internal use we have functions similar to `begin'/`end'
// but they do not call _M_leak.
iterator
_M_ibegin() const
{ return iterator(this->_M_data()); }
iterator
_M_iend() const
{ return iterator(this->_M_data() + this->_M_length()); }
public:
// Construct/copy/destroy:
// NB: We overload ctors in some cases instead of using default
// arguments, per 17.4.4.4 para. 2 item 2.
/**
* @brief Default constructor creates an empty string.
*/
__versa_string()
: __vstring_base() { }
/**
* @brief Construct an empty string using allocator @a a.
*/
explicit
__versa_string(const _Alloc& __a)
: __vstring_base(__a) { }
// NB: per LWG issue 42, semantics different from IS:
/**
* @brief Construct string with copy of value of @a str.
* @param __str Source string.
*/
__versa_string(const __versa_string& __str)
: __vstring_base(__str) { }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* @brief String move constructor.
* @param __str Source string.
*
* The newly-constructed %string contains the exact contents of
* @a str. The contents of @a str are a valid, but unspecified
* string.
*/
__versa_string(__versa_string&& __str)
: __vstring_base(std::forward<__vstring_base>(__str)) { }
/**
* @brief Construct string from an initializer list.
* @param __l std::initializer_list of characters.
* @param __a Allocator to use (default is default allocator).
*/
__versa_string(std::initializer_list<_CharT> __l,
const _Alloc& __a = _Alloc())
: __vstring_base(__l.begin(), __l.end(), __a) { }
#endif
/**
* @brief Construct string as copy of a substring.
* @param __str Source string.
* @param __pos Index of first character to copy from.
* @param __n Number of characters to copy (default remainder).
*/
__versa_string(const __versa_string& __str, size_type __pos,
size_type __n = npos)
: __vstring_base(__str._M_data()
+ __str._M_check(__pos,
"__versa_string::__versa_string"),
__str._M_data() + __str._M_limit(__pos, __n)
+ __pos, _Alloc()) { }
/**
* @brief Construct string as copy of a substring.
* @param __str Source string.
* @param __pos Index of first character to copy from.
* @param __n Number of characters to copy.
* @param __a Allocator to use.
*/
__versa_string(const __versa_string& __str, size_type __pos,
size_type __n, const _Alloc& __a)
: __vstring_base(__str._M_data()
+ __str._M_check(__pos,
"__versa_string::__versa_string"),
__str._M_data() + __str._M_limit(__pos, __n)
+ __pos, __a) { }
/**
* @brief Construct string initialized by a character array.
* @param __s Source character array.
* @param __n Number of characters to copy.
* @param __a Allocator to use (default is default allocator).
*
* NB: @a __s must have at least @a __n characters, '\\0' has no special
* meaning.
*/
__versa_string(const _CharT* __s, size_type __n,
const _Alloc& __a = _Alloc())
: __vstring_base(__s, __s + __n,