184865Sobrien// Versatile string utility -*- C++ -*- 284865Sobrien 384865Sobrien// Copyright (C) 2005-2022 Free Software Foundation, Inc. 484865Sobrien// 584865Sobrien// This file is part of the GNU ISO C++ Library. This library is free 684865Sobrien// software; you can redistribute it and/or modify it under the 784865Sobrien// terms of the GNU General Public License as published by the 884865Sobrien// Free Software Foundation; either version 3, or (at your option) 984865Sobrien// any later version. 1084865Sobrien 1184865Sobrien// This library is distributed in the hope that it will be useful, 1284865Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1384865Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1484865Sobrien// GNU General Public License for more details. 1584865Sobrien 1684865Sobrien// Under Section 7 of GPL version 3, you are granted additional 1784865Sobrien// permissions described in the GCC Runtime Library Exception, version 1884865Sobrien// 3.1, as published by the Free Software Foundation. 19218822Sdim 20218822Sdim// You should have received a copy of the GNU General Public License and 2184865Sobrien// a copy of the GCC Runtime Library Exception along with this program; 2284865Sobrien// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2384865Sobrien// <http://www.gnu.org/licenses/>. 2484865Sobrien 2584865Sobrien/** @file ext/vstring_util.h 2684865Sobrien * This is an internal header file, included by other library headers. 2784865Sobrien * Do not attempt to use it directly. @headername{ext/vstring.h} 2884865Sobrien */ 2984865Sobrien 3084865Sobrien#ifndef _VSTRING_UTIL_H 3184865Sobrien#define _VSTRING_UTIL_H 1 3284865Sobrien 3384865Sobrien#pragma GCC system_header 3484865Sobrien 3584865Sobrien#include <ext/vstring_fwd.h> 3684865Sobrien#include <debug/debug.h> 3784865Sobrien#include <bits/stl_function.h> // For less 3884865Sobrien#include <bits/functexcept.h> 3984865Sobrien#include <bits/localefwd.h> 4084865Sobrien#include <bits/ostream_insert.h> 4184865Sobrien#include <bits/stl_iterator.h> 4284865Sobrien#include <ext/numeric_traits.h> 4384865Sobrien#include <ext/alloc_traits.h> 4484865Sobrien#include <bits/move.h> 4584865Sobrien#include <bits/range_access.h> 4684865Sobrien 4784865Sobriennamespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 4884865Sobrien{ 4984865Sobrien_GLIBCXX_BEGIN_NAMESPACE_VERSION 5084865Sobrien 5184865Sobrien template<typename _CharT, typename _Traits, typename _Alloc> 5284865Sobrien struct __vstring_utility 5384865Sobrien { 5484865Sobrien typedef typename __alloc_traits<_Alloc>::template rebind<_CharT>::other 5584865Sobrien _CharT_alloc_type; 5684865Sobrien typedef __alloc_traits<_CharT_alloc_type> _CharT_alloc_traits; 5784865Sobrien 5884865Sobrien typedef _Traits traits_type; 5984865Sobrien typedef typename _Traits::char_type value_type; 6084865Sobrien typedef typename _CharT_alloc_type::size_type size_type; 6184865Sobrien typedef typename _CharT_alloc_type::difference_type difference_type; 6284865Sobrien typedef typename _CharT_alloc_traits::pointer pointer; 6384865Sobrien typedef typename _CharT_alloc_traits::const_pointer const_pointer; 6484865Sobrien 6584865Sobrien // For __sso_string. 6684865Sobrien typedef __gnu_cxx:: 6784865Sobrien __normal_iterator<pointer, __gnu_cxx:: 6884865Sobrien __versa_string<_CharT, _Traits, _Alloc, 6984865Sobrien __sso_string_base> > 7084865Sobrien __sso_iterator; 7184865Sobrien typedef __gnu_cxx:: 7284865Sobrien __normal_iterator<const_pointer, __gnu_cxx:: 7384865Sobrien __versa_string<_CharT, _Traits, _Alloc, 7484865Sobrien __sso_string_base> > 7584865Sobrien __const_sso_iterator; 7684865Sobrien 7784865Sobrien // For __rc_string. 7884865Sobrien typedef __gnu_cxx:: 7984865Sobrien __normal_iterator<pointer, __gnu_cxx:: 8084865Sobrien __versa_string<_CharT, _Traits, _Alloc, 8184865Sobrien __rc_string_base> > 8284865Sobrien __rc_iterator; 8384865Sobrien typedef __gnu_cxx:: 8484865Sobrien __normal_iterator<const_pointer, __gnu_cxx:: 8584865Sobrien __versa_string<_CharT, _Traits, _Alloc, 8684865Sobrien __rc_string_base> > 8784865Sobrien __const_rc_iterator; 8884865Sobrien 8984865Sobrien // NB: When the allocator is empty, deriving from it saves space 9084865Sobrien // (http://www.cantrip.org/emptyopt.html). 9184865Sobrien template<typename _Alloc1> 9284865Sobrien struct _Alloc_hider 9384865Sobrien : public _Alloc1 9484865Sobrien { 9584865Sobrien _Alloc_hider(_CharT* __ptr) 9684865Sobrien : _Alloc1(), _M_p(__ptr) { } 9784865Sobrien 9884865Sobrien _Alloc_hider(const _Alloc1& __a, _CharT* __ptr) 9984865Sobrien : _Alloc1(__a), _M_p(__ptr) { } 10084865Sobrien 10184865Sobrien _CharT* _M_p; // The actual data. 10284865Sobrien }; 10384865Sobrien 10484865Sobrien // When __n = 1 way faster than the general multichar 10584865Sobrien // traits_type::copy/move/assign. 10684865Sobrien static void 10784865Sobrien _S_copy(_CharT* __d, const _CharT* __s, size_type __n) 10884865Sobrien { 10984865Sobrien if (__n == 1) 11084865Sobrien traits_type::assign(*__d, *__s); 11184865Sobrien else 11284865Sobrien traits_type::copy(__d, __s, __n); 11384865Sobrien } 11484865Sobrien 11584865Sobrien static void 11684865Sobrien _S_move(_CharT* __d, const _CharT* __s, size_type __n) 11784865Sobrien { 11884865Sobrien if (__n == 1) 11984865Sobrien traits_type::assign(*__d, *__s); 12084865Sobrien else 12184865Sobrien traits_type::move(__d, __s, __n); 12284865Sobrien } 12384865Sobrien 12484865Sobrien static void 12584865Sobrien _S_assign(_CharT* __d, size_type __n, _CharT __c) 12684865Sobrien { 12784865Sobrien if (__n == 1) 12884865Sobrien traits_type::assign(*__d, __c); 12984865Sobrien else 13084865Sobrien traits_type::assign(__d, __n, __c); 13184865Sobrien } 13284865Sobrien 13384865Sobrien // _S_copy_chars is a separate template to permit specialization 13484865Sobrien // to optimize for the common case of pointers as iterators. 13584865Sobrien template<typename _Iterator> 13684865Sobrien static void 13784865Sobrien _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) 13884865Sobrien { 13984865Sobrien for (; __k1 != __k2; ++__k1, ++__p) 14084865Sobrien traits_type::assign(*__p, *__k1); // These types are off. 14184865Sobrien } 14284865Sobrien 14384865Sobrien static void 14484865Sobrien _S_copy_chars(_CharT* __p, __sso_iterator __k1, __sso_iterator __k2) 14584865Sobrien { _S_copy_chars(__p, __k1.base(), __k2.base()); } 14684865Sobrien 14784865Sobrien static void 14884865Sobrien _S_copy_chars(_CharT* __p, __const_sso_iterator __k1, 149 __const_sso_iterator __k2) 150 { _S_copy_chars(__p, __k1.base(), __k2.base()); } 151 152 static void 153 _S_copy_chars(_CharT* __p, __rc_iterator __k1, __rc_iterator __k2) 154 { _S_copy_chars(__p, __k1.base(), __k2.base()); } 155 156 static void 157 _S_copy_chars(_CharT* __p, __const_rc_iterator __k1, 158 __const_rc_iterator __k2) 159 { _S_copy_chars(__p, __k1.base(), __k2.base()); } 160 161 static void 162 _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) 163 { _S_copy(__p, __k1, __k2 - __k1); } 164 165 static void 166 _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) 167 { _S_copy(__p, __k1, __k2 - __k1); } 168 169 static int 170 _S_compare(size_type __n1, size_type __n2) 171 { 172 const difference_type __d = difference_type(__n1 - __n2); 173 174 if (__d > __numeric_traits_integer<int>::__max) 175 return __numeric_traits_integer<int>::__max; 176 else if (__d < __numeric_traits_integer<int>::__min) 177 return __numeric_traits_integer<int>::__min; 178 else 179 return int(__d); 180 } 181 }; 182 183_GLIBCXX_END_NAMESPACE_VERSION 184} // namespace 185 186#endif /* _VSTRING_UTIL_H */ 187