1  // Versatile string utility -*- C++ -*-
       2  
       3  // Copyright (C) 2005-2023 Free Software Foundation, Inc.
       4  //
       5  // This file is part of the GNU ISO C++ Library.  This library is free
       6  // software; you can redistribute it and/or modify it under the
       7  // terms of the GNU General Public License as published by the
       8  // Free Software Foundation; either version 3, or (at your option)
       9  // any later version.
      10  
      11  // This library is distributed in the hope that it will be useful,
      12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  // GNU General Public License for more details.
      15  
      16  // Under Section 7 of GPL version 3, you are granted additional
      17  // permissions described in the GCC Runtime Library Exception, version
      18  // 3.1, as published by the Free Software Foundation.
      19  
      20  // You should have received a copy of the GNU General Public License and
      21  // a copy of the GCC Runtime Library Exception along with this program;
      22  // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  // <http://www.gnu.org/licenses/>.
      24  
      25  /** @file ext/vstring_util.h
      26   *  This is an internal header file, included by other library headers.
      27   *  Do not attempt to use it directly. @headername{ext/vstring.h}
      28   */
      29  
      30  #ifndef _VSTRING_UTIL_H
      31  #define _VSTRING_UTIL_H 1
      32  
      33  #pragma GCC system_header
      34  
      35  #include <bits/requires_hosted.h> // GNU extensions are currently omitted
      36  
      37  #include <ext/vstring_fwd.h>
      38  #include <debug/debug.h>
      39  #include <bits/stl_function.h>  // For less
      40  #include <bits/functexcept.h>
      41  #include <bits/localefwd.h>
      42  #include <bits/ostream_insert.h>
      43  #include <bits/stl_iterator.h>
      44  #include <ext/numeric_traits.h>
      45  #include <ext/alloc_traits.h>
      46  #include <bits/move.h>
      47  #include <bits/range_access.h>
      48  
      49  namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
      50  {
      51  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      52  
      53    template<typename _CharT, typename _Traits, typename _Alloc>
      54      struct __vstring_utility
      55      {
      56        typedef typename __alloc_traits<_Alloc>::template rebind<_CharT>::other
      57  	_CharT_alloc_type;
      58        typedef __alloc_traits<_CharT_alloc_type> _CharT_alloc_traits;
      59  
      60        typedef _Traits					    traits_type;
      61        typedef typename _Traits::char_type		    value_type;
      62        typedef typename _CharT_alloc_type::size_type	    size_type;
      63        typedef typename _CharT_alloc_type::difference_type   difference_type;
      64        typedef typename _CharT_alloc_traits::pointer	    pointer;
      65        typedef typename _CharT_alloc_traits::const_pointer   const_pointer;
      66  
      67        // For __sso_string.
      68        typedef __gnu_cxx::
      69        __normal_iterator<pointer, __gnu_cxx::
      70  			__versa_string<_CharT, _Traits, _Alloc,
      71  				       __sso_string_base> >
      72  	__sso_iterator;
      73        typedef __gnu_cxx::
      74        __normal_iterator<const_pointer, __gnu_cxx::
      75  			__versa_string<_CharT, _Traits, _Alloc,
      76  				       __sso_string_base> >
      77  	__const_sso_iterator;
      78  
      79        // For __rc_string.
      80        typedef __gnu_cxx::
      81        __normal_iterator<pointer, __gnu_cxx::
      82  			__versa_string<_CharT, _Traits, _Alloc,
      83  				       __rc_string_base> >
      84  	__rc_iterator;
      85        typedef __gnu_cxx::
      86        __normal_iterator<const_pointer, __gnu_cxx::
      87  			__versa_string<_CharT, _Traits, _Alloc,
      88  				       __rc_string_base> >
      89  	__const_rc_iterator;
      90  
      91        // NB:  When the allocator is empty, deriving from it saves space
      92        // (http://www.cantrip.org/emptyopt.html).
      93        template<typename _Alloc1>
      94  	struct _Alloc_hider
      95  	: public _Alloc1
      96  	{
      97  	  _Alloc_hider(_CharT* __ptr)
      98  	  : _Alloc1(), _M_p(__ptr) { }
      99  
     100  	  _Alloc_hider(const _Alloc1& __a, _CharT* __ptr)
     101  	  : _Alloc1(__a), _M_p(__ptr) { }
     102  
     103  	  _CharT*  _M_p; // The actual data.
     104  	};
     105  
     106        // When __n = 1 way faster than the general multichar
     107        // traits_type::copy/move/assign.
     108        static void
     109        _S_copy(_CharT* __d, const _CharT* __s, size_type __n)
     110        {
     111  	if (__n == 1)
     112  	  traits_type::assign(*__d, *__s);
     113  	else
     114  	  traits_type::copy(__d, __s, __n);
     115        }
     116  
     117        static void
     118        _S_move(_CharT* __d, const _CharT* __s, size_type __n)
     119        {
     120  	if (__n == 1)
     121  	  traits_type::assign(*__d, *__s);
     122  	else
     123  	  traits_type::move(__d, __s, __n);
     124        }
     125  
     126        static void
     127        _S_assign(_CharT* __d, size_type __n, _CharT __c)
     128        {
     129  	if (__n == 1)
     130  	  traits_type::assign(*__d, __c);
     131  	else
     132  	  traits_type::assign(__d, __n, __c);
     133        }
     134  
     135        // _S_copy_chars is a separate template to permit specialization
     136        // to optimize for the common case of pointers as iterators.
     137        template<typename _Iterator>
     138  	static void
     139  	_S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
     140  	{
     141  	  for (; __k1 != __k2; ++__k1, ++__p)
     142  	    traits_type::assign(*__p, *__k1); // These types are off.
     143  	}
     144  
     145        static void
     146        _S_copy_chars(_CharT* __p, __sso_iterator __k1, __sso_iterator __k2)
     147        { _S_copy_chars(__p, __k1.base(), __k2.base()); }
     148  
     149        static void
     150        _S_copy_chars(_CharT* __p, __const_sso_iterator __k1,
     151  		    __const_sso_iterator __k2)
     152        { _S_copy_chars(__p, __k1.base(), __k2.base()); }
     153  
     154        static void
     155        _S_copy_chars(_CharT* __p, __rc_iterator __k1, __rc_iterator __k2)
     156        { _S_copy_chars(__p, __k1.base(), __k2.base()); }
     157  
     158        static void
     159        _S_copy_chars(_CharT* __p, __const_rc_iterator __k1,
     160  		    __const_rc_iterator __k2)
     161        { _S_copy_chars(__p, __k1.base(), __k2.base()); }
     162  
     163        static void
     164        _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
     165        { _S_copy(__p, __k1, __k2 - __k1); }
     166  
     167        static void
     168        _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
     169        { _S_copy(__p, __k1, __k2 - __k1); }
     170  
     171        static int
     172        _S_compare(size_type __n1, size_type __n2)
     173        {
     174  	const difference_type __d = difference_type(__n1 - __n2);
     175  
     176  	if (__d > __numeric_traits_integer<int>::__max)
     177  	  return __numeric_traits_integer<int>::__max;
     178  	else if (__d < __numeric_traits_integer<int>::__min)
     179  	  return __numeric_traits_integer<int>::__min;
     180  	else
     181  	  return int(__d);
     182        }
     183      };
     184  
     185  _GLIBCXX_END_NAMESPACE_VERSION
     186  } // namespace
     187  
     188  #endif /* _VSTRING_UTIL_H */