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)
6 // See http://www.boost.org/libs/test for the library home page.
10 // Version : $Revision$
12 // Description : basic_cstring unit test
13 // *****************************************************************************
16 #pragma warning(disable: 4996)
17 #pragma warning(disable: 4267)
21 #include <boost/test/unit_test.hpp>
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
;
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>
44 namespace mpl
= boost::mpl
;
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
;
52 //____________________________________________________________________________//
54 template<typename CharT
>
55 struct string_literal
{
56 typedef typename
boost::remove_const
<CharT
>::type mutable_char
;
59 string_literal( char const* orig
, std::size_t orig_size
)
61 assign(orig
, orig_size
);
64 CharT
* begin() const { return const_cast<CharT
*>(buff
.c_str()); }
66 void assign( char const* orig
, std::size_t orig_size
)
68 buff
.resize( orig_size
);
69 for (size_t index
= 0; index
< orig_size
; ++index
)
70 buff
[index
] = orig
[index
];
73 std::basic_string
<mutable_char
> buff
;
76 //____________________________________________________________________________//
78 template<typename CharT
>
80 test_string( CharT
* = 0 )
82 static string_literal
<CharT
> l( "test_string", 11 );
86 #define TEST_STRING test_string<CharT>( (CharT*)0 )
88 //____________________________________________________________________________//
90 template<typename CharT
>
92 static_literal(char const* orig
, std::size_t orig_size
)
94 static string_literal
<CharT
> l
;
96 l
.assign(orig
, orig_size
);
100 #define LITERAL( s ) static_literal<CharT>( s, sizeof( s ) )
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()))\
108 //____________________________________________________________________________//
110 BOOST_TEST_CASE_TEMPLATE_FUNCTION( constructors_test
, CharT
)
113 utf::basic_cstring
<CharT
> bcs
;
114 BOOST_TEST( bcs
.size() == 0U );
115 BOOST_TEST( bcs
.is_empty() );
119 utf::basic_cstring
<CharT
> bcs( utf::basic_cstring
<CharT
>::null_str() );
120 BOOST_TEST( bcs
.size() == 0U );
121 BOOST_TEST( bcs
.is_empty() );
125 utf::basic_cstring
<CharT
> bcs( 0 );
126 BOOST_TEST( bcs
.size() == 0U );
127 BOOST_TEST( bcs
.is_empty() );
131 typedef typename
utf::basic_cstring
<CharT
>::traits_type traits
;
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
) );
137 utf::basic_cstring
<CharT
> bcs1( bcs
);
138 BOOST_TEST( traits::compare( bcs1
.begin(), TEST_STRING
, bcs1
.size() ) == 0 );
142 typedef typename
utf::basic_cstring
<CharT
>::traits_type traits
;
144 utf::basic_cstring
<CharT
> bcs( TEST_STRING
, 4 );
145 BOOST_TEST( traits::compare( bcs
.begin(), LITERAL( "test" ), bcs
.size() ) == 0 );
149 typedef typename
utf::basic_cstring
<CharT
>::traits_type traits
;
151 utf::basic_cstring
<CharT
> bcs( TEST_STRING
, TEST_STRING
+ 6 );
152 BOOST_TEST( traits::compare( bcs
.begin(), LITERAL( "test_s" ), bcs
.size() ) == 0 );
156 //____________________________________________________________________________//
158 BOOST_TEST_CASE_TEMPLATE_FUNCTION( constructors_std_string_test
, CharT
)
160 typedef typename
utf::basic_cstring
<CharT
>::traits_type traits
;
163 typename
utf::basic_cstring
<CharT
>::std_string
l( TEST_STRING
);
165 utf::basic_cstring
<CharT
> bcs( l
);
166 BOOST_TEST( traits::compare( bcs
.begin(), TEST_STRING
, bcs
.size() ) == 0 );
171 //____________________________________________________________________________//
173 void array_construction_test()
175 const_string bcs_array
[] = { "str1", "str2" };
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 );
180 const_string
bcs( "abc" );
181 BOOST_TEST( const_string::traits_type::compare( bcs
.begin(), "abc", bcs
.size() ) == 0 );
184 //____________________________________________________________________________//
186 BOOST_TEST_CASE_TEMPLATE_FUNCTION( data_access_test
, CharT
)
188 typedef typename
utf::basic_cstring
<CharT
>::traits_type traits_type
;
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 );
194 BOOST_TEST( bcs1
[0] == 't' );
195 BOOST_TEST( bcs1
[4] == '_' );
196 BOOST_TEST( bcs1
[bcs1
.size()-1] == 'g' );
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 );
204 BOOST_TEST( utf::first_char( bcs1
) == 't' );
205 BOOST_TEST( utf::last_char( bcs1
) == 'g' );
207 BOOST_TEST( utf::first_char( utf::basic_cstring
<CharT
>() ) == 0 );
208 BOOST_TEST( utf::last_char( utf::basic_cstring
<CharT
>() ) == 0 );
211 //____________________________________________________________________________//
213 BOOST_TEST_CASE_TEMPLATE_FUNCTION( size_test
, CharT
)
215 utf::basic_cstring
<CharT
> bcs1
;
217 BOOST_TEST( bcs1
.size() == 0U );
218 BOOST_TEST( bcs1
.is_empty() );
221 BOOST_TEST( bcs1
.size() == 11U );
224 BOOST_TEST( bcs1
.size() == 0U );
225 BOOST_TEST( bcs1
.is_empty() );
227 bcs1
= utf::basic_cstring
<CharT
>( TEST_STRING
, 4 );
228 BOOST_TEST( bcs1
.size() == 4U );
231 BOOST_TEST( bcs1
.size() == 4U );
234 BOOST_TEST( bcs1
.size() == 3U );
237 //____________________________________________________________________________//
239 BOOST_TEST_CASE_TEMPLATE_FUNCTION( asignment_test
, CharT
)
241 typedef typename
utf::basic_cstring
<CharT
>::traits_type traits_type
;
243 utf::basic_cstring
<CharT
> bcs1
;
244 string_literal
<CharT
> l( "test", 4 );
247 BOOST_TEST( traits_type::compare( bcs1
.begin(), LITERAL( "test" ), bcs1
.size() ) == 0 );
249 utf::basic_cstring
<CharT
> bcs2( TEST_STRING
);
251 BOOST_TEST( traits_type::compare( bcs1
.begin(), TEST_STRING
, bcs1
.size() ) == 0 );
253 bcs1
.assign( l
.begin() );
254 BOOST_TEST( traits_type::compare( bcs1
.begin(), LITERAL( "test" ), bcs1
.size() ) == 0 );
256 bcs1
.assign( l
.begin()+1, l
.begin()+3 );
257 BOOST_TEST( traits_type::compare( bcs1
.begin(), LITERAL( "est" ), bcs1
.size() ) == 0 );
259 bcs1
.assign( bcs2
, 4, 3 );
260 BOOST_TEST( traits_type::compare( bcs1
.begin(), LITERAL( "_st" ), bcs1
.size() ) == 0 );
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 );
267 //____________________________________________________________________________//
269 BOOST_TEST_CASE_TEMPLATE_FUNCTION( asignment_std_string_test
, CharT
)
271 typedef typename
utf::basic_cstring
<CharT
>::traits_type traits_type
;
273 utf::basic_cstring
<CharT
> bcs1
;
274 typename
utf::basic_cstring
<CharT
>::std_string
l( TEST_STRING
);
277 BOOST_TEST( traits_type::compare( bcs1
.begin(), TEST_STRING
, bcs1
.size() ) == 0 );
280 BOOST_TEST( traits_type::compare( bcs1
.begin(), TEST_STRING
, bcs1
.size() ) == 0 );
282 bcs1
.assign( l
, 1, 2 );
283 BOOST_TEST( traits_type::compare( bcs1
.begin(), LITERAL( "es" ), bcs1
.size() ) == 0 );
286 //____________________________________________________________________________//
288 BOOST_TEST_CASE_TEMPLATE_FUNCTION( comparison_test
, CharT
)
290 utf::basic_cstring
<CharT
> bcs1( TEST_STRING
);
291 utf::basic_cstring
<CharT
> bcs2( TEST_STRING
);
293 BOOST_TEST(( bcs1
== TEST_STRING
));
294 BOOST_TEST(( TEST_STRING
== bcs1
));
295 BOOST_TEST(( bcs1
== bcs2
));
299 BOOST_TEST(( bcs1
== LITERAL( "test" ) ));
301 BOOST_TEST(( bcs1
!= TEST_STRING
));
302 BOOST_TEST(( TEST_STRING
!= bcs1
));
303 BOOST_TEST(( bcs1
!= bcs2
));
305 LOCAL_DEF( bcs3
, "TeSt" );
306 BOOST_TEST( utf::case_ins_eq( bcs1
, bcs3
) );
309 //____________________________________________________________________________//
311 BOOST_TEST_DONT_PRINT_LOG_VALUE( std::wstring
)
313 BOOST_TEST_CASE_TEMPLATE_FUNCTION( comparison_std_string_test
, CharT
)
315 utf::basic_cstring
<CharT
> bcs1( TEST_STRING
);
316 typename
utf::basic_cstring
<CharT
>::std_string
l( TEST_STRING
);
318 BOOST_TEST( bcs1
== l
);
319 BOOST_TEST( l
== bcs1
);
323 BOOST_TEST( bcs1
!= l
);
324 BOOST_TEST( l
!= bcs1
);
327 //____________________________________________________________________________//
329 BOOST_TEST_CASE_TEMPLATE_FUNCTION( ordering_test
, CharT
)
331 LOCAL_DEF( bcs1
, "aBcd" );
332 LOCAL_DEF( bcs2
, "aBbdd" );
333 LOCAL_DEF( bcs3
, "aBbde" );
334 LOCAL_DEF( bcs4
, "abab" );
336 BOOST_TEST(( bcs1
< bcs2
));
337 BOOST_TEST(( bcs2
< bcs3
));
338 BOOST_TEST(( bcs1
< bcs3
));
339 BOOST_TEST(( bcs1
< bcs4
));
341 utf::case_ins_less
<CharT
> cil
;
342 BOOST_TEST( cil( bcs4
, bcs1
) );
345 //____________________________________________________________________________//
347 BOOST_TEST_CASE_TEMPLATE_FUNCTION( trim_test
, CharT
)
349 LOCAL_DEF( bcs0
, "tes" );
351 bcs0
.trim_right( 1 );
352 BOOST_TEST( bcs0
.size() == 2U );
353 BOOST_TEST( bcs0
[0] == 't' );
356 BOOST_TEST( bcs0
.size() == 1U );
357 BOOST_TEST( bcs0
[0] == 'e' );
360 BOOST_TEST( bcs0
.is_empty() );
363 bcs0
.trim_left( 11 );
364 BOOST_TEST( bcs0
.is_empty() );
367 bcs0
.trim_right( 11 );
368 BOOST_TEST( bcs0
.is_empty() );
371 bcs0
.trim_right( bcs0
.size() - bcs0
.find( LITERAL( "t_s" ) ) - 3 );
372 BOOST_TEST( bcs0
== LITERAL( "test_s" ) );
374 bcs0
.trim_left( bcs0
.find( LITERAL( "t_s" ) ) );
375 BOOST_TEST( bcs0
== LITERAL( "t_s" ) );
377 LOCAL_DEF( bcs1
, "abcd " );
378 LOCAL_DEF( bcs2
, " abcd" );
379 LOCAL_DEF( bcs3
, " abcd " );
382 BOOST_TEST( bcs1
== LITERAL( "abcd" ) );
385 BOOST_TEST( bcs2
== LITERAL( "abcd" ) );
387 bcs3
.trim( LITERAL( "\"" ) );
388 BOOST_TEST( bcs3
== LITERAL( " abcd " ) );
391 BOOST_TEST( bcs3
== LITERAL( "abcd" ) );
394 BOOST_TEST( bcs3
== LITERAL( "abcd" ) );
397 //____________________________________________________________________________//
399 BOOST_TEST_CASE_TEMPLATE_FUNCTION( io_test
, CharT
)
401 utf::basic_cstring
<CharT
> bcs1( TEST_STRING
);
402 bcs1
.trim_right( 7 );
404 tt::output_test_stream ostr
;
406 ostr
<< std::setw( 6 ) << bcs1
;
407 BOOST_TEST( ostr
.is_equal( " test" ) );
409 ostr
<< std::setw( 3 ) << bcs1
;
410 BOOST_TEST( ostr
.is_equal( "test" ) );
412 ostr
<< std::setw( 5 ) << std::setiosflags( std::ios::left
) << bcs1
;
413 BOOST_TEST( ostr
.is_equal( "test " ) );
416 //____________________________________________________________________________//
418 BOOST_TEST_CASE_TEMPLATE_FUNCTION( find_test
, CharT
)
420 typedef typename
utf::basic_cstring
<CharT
>::size_type size
;
421 utf::basic_cstring
<CharT
> bcs1( TEST_STRING
);
423 size not_found
= (size
)utf::basic_cstring
<CharT
>::npos
;
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
);
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
);
446 //____________________________________________________________________________//
448 void const_conversion()
450 char arr
[] = { "ABC" };
452 utf::basic_cstring
<char> str1( arr
);
453 utf::basic_cstring
<char const> str2
;
457 BOOST_TEST( str1
== "ABC" );
458 BOOST_TEST( str2
== "ABC" );
461 //____________________________________________________________________________//
463 #if defined(BOOST_TEST_STRING_VIEW)
464 BOOST_TEST_CASE_TEMPLATE_FUNCTION( string_view_support
, CharT
)
466 using namespace std::literals
;
467 typedef std::basic_string_view
<CharT
> string_view_t
;
468 namespace utf
= boost::unit_test
;
471 string_view_t sv
= LITERAL("");
473 utf::stringview_cstring_helper
<CharT
, string_view_t
> svh
= sv
;
474 BOOST_TEST( svh
.size() == 0U );
475 BOOST_TEST( svh
.is_empty() );
480 string_view_t sv
= LITERAL("bla");
482 utf::stringview_cstring_helper
<CharT
, string_view_t
> svh
= sv
;
483 BOOST_TEST( svh
.size() == 3U );
484 BOOST_TEST( !svh
.is_empty() );
490 //____________________________________________________________________________//
493 init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
495 utf::test_suite
* test
= BOOST_TEST_SUITE("basic_cstring test");
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
) );
512 #if defined(BOOST_TEST_STRING_VIEW)
513 test
->add( BOOST_TEST_CASE_TEMPLATE( string_view_support
, char_types
) );