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