]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/container/test/string_test.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / container / test / string_test.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/container for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10
11 #include <boost/container/detail/config_begin.hpp>
12 #include <boost/container/vector.hpp>
13 #include <boost/container/string.hpp>
14 #include <string>
15 #include <vector>
16 #include <boost/container/detail/algorithm.hpp> //equal()
17 #include <cstring>
18 #include <cstdio>
19 #include <cstddef>
20 #include <new>
21 #include "dummy_test_allocator.hpp"
22 #include "check_equal_containers.hpp"
23 #include "expand_bwd_test_allocator.hpp"
24 #include "expand_bwd_test_template.hpp"
25 #include "propagate_allocator_test.hpp"
26 #include "default_init_test.hpp"
27 #include "comparison_test.hpp"
28 #include "../../intrusive/test/iterator_test.hpp"
29 #include <boost/utility/string_view.hpp>
30 #include <boost/core/lightweight_test.hpp>
31
32 using namespace boost::container;
33
34 typedef test::simple_allocator<char> SimpleCharAllocator;
35 typedef basic_string<char, std::char_traits<char>, SimpleCharAllocator> SimpleString;
36 typedef test::simple_allocator<SimpleString> SimpleStringAllocator;
37 typedef test::simple_allocator<wchar_t> SimpleWCharAllocator;
38 typedef basic_string<wchar_t, std::char_traits<wchar_t>, SimpleWCharAllocator> SimpleWString;
39 typedef test::simple_allocator<SimpleWString> SimpleWStringAllocator;
40
41 namespace boost {
42 namespace container {
43
44 //Explicit instantiations of container::basic_string
45 template class basic_string<char, std::char_traits<char>, SimpleCharAllocator>;
46 template class basic_string<wchar_t, std::char_traits<wchar_t>, SimpleWCharAllocator>;
47 template class basic_string<char, std::char_traits<char>, std::allocator<char> >;
48 template class basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >;
49
50 //Explicit instantiation of container::vectors of container::strings
51 template class vector<SimpleString, SimpleStringAllocator>;
52 template class vector<SimpleWString, SimpleWStringAllocator>;
53
54 }}
55
56 struct StringEqual
57 {
58 template<class Str1, class Str2>
59 bool operator ()(const Str1 &string1, const Str2 &string2) const
60 {
61 if(string1.size() != string2.size())
62 return false;
63 return std::char_traits<typename Str1::value_type>::compare
64 (string1.c_str(), string2.c_str(), string1.size()) == 0;
65 }
66 };
67
68 //Function to check if both lists are equal
69 template<class StrVector1, class StrVector2>
70 bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2)
71 {
72 StringEqual comp;
73 return boost::container::algo_equal(strvect1->begin(), strvect1->end(),
74 strvect2->begin(), comp);
75 }
76
77 template<class ForwardIt>
78 ForwardIt unique(ForwardIt first, ForwardIt const last)
79 {
80 if(first == last){
81 ForwardIt i = first;
82 //Find first adjacent pair
83 while(1){
84 if(++i == last){
85 return last;
86 }
87 else if(*first == *i){
88 break;
89 }
90 ++first;
91 }
92 //Now overwrite skipping adjacent elements
93 while (++i != last) {
94 if (!(*first == *i)) {
95 *(++first) = boost::move(*i);
96 }
97 }
98 ++first;
99 }
100 return first;
101 }
102
103 template<class CharType>
104 struct string_literals;
105
106 template<>
107 struct string_literals<char>
108 {
109 static const char *String()
110 { return "String"; }
111 static const char *Prefix()
112 { return "Prefix"; }
113 static const char *Suffix()
114 { return "Suffix"; }
115 static const char *LongString()
116 { return "LongLongLongLongLongLongLongLongLongLongLongLongLongString"; }
117 static char Char()
118 { return 'C'; }
119 static void sprintf_number(char *buf, int number)
120 {
121 std::sprintf(buf, "%i", number);
122 }
123 };
124
125 template<>
126 struct string_literals<wchar_t>
127 {
128 static const wchar_t *String()
129 { return L"String"; }
130 static const wchar_t *Prefix()
131 { return L"Prefix"; }
132 static const wchar_t *Suffix()
133 { return L"Suffix"; }
134 static const wchar_t *LongString()
135 { return L"LongLongLongLongLongLongLongLongLongLongLongLongLongString"; }
136 static wchar_t Char()
137 { return L'C'; }
138 static void sprintf_number(wchar_t *buffer, unsigned int number)
139 {
140 //For compilers without wsprintf, print it backwards
141 const wchar_t *digits = L"0123456789";
142 wchar_t *buf = buffer;
143
144 while(1){
145 int rem = number % 10;
146 number = number / 10;
147
148 *buf = digits[rem];
149 ++buf;
150 if(!number){
151 *buf = 0;
152 break;
153 }
154 }
155
156 }
157 };
158
159 template<class CharType>
160 int string_test()
161 {
162 typedef std::basic_string<CharType> StdString;
163 typedef vector<StdString> StdStringVector;
164 typedef basic_string<CharType> BoostString;
165 typedef vector<BoostString> BoostStringVector;
166
167 const int MaxSize = 100;
168
169 {
170 BoostStringVector *boostStringVect = new BoostStringVector;
171 StdStringVector *stdStringVect = new StdStringVector;
172 BoostString auxBoostString;
173 StdString auxStdString(StdString(auxBoostString.begin(), auxBoostString.end() ));
174
175 CharType buffer [20];
176
177 //First, push back
178 for(int i = 0; i < MaxSize; ++i){
179 auxBoostString = string_literals<CharType>::String();
180 auxStdString = string_literals<CharType>::String();
181 string_literals<CharType>::sprintf_number(buffer, i);
182 auxBoostString += buffer;
183 auxStdString += buffer;
184 boostStringVect->push_back(auxBoostString);
185 stdStringVect->push_back(auxStdString);
186 }
187
188 if(auxBoostString.data() != const_cast<const BoostString&>(auxBoostString).data() &&
189 auxBoostString.data() != &auxBoostString[0])
190 return 1;
191
192 if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
193 return 1;
194 }
195
196 //Now push back moving
197 for(int i = 0; i < MaxSize; ++i){
198 auxBoostString = string_literals<CharType>::String();
199 auxStdString = string_literals<CharType>::String();
200 string_literals<CharType>::sprintf_number(buffer, i);
201 auxBoostString += buffer;
202 auxStdString += buffer;
203 boostStringVect->push_back(boost::move(auxBoostString));
204 stdStringVect->push_back(auxStdString);
205 }
206
207 if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
208 return 1;
209 }
210
211 //push front
212 for(int i = 0; i < MaxSize; ++i){
213 auxBoostString = string_literals<CharType>::String();
214 auxStdString = string_literals<CharType>::String();
215 string_literals<CharType>::sprintf_number(buffer, i);
216 auxBoostString += buffer;
217 auxStdString += buffer;
218 boostStringVect->insert(boostStringVect->begin(), auxBoostString);
219 stdStringVect->insert(stdStringVect->begin(), auxStdString);
220 }
221
222 if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
223 return 1;
224 }
225
226 //Now push front moving
227 for(int i = 0; i < MaxSize; ++i){
228 auxBoostString = string_literals<CharType>::String();
229 auxStdString = string_literals<CharType>::String();
230 string_literals<CharType>::sprintf_number(buffer, i);
231 auxBoostString += buffer;
232 auxStdString += buffer;
233 boostStringVect->insert(boostStringVect->begin(), boost::move(auxBoostString));
234 stdStringVect->insert(stdStringVect->begin(), auxStdString);
235 }
236
237 if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
238 return 1;
239 }
240
241 //Now test long and short representation swapping
242
243 //Short first
244 auxBoostString = string_literals<CharType>::String();
245 auxStdString = string_literals<CharType>::String();
246 BoostString boost_swapper;
247 StdString std_swapper;
248 boost_swapper.swap(auxBoostString);
249 std_swapper.swap(auxStdString);
250 if(!StringEqual()(auxBoostString, auxStdString))
251 return 1;
252 if(!StringEqual()(boost_swapper, std_swapper))
253 return 1;
254 boost_swapper.swap(auxBoostString);
255 std_swapper.swap(auxStdString);
256 if(!StringEqual()(auxBoostString, auxStdString))
257 return 1;
258 if(!StringEqual()(boost_swapper, std_swapper))
259 return 1;
260
261 //Shrink_to_fit
262 auxBoostString.shrink_to_fit();
263 StdString(auxStdString).swap(auxStdString);
264 if(!StringEqual()(auxBoostString, auxStdString))
265 return 1;
266
267 //Reserve + shrink_to_fit
268 auxBoostString.reserve(boost_swapper.size()*2+1);
269 auxStdString.reserve(std_swapper.size()*2+1);
270 if(!StringEqual()(auxBoostString, auxStdString))
271 return 1;
272
273 auxBoostString.shrink_to_fit();
274 StdString(auxStdString).swap(auxStdString);
275 if(!StringEqual()(auxBoostString, auxStdString))
276 return 1;
277
278 //Long string
279 auxBoostString = string_literals<CharType>::LongString();
280 auxStdString = string_literals<CharType>::LongString();
281 boost_swapper = BoostString();
282 std_swapper = StdString();
283 boost_swapper.swap(auxBoostString);
284 std_swapper.swap(auxStdString);
285 if(!StringEqual()(auxBoostString, auxStdString))
286 return 1;
287 if(!StringEqual()(boost_swapper, std_swapper))
288 return 1;
289 boost_swapper.swap(auxBoostString);
290 std_swapper.swap(auxStdString);
291
292 //Shrink_to_fit
293 auxBoostString.shrink_to_fit();
294 StdString(auxStdString).swap(auxStdString);
295 if(!StringEqual()(auxBoostString, auxStdString))
296 return 1;
297
298 auxBoostString.clear();
299 auxStdString.clear();
300 auxBoostString.shrink_to_fit();
301 StdString(auxStdString).swap(auxStdString);
302 if(!StringEqual()(auxBoostString, auxStdString))
303 return 1;
304
305 //No sort
306 std::sort(boostStringVect->begin(), boostStringVect->end());
307 std::sort(stdStringVect->begin(), stdStringVect->end());
308 if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
309
310 const CharType *prefix = string_literals<CharType>::Prefix();
311 const int prefix_size = std::char_traits<CharType>::length(prefix);
312 const CharType *sufix = string_literals<CharType>::Suffix();
313
314 for(int i = 0; i < MaxSize; ++i){
315 (*boostStringVect)[i].append(sufix);
316 (*stdStringVect)[i].append(sufix);
317 (*boostStringVect)[i].insert((*boostStringVect)[i].begin(),
318 prefix, prefix + prefix_size);
319 (*stdStringVect)[i].insert((*stdStringVect)[i].begin(),
320 prefix, prefix + prefix_size);
321 }
322
323 if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
324
325 for(int i = 0; i < MaxSize; ++i){
326 std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end());
327 std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
328 }
329
330 if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
331
332 for(int i = 0; i < MaxSize; ++i){
333 std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end());
334 std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
335 }
336
337 if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
338
339 for(int i = 0; i < MaxSize; ++i){
340 std::sort(boostStringVect->begin(), boostStringVect->end());
341 std::sort(stdStringVect->begin(), stdStringVect->end());
342 }
343
344 if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
345
346 for(int i = 0; i < MaxSize; ++i){
347 (*boostStringVect)[i].replace((*boostStringVect)[i].begin(),
348 (*boostStringVect)[i].end(),
349 string_literals<CharType>::String());
350 (*stdStringVect)[i].replace((*stdStringVect)[i].begin(),
351 (*stdStringVect)[i].end(),
352 string_literals<CharType>::String());
353 }
354
355 if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
356
357 boostStringVect->erase(::unique(boostStringVect->begin(), boostStringVect->end()),
358 boostStringVect->end());
359 stdStringVect->erase(::unique(stdStringVect->begin(), stdStringVect->end()),
360 stdStringVect->end());
361 if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
362
363 //Check addition
364 {
365 BoostString bs2 = string_literals<CharType>::String();
366 StdString ss2 = string_literals<CharType>::String();
367 BoostString bs3 = string_literals<CharType>::Suffix();
368 StdString ss3 = string_literals<CharType>::Suffix();
369 BoostString bs4 = bs2 + bs3;
370 StdString ss4 = ss2 + ss3;
371 if(!StringEqual()(bs4, ss4)){
372 return 1;
373 }
374
375 bs4 = bs2 + BoostString();
376 ss4 = ss2 + StdString();
377 if(!StringEqual()(bs4, ss4)){
378 return 1;
379 }
380
381 bs4 = BoostString() + bs2;
382 ss4 = StdString() + ss2;
383 if(!StringEqual()(bs4, ss4)){
384 return 1;
385 }
386
387 bs4 = BoostString() + boost::move(bs2);
388 ss4 = StdString() + boost::move(ss2);
389 if(!StringEqual()(bs4, ss4)){
390 return 1;
391 }
392
393 bs2 = string_literals<CharType>::String();
394 ss2 = string_literals<CharType>::String();
395 bs4 = boost::move(bs2) + BoostString();
396 ss4 = boost::move(ss2) + StdString();
397 if(!StringEqual()(bs4, ss4)){
398 return 1;
399 }
400
401 bs2 = string_literals<CharType>::String();
402 ss2 = string_literals<CharType>::String();
403 bs4 = string_literals<CharType>::Prefix() + boost::move(bs2);
404 ss4 = string_literals<CharType>::Prefix() + boost::move(ss2);
405 if(!StringEqual()(bs4, ss4)){
406 return 1;
407 }
408
409 bs2 = string_literals<CharType>::String();
410 ss2 = string_literals<CharType>::String();
411 bs4 = boost::move(bs2) + string_literals<CharType>::Suffix();
412 ss4 = boost::move(ss2) + string_literals<CharType>::Suffix();
413 if(!StringEqual()(bs4, ss4)){
414 return 1;
415 }
416
417 bs2 = string_literals<CharType>::String();
418 ss2 = string_literals<CharType>::String();
419 bs4 = string_literals<CharType>::Prefix() + bs2;
420 ss4 = string_literals<CharType>::Prefix() + ss2;
421 if(!StringEqual()(bs4, ss4)){
422 return 1;
423 }
424
425 bs2 = string_literals<CharType>::String();
426 ss2 = string_literals<CharType>::String();
427 bs4 = bs2 + string_literals<CharType>::Suffix();
428 ss4 = ss2 + string_literals<CharType>::Suffix();
429 if(!StringEqual()(bs4, ss4)){
430 return 1;
431 }
432
433 bs2 = string_literals<CharType>::String();
434 ss2 = string_literals<CharType>::String();
435 bs4 = string_literals<CharType>::Char() + bs2;
436 ss4 = string_literals<CharType>::Char() + ss2;
437 if(!StringEqual()(bs4, ss4)){
438 return 1;
439 }
440
441 bs2 = string_literals<CharType>::String();
442 ss2 = string_literals<CharType>::String();
443 bs4 = bs2 + string_literals<CharType>::Char();
444 ss4 = ss2 + string_literals<CharType>::Char();
445 if(!StringEqual()(bs4, ss4)){
446 return 1;
447 }
448
449 //Check front/back/begin/end
450
451 if(bs4.front() != *ss4.begin())
452 return 1;
453
454 if(bs4.back() != *(ss4.end()-1))
455 return 1;
456
457 bs4.pop_back();
458 ss4.erase(ss4.end()-1);
459 if(!StringEqual()(bs4, ss4)){
460 return 1;
461 }
462
463 if(*bs4.begin() != *ss4.begin())
464 return 1;
465 if(*bs4.cbegin() != *ss4.begin())
466 return 1;
467 if(*bs4.rbegin() != *ss4.rbegin())
468 return 1;
469 if(*bs4.crbegin() != *ss4.rbegin())
470 return 1;
471 if(*(bs4.end()-1) != *(ss4.end()-1))
472 return 1;
473 if(*(bs4.cend()-1) != *(ss4.end()-1))
474 return 1;
475 if(*(bs4.rend()-1) != *(ss4.rend()-1))
476 return 1;
477 if(*(bs4.crend()-1) != *(ss4.rend()-1))
478 return 1;
479 }
480
481 //When done, delete vector
482 delete boostStringVect;
483 delete stdStringVect;
484 }
485 return 0;
486 }
487
488 bool test_expand_bwd()
489 {
490 //Now test all back insertion possibilities
491 typedef test::expand_bwd_test_allocator<char>
492 allocator_type;
493 typedef basic_string<char, std::char_traits<char>, allocator_type>
494 string_type;
495 return test::test_all_expand_bwd<string_type>();
496 }
497
498 struct boost_container_string;
499
500 namespace boost { namespace container { namespace test {
501
502 template<>
503 struct alloc_propagate_base<boost_container_string>
504 {
505 template <class T, class Allocator>
506 struct apply
507 {
508 typedef boost::container::basic_string<T, std::char_traits<T>, Allocator> type;
509 };
510 };
511
512
513 }}} //namespace boost::container::test
514
515
516 int main()
517 {
518 if(string_test<char>()){
519 return 1;
520 }
521
522 if(string_test<wchar_t>()){
523 return 1;
524 }
525
526 ////////////////////////////////////
527 // Backwards expansion test
528 ////////////////////////////////////
529 if(!test_expand_bwd())
530 return 1;
531
532 ////////////////////////////////////
533 // Allocator propagation testing
534 ////////////////////////////////////
535 if(!boost::container::test::test_propagate_allocator<boost_container_string>())
536 return 1;
537
538 ////////////////////////////////////
539 // Default init test
540 ////////////////////////////////////
541 if(!test::default_init_test< basic_string<char, std::char_traits<char>, test::default_init_allocator<char> > >()){
542 std::cerr << "Default init test failed" << std::endl;
543 return 1;
544 }
545
546 if(!test::default_init_test< basic_string<wchar_t, std::char_traits<wchar_t>, test::default_init_allocator<wchar_t> > >()){
547 std::cerr << "Default init test failed" << std::endl;
548 return 1;
549 }
550
551 ////////////////////////////////////
552 // Iterator testing
553 ////////////////////////////////////
554 {
555 typedef boost::container::basic_string<char> cont_int;
556 cont_int a; a.push_back(char(1)); a.push_back(char(2)); a.push_back(char(3));
557 boost::intrusive::test::test_iterator_random< cont_int >(a);
558 }
559 {
560 typedef boost::container::basic_string<wchar_t> cont_int;
561 cont_int a; a.push_back(wchar_t(1)); a.push_back(wchar_t(2)); a.push_back(wchar_t(3));
562 boost::intrusive::test::test_iterator_random< cont_int >(a);
563 }
564
565 ////////////////////////////////////
566 // Comparison testing
567 ////////////////////////////////////
568 {
569 if(!boost::container::test::test_container_comparisons<string>())
570 return 1;
571 if(!boost::container::test::test_container_comparisons<wstring>())
572 return 1;
573 }
574
575 return boost::report_errors();
576 }
577
578 #include <boost/container/detail/config_end.hpp>