Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / range / test / string.cpp
1 // Boost.Range library
2 //
3 //  Copyright Thorsten Ottosen 2003-2004. Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see http://www.boost.org/libs/range/
9 //
10
11 //#define _MSL_USING_NAMESPACE 1
12
13 #include <boost/detail/workaround.hpp>
14
15 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
16 #  pragma warn -8091 // suppress warning in Boost.Test
17 #  pragma warn -8057 // unused argument argc/argv in Boost.Test
18 #endif
19
20 #include <boost/array.hpp>
21 #include <boost/range/as_array.hpp>
22 #include <boost/range/as_literal.hpp>
23 #include <boost/range/functions.hpp>
24 #include <boost/range/metafunctions.hpp>
25 #include <boost/static_assert.hpp>
26 #include <boost/type_traits.hpp>
27 #include <boost/test/test_tools.hpp>
28 #include <boost/config.hpp>
29 #include <vector>
30 #include <fstream>
31 #include <algorithm>
32
33 namespace
34 {
35     template< class CharT, std::size_t Length >
36     class test_string
37     {
38     public:
39         typedef CharT value_type;
40         typedef value_type* pointer;
41         typedef const value_type* const_pointer;
42         typedef std::size_t size_type;
43         typedef value_type array_t[Length];
44         typedef const value_type const_array_t[Length];
45
46         explicit test_string(const CharT literal_sz[])
47         {
48             std::copy(literal_sz, literal_sz + Length, m_buffer.data());
49             m_buffer[Length] = value_type();
50         }
51
52         const_pointer const_sz() const { return m_buffer.data(); }
53         pointer mutable_sz() { return m_buffer.data(); }
54
55     private:
56         typedef boost::array<value_type, Length + 1> buffer_t;
57         buffer_t m_buffer;
58     };
59 }
60
61 template< class T >
62 inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type
63 str_begin( T& r )
64 {
65     return boost::begin( boost::as_literal(r) );
66 }
67
68 template< class T >
69 inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type
70 str_end( T& r )
71 {
72     return boost::end( boost::as_literal(r) );
73 }
74
75 template< class T >
76 inline BOOST_DEDUCED_TYPENAME boost::range_difference<T>::type
77 str_size( const T& r )
78 {
79     return boost::size( boost::as_literal(r) );
80 }
81
82 template< class T >
83 inline bool
84 str_empty( T& r )
85 {
86     return boost::empty( boost::as_literal(r) );
87 }
88
89 template< typename Container, typename T >
90 BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
91 find( Container& c,  T value )
92 {
93     return std::find( str_begin(c), str_end(c),
94                       value );
95 }
96
97 template< typename Container, typename T >
98 BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type
99 find( const Container& c, T value )
100 {
101     return std::find( str_begin(c), str_end(c),
102                       value );
103 }
104
105 template< typename Container, typename T >
106 BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
107 find_mutable( Container& c,  T value )
108 {
109     str_size( c );
110     return std::find( str_begin(c), str_end(c),
111                       value );
112 }
113
114 template< typename Container, typename T >
115 BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type
116 find_const( const Container& c, T value )
117 {
118     str_size( c );
119     return std::find( str_begin(c), str_end(c),
120                       value );
121 }
122
123
124 std::vector<char>
125 check_rvalue_return()
126 {
127     return std::vector<char>( 10, 'm' );
128 }
129
130 using namespace boost;
131
132
133 void check_char()
134 {
135     typedef boost::range_difference<std::string>::type diff_t;
136     typedef char*                  char_iterator_t;
137     typedef char                   char_array_t[10];
138
139     test_string<char, 8> a_string("a string");
140     test_string<char, 14> another_string("another string");
141
142     const char*      char_s = a_string.const_sz();
143     char             my_string[] = "another_string";
144     const char       my_const_string[] = "another string";
145     const diff_t     my_string_length = 14;
146     char*            char_s2 = a_string.mutable_sz();
147
148     BOOST_STATIC_ASSERT(( is_same<  range_value<char_iterator_t>::type,
149                                     detail::iterator_traits<char_iterator_t>::value_type>::value ));
150     BOOST_STATIC_ASSERT(( is_same<  range_iterator<char_iterator_t>::type, char_iterator_t >::value ));
151
152     BOOST_STATIC_ASSERT(( is_same<  range_difference<char_iterator_t>::type,
153                                     ::std::ptrdiff_t >::value ));
154     BOOST_STATIC_ASSERT(( is_same<  range_size<char_iterator_t>::type, std::size_t >::value ));
155     BOOST_STATIC_ASSERT(( is_same<  range_iterator<char_iterator_t>::type, char_iterator_t >::value ));
156     BOOST_STATIC_ASSERT(( is_same<  range_iterator<const char*>::type, const char* >::value ));
157
158     BOOST_STATIC_ASSERT(( is_same< range_value<char_array_t>::type,
159                                     char>::value ));
160     BOOST_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value ));
161     BOOST_STATIC_ASSERT(( is_same< range_iterator<const char_array_t>::type, const char* >::value ));
162     BOOST_STATIC_ASSERT(( is_same< range_difference<char_array_t>::type,
163                                     ::std::ptrdiff_t >::value ));
164     BOOST_STATIC_ASSERT(( is_same< range_size<char_array_t>::type, std::size_t >::value ));
165     BOOST_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value ));
166     BOOST_STATIC_ASSERT(( is_same< range_iterator<const char_array_t>::type, const char* >::value ));
167
168     BOOST_CHECK_EQUAL( str_begin( char_s ), char_s );
169     const diff_t sz = str_size(char_s);
170     const char* str_end1 = str_begin( char_s ) + sz;
171     BOOST_CHECK_EQUAL( str_end( char_s ), str_end1 );
172     BOOST_CHECK_EQUAL( str_empty( char_s ), (char_s == 0 || char_s[0] == char()) );
173     BOOST_CHECK_EQUAL( sz, static_cast<diff_t>(std::char_traits<char>::length(char_s)) );
174
175     BOOST_CHECK_EQUAL( str_begin( my_string ), my_string );
176     range_iterator<char_array_t>::type str_end2 = str_begin( my_string ) + str_size(my_string);
177     range_iterator<char_array_t>::type str_end3 = str_end(my_string);
178     BOOST_CHECK_EQUAL( str_end3, str_end2 );
179     BOOST_CHECK_EQUAL( str_empty( my_string ), (my_string == 0 || my_string[0] == char()) );
180     BOOST_CHECK_EQUAL( str_size( my_string ), my_string_length );
181     BOOST_CHECK_EQUAL( str_size( my_string ), static_cast<diff_t>(std::char_traits<char>::length(my_string)) );
182
183     char to_search = 'n';
184     BOOST_CHECK( find_mutable( char_s, to_search ) != str_end( char_s ) );
185     BOOST_CHECK( find_const( char_s, to_search ) != str_end(char_s) );
186
187     BOOST_CHECK( find_mutable( my_string, to_search ) != str_end(my_string) );
188     BOOST_CHECK( find_const( my_string, to_search ) != str_end(my_string) );
189
190     BOOST_CHECK( find_mutable( char_s2, to_search ) != str_end(char_s) );
191     BOOST_CHECK( find_const( char_s2, to_search ) != str_end(char_s2) );
192
193     BOOST_CHECK( find_const( as_array( my_string ), to_search ) != str_end(my_string) );
194     BOOST_CHECK( find_const( as_array( my_const_string ), to_search ) != str_end(my_string) );
195
196     //
197     // Test that as_literal() always scan for null terminator
198     //
199     char an_array[] = "foo\0bar";
200     BOOST_CHECK_EQUAL( str_begin( an_array ), an_array );
201     BOOST_CHECK_EQUAL( str_end( an_array ), an_array + 3 );
202     BOOST_CHECK_EQUAL( str_size( an_array ), 3 );
203
204     const char a_const_array[] = "foobar\0doh";
205     BOOST_CHECK_EQUAL( str_begin( a_const_array ), a_const_array );
206     BOOST_CHECK_EQUAL( str_end( a_const_array ), a_const_array + 6 );
207     BOOST_CHECK_EQUAL( str_size( a_const_array ), 6 );
208
209 }
210
211
212
213 void check_string()
214 {
215     check_char();
216
217 #ifndef BOOST_NO_STD_WSTRING
218     typedef wchar_t*               wchar_iterator_t;
219
220     test_string<wchar_t, 13> a_wide_string(L"a wide string");
221     test_string<wchar_t, 19> another_wide_string(L"another wide string");
222
223     const wchar_t*  char_ws      = a_wide_string.const_sz();
224     wchar_t         my_wstring[] = L"another wide string";
225     wchar_t*        char_ws2     = a_wide_string.mutable_sz();
226
227     BOOST_STATIC_ASSERT(( is_same< range_value<wchar_iterator_t>::type,
228                                    detail::iterator_traits<wchar_iterator_t>::value_type>::value ));
229     BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value ));
230     BOOST_STATIC_ASSERT(( is_same< range_iterator<const wchar_t*>::type, const wchar_t* >::value ));
231     BOOST_STATIC_ASSERT(( is_same< range_difference<wchar_iterator_t>::type,
232                                    detail::iterator_traits<wchar_iterator_t>::difference_type >::value ));
233     BOOST_STATIC_ASSERT(( is_same< range_size<wchar_iterator_t>::type, std::size_t >::value ));
234     BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value ));
235     BOOST_STATIC_ASSERT(( is_same< range_iterator<const wchar_t*>::type, const wchar_t* >::value ));
236
237     typedef boost::range_difference<std::wstring>::type diff_t;
238     const diff_t sz = str_size( char_ws );
239     BOOST_CHECK_EQUAL( str_begin( char_ws ), char_ws );
240     BOOST_CHECK_EQUAL( str_end(char_ws), (str_begin( char_ws ) + sz) );
241     BOOST_CHECK_EQUAL( str_empty( char_ws ), (char_ws == 0 || char_ws[0] == wchar_t()) );
242     BOOST_CHECK_EQUAL( sz, static_cast<diff_t>(std::char_traits<wchar_t>::length(char_ws)) );
243
244     wchar_t to_search = L'n';
245     BOOST_CHECK( find( char_ws, to_search ) != str_end(char_ws) );
246     BOOST_CHECK( find( char_ws2, to_search ) != str_end(char_ws2) );
247
248 #if BOOST_WORKAROUND(_MSC_VER, BOOST_TESTED_AT(1300))
249
250     BOOST_CHECK( find( my_wstring, to_search ) != str_end(my_wstring) );
251
252 #else
253
254     boost::ignore_unused_variable_warning( my_wstring );
255
256 #endif
257 #endif
258
259     find( check_rvalue_return(), 'n' );
260
261 }
262
263 #include <boost/test/unit_test.hpp>
264 using boost::unit_test::test_suite;
265
266
267 test_suite* init_unit_test_suite( int argc, char* argv[] )
268 {
269     test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
270
271     test->add( BOOST_TEST_CASE( &check_string ) );
272
273     return test;
274 }
275
276
277
278
279
280