]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/utility/test/string_view_test2.cpp
135fd1aa35a04a21d2f472f0e3f82f3b9bf8af36
[ceph.git] / ceph / src / boost / libs / utility / test / string_view_test2.cpp
1 /*
2 Copyright (c) Marshall Clow 2012-2012.
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 For more information, see http://www.boost.org
8 */
9
10 #include <new> // for placement new
11 #include <iostream>
12 #include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
13 #include <cstring> // for std::strchr and std::strcmp
14 #include <cstdlib> // for std::malloc and std::free
15
16 #include <boost/utility/string_view.hpp>
17 #include <boost/config.hpp>
18
19 #include <boost/core/lightweight_test.hpp>
20
21 typedef boost::string_view string_view;
22
23 void ends_with ( const char *arg ) {
24 const size_t sz = std::strlen ( arg );
25 string_view sr ( arg );
26 string_view sr2 ( arg );
27 const char *p = arg;
28
29 while ( *p ) {
30 BOOST_TEST ( sr.ends_with ( p ));
31 ++p;
32 }
33
34 while ( !sr2.empty ()) {
35 BOOST_TEST ( sr.ends_with ( sr2 ));
36 sr2.remove_prefix (1);
37 }
38
39 sr2 = arg;
40 while ( !sr2.empty ()) {
41 BOOST_TEST ( sr.ends_with ( sr2 ));
42 sr2.remove_prefix (1);
43 }
44
45 char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
46 sr2 = arg;
47 if ( sz > 0 )
48 BOOST_TEST ( sr2.ends_with ( ch ));
49 BOOST_TEST ( !sr2.ends_with ( ++ch ));
50 BOOST_TEST ( sr2.ends_with ( string_view()));
51 }
52
53 void starts_with ( const char *arg ) {
54 const size_t sz = std::strlen ( arg );
55 string_view sr ( arg );
56 string_view sr2 ( arg );
57 const char *p = arg + std::strlen ( arg ) - 1;
58 while ( p >= arg ) {
59 std::string foo ( arg, p + 1 );
60 BOOST_TEST ( sr.starts_with ( foo ));
61 --p;
62 }
63
64 while ( !sr2.empty ()) {
65 BOOST_TEST ( sr.starts_with ( sr2 ));
66 sr2.remove_suffix (1);
67 }
68
69 char ch = *arg;
70 sr2 = arg;
71 if ( sz > 0 )
72 BOOST_TEST ( sr2.starts_with ( ch ));
73 BOOST_TEST ( !sr2.starts_with ( ++ch ));
74 BOOST_TEST ( sr2.starts_with ( string_view ()));
75 }
76
77 void reverse ( const char *arg ) {
78 // Round trip
79 string_view sr1 ( arg );
80 std::string string1 ( sr1.rbegin (), sr1.rend ());
81 string_view sr2 ( string1 );
82 std::string string2 ( sr2.rbegin (), sr2.rend ());
83
84 BOOST_TEST ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
85 BOOST_TEST ( string2 == arg );
86 BOOST_TEST ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
87 }
88
89 // This helper function eliminates signed vs. unsigned warnings
90 string_view::size_type ptr_diff ( const char *res, const char *base ) {
91 BOOST_TEST ( res >= base );
92 return static_cast<string_view::size_type> ( res - base );
93 }
94
95 void find ( const char *arg ) {
96 string_view sr1;
97 string_view sr2;
98 const char *p;
99
100 // When we search for the empty string, we find it at position 0
101 BOOST_TEST ( sr1.find (sr2) == 0 );
102 BOOST_TEST ( sr1.rfind(sr2) == 0 );
103
104 // Look for each character in the string(searching from the start)
105 p = arg;
106 sr1 = arg;
107 while ( *p ) {
108 string_view::size_type pos = sr1.find(*p);
109 BOOST_TEST ( pos != string_view::npos && ( pos <= ptr_diff ( p, arg )));
110 ++p;
111 }
112
113 // Look for each character in the string (searching from the end)
114 p = arg;
115 sr1 = arg;
116 while ( *p ) {
117 string_view::size_type pos = sr1.rfind(*p);
118 BOOST_TEST ( pos != string_view::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
119 ++p;
120 }
121
122 // Look for pairs on characters (searching from the start)
123 sr1 = arg;
124 p = arg;
125 while ( *p && *(p+1)) {
126 string_view sr3 ( p, 2 );
127 string_view::size_type pos = sr1.find ( sr3 );
128 BOOST_TEST ( pos != string_view::npos && pos <= static_cast<string_view::size_type>( p - arg ));
129 p++;
130 }
131
132 sr1 = arg;
133 p = arg;
134 // for all possible chars, see if we find them in the right place.
135 // Note that strchr will/might do the _wrong_ thing if we search for NULL
136 for ( int ch = 1; ch < 256; ++ch ) {
137 string_view::size_type pos = sr1.find(ch);
138 const char *strp = std::strchr ( arg, ch );
139 BOOST_TEST (( strp == NULL ) == ( pos == string_view::npos ));
140 if ( strp != NULL )
141 BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
142 }
143
144 sr1 = arg;
145 p = arg;
146 // for all possible chars, see if we find them in the right place.
147 // Note that strchr will/might do the _wrong_ thing if we search for NULL
148 for ( int ch = 1; ch < 256; ++ch ) {
149 string_view::size_type pos = sr1.rfind(ch);
150 const char *strp = std::strrchr ( arg, ch );
151 BOOST_TEST (( strp == NULL ) == ( pos == string_view::npos ));
152 if ( strp != NULL )
153 BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
154 }
155
156
157 // Find everything at the start
158 p = arg;
159 sr1 = arg;
160 while ( !sr1.empty ()) {
161 string_view::size_type pos = sr1.find(*p);
162 BOOST_TEST ( pos == 0 );
163 sr1.remove_prefix (1);
164 ++p;
165 }
166
167 // Find everything at the end
168 sr1 = arg;
169 p = arg + std::strlen ( arg ) - 1;
170 while ( !sr1.empty ()) {
171 string_view::size_type pos = sr1.rfind(*p);
172 BOOST_TEST ( pos == sr1.size () - 1 );
173 sr1.remove_suffix (1);
174 --p;
175 }
176
177 // Find everything at the start
178 sr1 = arg;
179 p = arg;
180 while ( !sr1.empty ()) {
181 string_view::size_type pos = sr1.find_first_of(*p);
182 BOOST_TEST ( pos == 0 );
183 sr1.remove_prefix (1);
184 ++p;
185 }
186
187
188 // Find everything at the end
189 sr1 = arg;
190 p = arg + std::strlen ( arg ) - 1;
191 while ( !sr1.empty ()) {
192 string_view::size_type pos = sr1.find_last_of(*p);
193 BOOST_TEST ( pos == sr1.size () - 1 );
194 sr1.remove_suffix (1);
195 --p;
196 }
197
198 // Basic sanity checking for "find_first_of / find_first_not_of"
199 sr1 = arg;
200 sr2 = arg;
201 while ( !sr1.empty() ) {
202 BOOST_TEST ( sr1.find_first_of ( sr2 ) == 0 );
203 BOOST_TEST ( sr1.find_first_not_of ( sr2 ) == string_view::npos );
204 sr1.remove_prefix ( 1 );
205 }
206
207 p = arg;
208 sr1 = arg;
209 while ( *p ) {
210 string_view::size_type pos1 = sr1.find_first_of(*p);
211 string_view::size_type pos2 = sr1.find_first_not_of(*p);
212 BOOST_TEST ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
213 if ( pos2 != string_view::npos ) {
214 for ( size_t i = 0 ; i < pos2; ++i )
215 BOOST_TEST ( sr1[i] == *p );
216 BOOST_TEST ( sr1 [ pos2 ] != *p );
217 }
218
219 BOOST_TEST ( pos2 != pos1 );
220 ++p;
221 }
222
223 // Basic sanity checking for "find_last_of / find_last_not_of"
224 sr1 = arg;
225 sr2 = arg;
226 while ( !sr1.empty() ) {
227 BOOST_TEST ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
228 BOOST_TEST ( sr1.find_last_not_of ( sr2 ) == string_view::npos );
229 sr1.remove_suffix ( 1 );
230 }
231
232 p = arg;
233 sr1 = arg;
234 while ( *p ) {
235 string_view::size_type pos1 = sr1.find_last_of(*p);
236 string_view::size_type pos2 = sr1.find_last_not_of(*p);
237 BOOST_TEST ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
238 BOOST_TEST ( pos2 == string_view::npos || pos1 < sr1.size ());
239 if ( pos2 != string_view::npos ) {
240 for ( size_t i = sr1.size () -1 ; i > pos2; --i )
241 BOOST_TEST ( sr1[i] == *p );
242 BOOST_TEST ( sr1 [ pos2 ] != *p );
243 }
244
245 BOOST_TEST ( pos2 != pos1 );
246 ++p;
247 }
248
249 }
250
251 template <typename T>
252 class custom_allocator {
253 public:
254 typedef T value_type;
255 typedef T* pointer;
256 typedef const T* const_pointer;
257 typedef void* void_pointer;
258 typedef const void* const_void_pointer;
259 typedef std::size_t size_type;
260 typedef std::ptrdiff_t difference_type;
261 typedef T& reference;
262 typedef const T& const_reference;
263
264 template<class U>
265 struct rebind {
266 typedef custom_allocator<U> other;
267 };
268
269 custom_allocator() BOOST_NOEXCEPT {}
270 template <typename U>
271 custom_allocator(custom_allocator<U> const&) BOOST_NOEXCEPT {}
272
273 pointer allocate(size_type n) const {
274 return static_cast<pointer>(std::malloc(sizeof(value_type) * n));
275 }
276 void deallocate(pointer p, size_type) const BOOST_NOEXCEPT {
277 std::free(p);
278 }
279
280 pointer address(reference value) const BOOST_NOEXCEPT {
281 return &value;
282 }
283
284 const_pointer address(const_reference value) const BOOST_NOEXCEPT {
285 return &value;
286 }
287
288 BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {
289 return (~(size_type)0u) / sizeof(value_type);
290 }
291
292 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
293 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
294 template <class U, class... Args>
295 void construct(U* ptr, Args&&... args) const {
296 ::new((void*)ptr) U(static_cast<Args&&>(args)...);
297 }
298 #else
299 template <class U, class V>
300 void construct(U* ptr, V&& value) const {
301 ::new((void*)ptr) U(static_cast<V&&>(value));
302 }
303 #endif
304 #else
305 template <class U, class V>
306 void construct(U* ptr, const V& value) const {
307 ::new((void*)ptr) U(value);
308 }
309 #endif
310
311 template <class U>
312 void construct(U* ptr) const {
313 ::new((void*)ptr) U();
314 }
315
316 template <class U>
317 void destroy(U* ptr) const {
318 (void)ptr;
319 ptr->~U();
320 }
321 };
322
323 template <typename T, typename U>
324 BOOST_CONSTEXPR bool operator==(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
325 return true;
326 }
327 template <typename T, typename U>
328 BOOST_CONSTEXPR bool operator!=(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
329 return false;
330 }
331
332 void to_string ( const char *arg ) {
333 string_view sr1;
334 std::string str1;
335 std::string str2;
336
337 str1.assign ( arg );
338 sr1 = arg;
339 // str2 = sr1.to_string<std::allocator<char> > ();
340 str2 = sr1.to_string ();
341 BOOST_TEST ( str1 == str2 );
342
343 std::basic_string<char, std::char_traits<char>, custom_allocator<char> > str3 = sr1.to_string(custom_allocator<char>());
344 BOOST_TEST ( std::strcmp(str1.c_str(), str3.c_str()) == 0 );
345
346 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
347 std::string str4 = static_cast<std::string> ( sr1 );
348 BOOST_TEST ( str1 == str4 );
349 #endif
350 }
351
352 void compare ( const char *arg ) {
353 string_view sr1;
354 std::string str1;
355 std::string str2 = str1;
356
357 str1.assign ( arg );
358 sr1 = arg;
359 BOOST_TEST ( sr1 == sr1); // compare string_view and string_view
360 BOOST_TEST ( sr1 == str1); // compare string and string_view
361 BOOST_TEST ( str1 == sr1 ); // compare string_view and string
362 BOOST_TEST ( sr1 == arg ); // compare string_view and pointer
363 BOOST_TEST ( arg == sr1 ); // compare pointer and string_view
364
365 if ( sr1.size () > 0 ) {
366 (*str1.rbegin())++;
367 BOOST_TEST ( sr1 != str1 );
368 BOOST_TEST ( str1 != sr1 );
369 BOOST_TEST ( sr1 < str1 );
370 BOOST_TEST ( sr1 <= str1 );
371 BOOST_TEST ( str1 > sr1 );
372 BOOST_TEST ( str1 >= sr1 );
373
374 (*str1.rbegin()) -= 2;
375 BOOST_TEST ( sr1 != str1 );
376 BOOST_TEST ( str1 != sr1 );
377 BOOST_TEST ( sr1 > str1 );
378 BOOST_TEST ( sr1 >= str1 );
379 BOOST_TEST ( str1 < sr1 );
380 BOOST_TEST ( str1 <= sr1 );
381 }
382 }
383
384 const char *test_strings [] = {
385 "",
386 "0",
387 "abc",
388 "AAA", // all the same
389 "adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf",
390 "abc\0asdfadsfasf",
391 NULL
392 };
393
394 int main()
395 {
396 const char **p = &test_strings[0];
397
398 while ( *p != NULL ) {
399 starts_with ( *p );
400 ends_with ( *p );
401 reverse ( *p );
402 find ( *p );
403 to_string ( *p );
404 compare ( *p );
405
406 p++;
407 }
408
409 return boost::report_errors();
410 }