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