Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / test / test / utils-ts / basic_cstring-test.cpp
1 //  (C) Copyright Gennadiy Rozental 2001-2015.
2 //  Distributed under the Boost Software License, Version 1.0.
3 //  (See accompanying file LICENSE_1_0.txt or copy at
4 //  http://www.boost.org/LICENSE_1_0.txt)
5
6 //  See http://www.boost.org/libs/test for the library home page.
7 //
8 //  File        : $RCSfile$
9 //
10 //  Version     : $Revision$
11 //
12 //  Description : basic_cstring unit test
13 // *****************************************************************************
14
15 #ifdef _MSC_VER
16 #pragma warning(disable: 4996)
17 #pragma warning(disable: 4267)
18 #endif
19
20 // Boost.Test
21 #include <boost/test/unit_test.hpp>
22
23 #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
24 #include <boost/test/utils/basic_cstring/compare.hpp>
25 #include <boost/test/utils/basic_cstring/io.hpp>
26 #include <boost/test/tools/output_test_stream.hpp>
27 namespace utf = boost::unit_test;
28 namespace tt  = boost::test_tools;
29 using utf::const_string;
30
31 // Boost
32 #include <boost/mpl/list.hpp>
33 #include <boost/mpl/joint_view.hpp>
34 #include <boost/mpl/transform.hpp>
35 #include <boost/type_traits/add_const.hpp>
36
37 // STL
38 #include <cctype>
39 #include <ctime>
40 #include <iomanip>
41 #include <iostream>
42 #include <stdexcept>
43
44 namespace mpl = boost::mpl;
45
46 typedef mpl::list2<char const,wchar_t const>                                base_const_char_types;
47 typedef mpl::list3<char,unsigned char,wchar_t>                              mutable_char_types;
48 typedef mpl::transform<mutable_char_types,boost::add_const<mpl::_1> >::type const_char_types;
49 typedef mpl::joint_view<const_char_types,mutable_char_types>                char_types;
50 typedef mpl::list2<char,const char>                                         io_test_types;
51
52 //____________________________________________________________________________//
53
54 template<typename CharT>
55 struct string_literal {
56     typedef typename boost::remove_const<CharT>::type   mutable_char;
57
58     string_literal() {}
59     string_literal( char const* orig, std::size_t orig_size )
60     {
61         assign(orig, orig_size);
62     }
63
64     CharT*    begin() const { return const_cast<CharT*>(buff.c_str()); }
65
66     void    assign( char const* orig, std::size_t orig_size )
67     {
68         buff.resize( orig_size );
69         for (size_t index = 0; index < orig_size; ++index)
70             buff[index] = orig[index];
71     }
72
73     std::basic_string<mutable_char> buff;
74 };
75
76 //____________________________________________________________________________//
77
78 template<typename CharT>
79 CharT*
80 test_string( CharT* = 0 )
81 {
82     static string_literal<CharT> l( "test_string", 11 );
83
84     return l.begin();
85 }
86 #define TEST_STRING test_string<CharT>( (CharT*)0 )
87
88 //____________________________________________________________________________//
89
90 template<typename CharT>
91 CharT*
92 static_literal(char const* orig, std::size_t orig_size)
93 {
94     static string_literal<CharT> l;
95     
96     l.assign(orig, orig_size);
97
98     return l.begin();
99 }
100 #define LITERAL( s ) static_literal<CharT>( s, sizeof( s ) )
101
102 #define LOCAL_DEF( name, s )                                                \
103 string_literal<CharT> BOOST_JOIN( sl, __LINE__)(s, sizeof( s ));            \
104 utf::basic_cstring<CharT> name( (CharT*)(BOOST_JOIN( sl, __LINE__).begin()))\
105 /**/
106
107
108 //____________________________________________________________________________//
109
110 BOOST_TEST_CASE_TEMPLATE_FUNCTION( constructors_test, CharT )
111 {
112     {
113         utf::basic_cstring<CharT> bcs;
114         BOOST_TEST( bcs.size() == 0U );
115         BOOST_TEST( bcs.is_empty() );
116     }
117
118     {
119         utf::basic_cstring<CharT> bcs( utf::basic_cstring<CharT>::null_str() );
120         BOOST_TEST( bcs.size() == 0U );
121         BOOST_TEST( bcs.is_empty() );
122     }
123
124     {
125         utf::basic_cstring<CharT> bcs( 0 );
126         BOOST_TEST( bcs.size() == 0U );
127         BOOST_TEST( bcs.is_empty() );
128     }
129
130     {
131         typedef typename utf::basic_cstring<CharT>::traits_type traits;
132
133         utf::basic_cstring<CharT> bcs( TEST_STRING );
134         BOOST_TEST( traits::compare( bcs.begin(), TEST_STRING, bcs.size() ) == 0 );
135         BOOST_TEST( bcs.size() == traits::length( TEST_STRING ) );
136
137         utf::basic_cstring<CharT> bcs1( bcs );
138         BOOST_TEST( traits::compare( bcs1.begin(), TEST_STRING, bcs1.size() ) == 0 );
139     }
140
141     {
142         typedef typename utf::basic_cstring<CharT>::traits_type traits;
143
144         utf::basic_cstring<CharT> bcs( TEST_STRING, 4 );
145         BOOST_TEST( traits::compare( bcs.begin(), LITERAL( "test" ), bcs.size() ) == 0 );
146     }
147
148     {
149         typedef typename utf::basic_cstring<CharT>::traits_type traits;
150
151         utf::basic_cstring<CharT> bcs( TEST_STRING, TEST_STRING + 6 );
152         BOOST_TEST( traits::compare( bcs.begin(), LITERAL( "test_s" ), bcs.size() ) == 0 );
153     }
154 }
155
156 //____________________________________________________________________________//
157
158 BOOST_TEST_CASE_TEMPLATE_FUNCTION( constructors_std_string_test, CharT )
159 {
160     typedef typename utf::basic_cstring<CharT>::traits_type traits;
161
162     {
163         typename utf::basic_cstring<CharT>::std_string l( TEST_STRING );
164
165         utf::basic_cstring<CharT> bcs( l );
166         BOOST_TEST( traits::compare( bcs.begin(), TEST_STRING, bcs.size() ) == 0 );
167     }
168
169 }
170
171 //____________________________________________________________________________//
172
173 void array_construction_test()
174 {
175     const_string bcs_array[] = { "str1", "str2" };
176
177     BOOST_TEST( const_string::traits_type::compare( bcs_array[0].begin(), "str1", bcs_array[0].size() ) == 0 );
178     BOOST_TEST( const_string::traits_type::compare( bcs_array[1].begin(), "str2", bcs_array[1].size() ) == 0 );
179
180     const_string bcs( "abc" );
181     BOOST_TEST( const_string::traits_type::compare( bcs.begin(), "abc", bcs.size() ) == 0 );
182 }
183
184 //____________________________________________________________________________//
185
186 BOOST_TEST_CASE_TEMPLATE_FUNCTION( data_access_test, CharT )
187 {
188     typedef typename utf::basic_cstring<CharT>::traits_type traits_type;
189
190     utf::basic_cstring<CharT> bcs1( TEST_STRING );
191     BOOST_TEST( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ) == 0 );
192     BOOST_TEST( traits_type::compare( bcs1.begin(), bcs1.begin(), bcs1.size() ) == 0 );
193
194     BOOST_TEST( bcs1[0] == 't' );
195     BOOST_TEST( bcs1[4] == '_' );
196     BOOST_TEST( bcs1[bcs1.size()-1] == 'g' );
197
198     BOOST_TEST( bcs1[0] == bcs1.at( 0 ) );
199     BOOST_TEST( bcs1[2] == bcs1.at( 5 ) );
200     BOOST_TEST( bcs1.at( bcs1.size() - 1 ) == 'g' );
201     BOOST_TEST( bcs1.at( bcs1.size() ) == 0 );
202     BOOST_TEST( bcs1.at( bcs1.size()+1 ) == 0 );
203
204     BOOST_TEST( utf::first_char( bcs1 ) == 't' );
205     BOOST_TEST( utf::last_char( bcs1 ) == 'g' );
206
207     BOOST_TEST( utf::first_char( utf::basic_cstring<CharT>() ) == 0 );
208     BOOST_TEST( utf::last_char( utf::basic_cstring<CharT>() ) == 0 );
209 }
210
211 //____________________________________________________________________________//
212
213 BOOST_TEST_CASE_TEMPLATE_FUNCTION( size_test, CharT )
214 {
215     utf::basic_cstring<CharT> bcs1;
216
217     BOOST_TEST( bcs1.size() == 0U );
218     BOOST_TEST( bcs1.is_empty() );
219
220     bcs1 = TEST_STRING;
221     BOOST_TEST( bcs1.size() == 11U );
222
223     bcs1.clear();
224     BOOST_TEST( bcs1.size() == 0U );
225     BOOST_TEST( bcs1.is_empty() );
226
227     bcs1 = utf::basic_cstring<CharT>( TEST_STRING, 4 );
228     BOOST_TEST( bcs1.size() == 4U );
229
230     bcs1.resize( 5 );
231     BOOST_TEST( bcs1.size() == 4U );
232
233     bcs1.resize( 3 );
234     BOOST_TEST( bcs1.size() == 3U );
235 }
236
237 //____________________________________________________________________________//
238
239 BOOST_TEST_CASE_TEMPLATE_FUNCTION( asignment_test, CharT )
240 {
241     typedef typename utf::basic_cstring<CharT>::traits_type traits_type;
242
243     utf::basic_cstring<CharT> bcs1;
244     string_literal<CharT> l( "test", 4 );
245
246     bcs1 = l.begin();
247     BOOST_TEST( traits_type::compare( bcs1.begin(), LITERAL( "test" ), bcs1.size() ) == 0 );
248
249     utf::basic_cstring<CharT> bcs2( TEST_STRING );
250     bcs1 = bcs2;
251     BOOST_TEST( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ) == 0 );
252
253     bcs1.assign( l.begin() );
254     BOOST_TEST( traits_type::compare( bcs1.begin(), LITERAL( "test" ), bcs1.size() ) == 0 );
255
256     bcs1.assign( l.begin()+1, l.begin()+3 );
257     BOOST_TEST( traits_type::compare( bcs1.begin(), LITERAL( "est" ), bcs1.size() ) == 0 );
258
259     bcs1.assign( bcs2, 4, 3 );
260     BOOST_TEST( traits_type::compare( bcs1.begin(), LITERAL( "_st" ), bcs1.size() ) == 0 );
261
262     bcs1.swap( bcs2 );
263     BOOST_TEST( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ) == 0 );
264     BOOST_TEST( traits_type::compare( bcs2.begin(), LITERAL( "_st" ), bcs2.size() ) == 0 );
265 }
266
267 //____________________________________________________________________________//
268
269 BOOST_TEST_CASE_TEMPLATE_FUNCTION( asignment_std_string_test, CharT )
270 {
271     typedef typename utf::basic_cstring<CharT>::traits_type traits_type;
272
273     utf::basic_cstring<CharT> bcs1;
274     typename utf::basic_cstring<CharT>::std_string l( TEST_STRING );
275
276     bcs1 = l;
277     BOOST_TEST( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ) == 0 );
278
279     bcs1.assign( l );
280     BOOST_TEST( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ) == 0 );
281
282     bcs1.assign( l, 1, 2 );
283     BOOST_TEST( traits_type::compare( bcs1.begin(), LITERAL( "es" ), bcs1.size() ) == 0 );
284 }
285
286 //____________________________________________________________________________//
287
288 BOOST_TEST_CASE_TEMPLATE_FUNCTION( comparison_test, CharT )
289 {
290     utf::basic_cstring<CharT> bcs1( TEST_STRING );
291     utf::basic_cstring<CharT> bcs2( TEST_STRING );
292
293     BOOST_TEST(( bcs1 == TEST_STRING ));
294     BOOST_TEST(( TEST_STRING == bcs1 ));
295     BOOST_TEST(( bcs1 == bcs2 ));
296
297     bcs1.resize( 4 );
298
299     BOOST_TEST(( bcs1 == LITERAL( "test" ) ));
300
301     BOOST_TEST(( bcs1 != TEST_STRING ));
302     BOOST_TEST(( TEST_STRING != bcs1 ));
303     BOOST_TEST(( bcs1 != bcs2 ));
304
305     LOCAL_DEF( bcs3, "TeSt" );
306     BOOST_TEST( utf::case_ins_eq( bcs1, bcs3 ) );
307 }
308
309 //____________________________________________________________________________//
310
311 BOOST_TEST_DONT_PRINT_LOG_VALUE( std::wstring )
312
313 BOOST_TEST_CASE_TEMPLATE_FUNCTION( comparison_std_string_test, CharT )
314 {
315     utf::basic_cstring<CharT> bcs1( TEST_STRING );
316     typename utf::basic_cstring<CharT>::std_string l( TEST_STRING );
317
318     BOOST_TEST( bcs1 == l );
319     BOOST_TEST( l == bcs1 );
320
321     bcs1.resize( 4 );
322
323     BOOST_TEST( bcs1 != l );
324     BOOST_TEST( l != bcs1 );
325 }
326
327 //____________________________________________________________________________//
328
329 BOOST_TEST_CASE_TEMPLATE_FUNCTION( ordering_test, CharT )
330 {
331     LOCAL_DEF( bcs1, "aBcd" );
332     LOCAL_DEF( bcs2, "aBbdd" );
333     LOCAL_DEF( bcs3, "aBbde" );
334     LOCAL_DEF( bcs4, "abab" );
335
336     BOOST_TEST(( bcs1 < bcs2 ));
337     BOOST_TEST(( bcs2 < bcs3 ));
338     BOOST_TEST(( bcs1 < bcs3 ));
339     BOOST_TEST(( bcs1 < bcs4 ));
340
341     utf::case_ins_less<CharT> cil;
342     BOOST_TEST( cil( bcs4, bcs1 ) );
343 }
344
345 //____________________________________________________________________________//
346
347 BOOST_TEST_CASE_TEMPLATE_FUNCTION( trim_test, CharT )
348 {
349     LOCAL_DEF( bcs0, "tes" );
350
351     bcs0.trim_right( 1 );
352     BOOST_TEST( bcs0.size() == 2U );
353     BOOST_TEST( bcs0[0] == 't' );
354
355     bcs0.trim_left( 1 );
356     BOOST_TEST( bcs0.size() == 1U );
357     BOOST_TEST( bcs0[0] == 'e' );
358
359     bcs0.trim_left( 1 );
360     BOOST_TEST( bcs0.is_empty() );
361
362     bcs0 = TEST_STRING;
363     bcs0.trim_left( 11 );
364     BOOST_TEST( bcs0.is_empty() );
365
366     bcs0 = TEST_STRING;
367     bcs0.trim_right( 11 );
368     BOOST_TEST( bcs0.is_empty() );
369
370     bcs0 = TEST_STRING;
371     bcs0.trim_right( bcs0.size() - bcs0.find( LITERAL( "t_s" ) ) - 3 );
372     BOOST_TEST( bcs0 == LITERAL( "test_s" ) );
373
374     bcs0.trim_left( bcs0.find( LITERAL( "t_s" ) ) );
375     BOOST_TEST( bcs0 == LITERAL( "t_s" ) );
376
377     LOCAL_DEF( bcs1, "abcd   " );
378     LOCAL_DEF( bcs2, "     abcd" );
379     LOCAL_DEF( bcs3, "  abcd  " );
380
381     bcs1.trim_right();
382     BOOST_TEST( bcs1 == LITERAL( "abcd" ) );
383
384     bcs2.trim_left();
385     BOOST_TEST( bcs2 == LITERAL( "abcd" ) );
386
387     bcs3.trim( LITERAL( "\"" ) );
388     BOOST_TEST( bcs3 == LITERAL( "  abcd  " ) );
389
390     bcs3.trim();
391     BOOST_TEST( bcs3 == LITERAL( "abcd" ) );
392
393     bcs3.trim();
394     BOOST_TEST( bcs3 == LITERAL( "abcd" ) );
395 }
396
397 //____________________________________________________________________________//
398
399 BOOST_TEST_CASE_TEMPLATE_FUNCTION( io_test, CharT )
400 {
401     utf::basic_cstring<CharT> bcs1( TEST_STRING );
402     bcs1.trim_right( 7 );
403
404     tt::output_test_stream ostr;
405
406     ostr << std::setw( 6 ) << bcs1;
407     BOOST_TEST( ostr.is_equal( "  test" ) );
408
409     ostr << std::setw( 3 ) << bcs1;
410     BOOST_TEST( ostr.is_equal( "test" ) );
411
412     ostr << std::setw( 5 ) << std::setiosflags( std::ios::left ) << bcs1;
413     BOOST_TEST( ostr.is_equal( "test " ) );
414 }
415
416 //____________________________________________________________________________//
417
418 BOOST_TEST_CASE_TEMPLATE_FUNCTION( find_test, CharT )
419 {
420     typedef typename utf::basic_cstring<CharT>::size_type size;
421     utf::basic_cstring<CharT> bcs1( TEST_STRING );
422
423     size not_found = (size)utf::basic_cstring<CharT>::npos;
424
425     BOOST_TEST( bcs1.find( utf::basic_cstring<CharT>() ) == not_found );
426     BOOST_TEST( bcs1.find( LITERAL( "test" ) ) == (size)0 );
427     BOOST_TEST( bcs1.find( TEST_STRING ) == (size)0 );
428     BOOST_TEST( bcs1.find( LITERAL( "test_string " ) ) == not_found );
429     BOOST_TEST( bcs1.find( LITERAL( " test_string" ) ) == not_found );
430     BOOST_TEST( bcs1.find( LITERAL( "est" ) ) == (size)1 );
431     BOOST_TEST( bcs1.find( LITERAL( "t_st" ) ) == (size)3 );
432     BOOST_TEST( bcs1.find( LITERAL( "ing" ) ) == (size)8 );
433     BOOST_TEST( bcs1.find( LITERAL( "tst" ) ) == not_found );
434
435     BOOST_TEST( bcs1.rfind( utf::basic_cstring<CharT>() ) == not_found );
436     BOOST_TEST( bcs1.rfind( LITERAL( "test" ) ) == (size)0 );
437     BOOST_TEST( bcs1.rfind( TEST_STRING ) == (size)0 );
438     BOOST_TEST( bcs1.rfind( LITERAL( "test_string " ) ) == not_found );
439     BOOST_TEST( bcs1.rfind( LITERAL( " test_string" ) ) == not_found );
440     BOOST_TEST( bcs1.rfind( LITERAL( "est" ) ) == (size)1 );
441     BOOST_TEST( bcs1.rfind( LITERAL( "t_st" ) ) == (size)3 );
442     BOOST_TEST( bcs1.rfind( LITERAL( "ing" ) ) == (size)8 );
443     BOOST_TEST( bcs1.rfind( LITERAL( "tst" ) ) == not_found );
444 }
445
446 //____________________________________________________________________________//
447
448 void const_conversion()
449 {
450     char arr[] = { "ABC" };
451
452     utf::basic_cstring<char> str1( arr );
453     utf::basic_cstring<char const> str2;
454
455     str2.assign( str1 );
456
457     BOOST_TEST( str1 == "ABC" );
458     BOOST_TEST( str2 == "ABC" );
459 }
460
461 //____________________________________________________________________________//
462
463 #if defined(BOOST_TEST_STRING_VIEW)
464 BOOST_TEST_CASE_TEMPLATE_FUNCTION( string_view_support, CharT )
465 {
466   using namespace std::literals;
467   typedef std::basic_string_view<CharT> string_view_t;
468   namespace utf = boost::unit_test;
469
470   {
471     string_view_t sv = LITERAL("");
472
473     utf::stringview_cstring_helper<CharT, string_view_t> svh = sv;
474     BOOST_TEST( svh.size() == 0U );
475     BOOST_TEST( svh.is_empty() );
476   }
477
478
479   {
480     string_view_t sv = LITERAL("bla");
481
482     utf::stringview_cstring_helper<CharT, string_view_t> svh = sv;
483     BOOST_TEST( svh.size() == 3U );
484     BOOST_TEST( !svh.is_empty() );
485   }
486 }
487 #endif
488
489
490 //____________________________________________________________________________//
491
492 utf::test_suite*
493 init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
494 {
495     utf::test_suite* test= BOOST_TEST_SUITE("basic_cstring test");
496
497     test->add( BOOST_TEST_CASE_TEMPLATE( constructors_test, char_types ) );
498     test->add( BOOST_TEST_CASE_TEMPLATE( constructors_std_string_test, base_const_char_types ) );
499     test->add( BOOST_TEST_CASE_TEMPLATE( asignment_std_string_test, base_const_char_types ) );
500     test->add( BOOST_TEST_CASE_TEMPLATE( comparison_std_string_test, base_const_char_types ) );
501     test->add( BOOST_TEST_CASE( array_construction_test ) );
502     test->add( BOOST_TEST_CASE_TEMPLATE( data_access_test, char_types ) );
503     test->add( BOOST_TEST_CASE_TEMPLATE( size_test, char_types ) );
504     test->add( BOOST_TEST_CASE_TEMPLATE( asignment_test, char_types ) );
505     test->add( BOOST_TEST_CASE_TEMPLATE( comparison_test, char_types ) );
506     test->add( BOOST_TEST_CASE_TEMPLATE( ordering_test, char_types ) );
507     test->add( BOOST_TEST_CASE_TEMPLATE( trim_test, char_types ) );
508     test->add( BOOST_TEST_CASE_TEMPLATE( io_test, io_test_types ) );
509     test->add( BOOST_TEST_CASE_TEMPLATE( find_test, char_types ) );
510     test->add( BOOST_TEST_CASE( &const_conversion ) );
511   
512 #if defined(BOOST_TEST_STRING_VIEW)
513     test->add( BOOST_TEST_CASE_TEMPLATE( string_view_support, char_types ) );
514 #endif
515
516     return test;
517 }
518
519 // EOF