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