]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | Copyright (c) Marshall Clow 2012-2012. | |
3 | ||
4 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | For more information, see http://www.boost.org | |
8 | */ | |
9 | ||
10 | #include <iostream> | |
11 | #include <cstring> // for std::strchr | |
12 | ||
13 | #include <boost/utility/string_ref.hpp> | |
14 | ||
15 | #define BOOST_TEST_MAIN | |
16 | #include <boost/test/unit_test.hpp> | |
17 | ||
18 | typedef boost::string_ref string_ref; | |
19 | ||
20 | void ends_with ( const char *arg ) { | |
21 | const size_t sz = std::strlen ( arg ); | |
22 | string_ref sr ( arg ); | |
23 | string_ref sr2 ( arg ); | |
24 | const char *p = arg; | |
25 | ||
26 | while ( *p ) { | |
27 | BOOST_CHECK ( sr.ends_with ( p )); | |
28 | ++p; | |
29 | } | |
30 | ||
31 | while ( !sr2.empty ()) { | |
32 | BOOST_CHECK ( sr.ends_with ( sr2 )); | |
33 | sr2.remove_prefix (1); | |
34 | } | |
35 | ||
36 | sr2 = arg; | |
37 | while ( !sr2.empty ()) { | |
38 | BOOST_CHECK ( sr.ends_with ( sr2 )); | |
39 | sr2.remove_prefix (1); | |
40 | } | |
41 | ||
42 | char ch = sz == 0 ? '\0' : arg [ sz - 1 ]; | |
43 | sr2 = arg; | |
44 | if ( sz > 0 ) | |
45 | BOOST_CHECK ( sr2.ends_with ( ch )); | |
46 | BOOST_CHECK ( !sr2.ends_with ( ++ch )); | |
47 | BOOST_CHECK ( sr2.ends_with ( string_ref ())); | |
48 | } | |
49 | ||
50 | void starts_with ( const char *arg ) { | |
51 | const size_t sz = std::strlen ( arg ); | |
52 | string_ref sr ( arg ); | |
53 | string_ref sr2 ( arg ); | |
54 | const char *p = arg + std::strlen ( arg ) - 1; | |
55 | while ( p >= arg ) { | |
56 | std::string foo ( arg, p + 1 ); | |
57 | BOOST_CHECK ( sr.starts_with ( foo )); | |
58 | --p; | |
59 | } | |
60 | ||
61 | while ( !sr2.empty ()) { | |
62 | BOOST_CHECK ( sr.starts_with ( sr2 )); | |
63 | sr2.remove_suffix (1); | |
64 | } | |
65 | ||
66 | char ch = *arg; | |
67 | sr2 = arg; | |
68 | if ( sz > 0 ) | |
69 | BOOST_CHECK ( sr2.starts_with ( ch )); | |
70 | BOOST_CHECK ( !sr2.starts_with ( ++ch )); | |
71 | BOOST_CHECK ( sr2.starts_with ( string_ref ())); | |
72 | } | |
73 | ||
74 | void reverse ( const char *arg ) { | |
75 | // Round trip | |
76 | string_ref sr1 ( arg ); | |
77 | std::string string1 ( sr1.rbegin (), sr1.rend ()); | |
78 | string_ref sr2 ( string1 ); | |
79 | std::string string2 ( sr2.rbegin (), sr2.rend ()); | |
80 | ||
81 | BOOST_CHECK ( std::equal ( sr2.rbegin (), sr2.rend (), arg )); | |
82 | BOOST_CHECK ( string2 == arg ); | |
83 | BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ())); | |
84 | } | |
85 | ||
86 | // This helper function eliminates signed vs. unsigned warnings | |
87 | string_ref::size_type ptr_diff ( const char *res, const char *base ) { | |
88 | BOOST_CHECK ( res >= base ); | |
89 | return static_cast<string_ref::size_type> ( res - base ); | |
90 | } | |
91 | ||
92 | void find ( const char *arg ) { | |
93 | string_ref sr1; | |
94 | string_ref sr2; | |
95 | const char *p; | |
96 | ||
97 | // Look for each character in the string(searching from the start) | |
98 | p = arg; | |
99 | sr1 = arg; | |
100 | while ( *p ) { | |
101 | string_ref::size_type pos = sr1.find(*p); | |
102 | BOOST_CHECK ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg ))); | |
103 | ++p; | |
104 | } | |
105 | ||
106 | // Look for each character in the string (searching from the end) | |
107 | p = arg; | |
108 | sr1 = arg; | |
109 | while ( *p ) { | |
110 | string_ref::size_type pos = sr1.rfind(*p); | |
111 | BOOST_CHECK ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg ))); | |
112 | ++p; | |
113 | } | |
114 | ||
115 | // Look for pairs on characters (searching from the start) | |
116 | sr1 = arg; | |
117 | p = arg; | |
118 | while ( *p && *(p+1)) { | |
119 | string_ref sr3 ( p, 2 ); | |
120 | string_ref::size_type pos = sr1.find ( sr3 ); | |
121 | BOOST_CHECK ( pos != string_ref::npos && pos <= static_cast<string_ref::size_type>( p - arg )); | |
122 | p++; | |
123 | } | |
124 | ||
125 | sr1 = arg; | |
126 | p = arg; | |
127 | // for all possible chars, see if we find them in the right place. | |
128 | // Note that strchr will/might do the _wrong_ thing if we search for NULL | |
129 | for ( int ch = 1; ch < 256; ++ch ) { | |
130 | string_ref::size_type pos = sr1.find(ch); | |
131 | const char *strp = std::strchr ( arg, ch ); | |
132 | BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos )); | |
133 | if ( strp != NULL ) | |
134 | BOOST_CHECK ( ptr_diff ( strp, arg ) == pos ); | |
135 | } | |
136 | ||
137 | sr1 = arg; | |
138 | p = arg; | |
139 | // for all possible chars, see if we find them in the right place. | |
140 | // Note that strchr will/might do the _wrong_ thing if we search for NULL | |
141 | for ( int ch = 1; ch < 256; ++ch ) { | |
142 | string_ref::size_type pos = sr1.rfind(ch); | |
143 | const char *strp = std::strrchr ( arg, ch ); | |
144 | BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos )); | |
145 | if ( strp != NULL ) | |
146 | BOOST_CHECK ( ptr_diff ( strp, arg ) == pos ); | |
147 | } | |
148 | ||
149 | ||
150 | // Find everything at the start | |
151 | p = arg; | |
152 | sr1 = arg; | |
153 | while ( !sr1.empty ()) { | |
154 | string_ref::size_type pos = sr1.find(*p); | |
155 | BOOST_CHECK ( pos == 0 ); | |
156 | sr1.remove_prefix (1); | |
157 | ++p; | |
158 | } | |
159 | ||
160 | // Find everything at the end | |
161 | sr1 = arg; | |
162 | p = arg + std::strlen ( arg ) - 1; | |
163 | while ( !sr1.empty ()) { | |
164 | string_ref::size_type pos = sr1.rfind(*p); | |
165 | BOOST_CHECK ( pos == sr1.size () - 1 ); | |
166 | sr1.remove_suffix (1); | |
167 | --p; | |
168 | } | |
169 | ||
170 | // Find everything at the start | |
171 | sr1 = arg; | |
172 | p = arg; | |
173 | while ( !sr1.empty ()) { | |
174 | string_ref::size_type pos = sr1.find_first_of(*p); | |
175 | BOOST_CHECK ( pos == 0 ); | |
176 | sr1.remove_prefix (1); | |
177 | ++p; | |
178 | } | |
179 | ||
180 | ||
181 | // Find everything at the end | |
182 | sr1 = arg; | |
183 | p = arg + std::strlen ( arg ) - 1; | |
184 | while ( !sr1.empty ()) { | |
185 | string_ref::size_type pos = sr1.find_last_of(*p); | |
186 | BOOST_CHECK ( pos == sr1.size () - 1 ); | |
187 | sr1.remove_suffix (1); | |
188 | --p; | |
189 | } | |
190 | ||
191 | // Basic sanity checking for "find_first_of / find_first_not_of" | |
192 | sr1 = arg; | |
193 | sr2 = arg; | |
194 | while ( !sr1.empty() ) { | |
195 | BOOST_CHECK ( sr1.find_first_of ( sr2 ) == 0 ); | |
196 | BOOST_CHECK ( sr1.find_first_not_of ( sr2 ) == string_ref::npos ); | |
197 | sr1.remove_prefix ( 1 ); | |
198 | } | |
199 | ||
200 | p = arg; | |
201 | sr1 = arg; | |
202 | while ( *p ) { | |
203 | string_ref::size_type pos1 = sr1.find_first_of(*p); | |
204 | string_ref::size_type pos2 = sr1.find_first_not_of(*p); | |
205 | BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg )); | |
206 | if ( pos2 != string_ref::npos ) { | |
207 | for ( size_t i = 0 ; i < pos2; ++i ) | |
208 | BOOST_CHECK ( sr1[i] == *p ); | |
209 | BOOST_CHECK ( sr1 [ pos2 ] != *p ); | |
210 | } | |
211 | ||
212 | BOOST_CHECK ( pos2 != pos1 ); | |
213 | ++p; | |
214 | } | |
215 | ||
216 | // Basic sanity checking for "find_last_of / find_last_not_of" | |
217 | sr1 = arg; | |
218 | sr2 = arg; | |
219 | while ( !sr1.empty() ) { | |
220 | BOOST_CHECK ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 )); | |
221 | BOOST_CHECK ( sr1.find_last_not_of ( sr2 ) == string_ref::npos ); | |
222 | sr1.remove_suffix ( 1 ); | |
223 | } | |
224 | ||
225 | p = arg; | |
226 | sr1 = arg; | |
227 | while ( *p ) { | |
228 | string_ref::size_type pos1 = sr1.find_last_of(*p); | |
229 | string_ref::size_type pos2 = sr1.find_last_not_of(*p); | |
230 | BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg )); | |
231 | BOOST_CHECK ( pos2 == string_ref::npos || pos1 < sr1.size ()); | |
232 | if ( pos2 != string_ref::npos ) { | |
233 | for ( size_t i = sr1.size () -1 ; i > pos2; --i ) | |
234 | BOOST_CHECK ( sr1[i] == *p ); | |
235 | BOOST_CHECK ( sr1 [ pos2 ] != *p ); | |
236 | } | |
237 | ||
238 | BOOST_CHECK ( pos2 != pos1 ); | |
239 | ++p; | |
240 | } | |
241 | ||
242 | } | |
243 | ||
244 | ||
245 | void to_string ( const char *arg ) { | |
246 | string_ref sr1; | |
247 | std::string str1; | |
248 | std::string str2; | |
249 | ||
250 | str1.assign ( arg ); | |
251 | sr1 = arg; | |
252 | // str2 = sr1.to_string<std::allocator<char> > (); | |
253 | str2 = sr1.to_string (); | |
254 | BOOST_CHECK ( str1 == str2 ); | |
255 | ||
256 | #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS | |
257 | std::string str3 = static_cast<std::string> ( sr1 ); | |
258 | BOOST_CHECK ( str1 == str3 ); | |
259 | #endif | |
260 | } | |
261 | ||
262 | void compare ( const char *arg ) { | |
263 | string_ref sr1; | |
264 | std::string str1; | |
265 | std::string str2 = str1; | |
266 | ||
267 | str1.assign ( arg ); | |
268 | sr1 = arg; | |
269 | BOOST_CHECK ( sr1 == sr1); // compare string_ref and string_ref | |
270 | BOOST_CHECK ( sr1 == str1); // compare string and string_ref | |
271 | BOOST_CHECK ( str1 == sr1 ); // compare string_ref and string | |
272 | BOOST_CHECK ( sr1 == arg ); // compare string_ref and pointer | |
273 | BOOST_CHECK ( arg == sr1 ); // compare pointer and string_ref | |
274 | ||
275 | if ( sr1.size () > 0 ) { | |
276 | (*str1.rbegin())++; | |
277 | BOOST_CHECK ( sr1 != str1 ); | |
278 | BOOST_CHECK ( str1 != sr1 ); | |
279 | BOOST_CHECK ( sr1 < str1 ); | |
280 | BOOST_CHECK ( sr1 <= str1 ); | |
281 | BOOST_CHECK ( str1 > sr1 ); | |
282 | BOOST_CHECK ( str1 >= sr1 ); | |
283 | ||
284 | (*str1.rbegin()) -= 2; | |
285 | BOOST_CHECK ( sr1 != str1 ); | |
286 | BOOST_CHECK ( str1 != sr1 ); | |
287 | BOOST_CHECK ( sr1 > str1 ); | |
288 | BOOST_CHECK ( sr1 >= str1 ); | |
289 | BOOST_CHECK ( str1 < sr1 ); | |
290 | BOOST_CHECK ( str1 <= sr1 ); | |
291 | } | |
292 | } | |
293 | ||
294 | const char *test_strings [] = { | |
295 | "", | |
296 | "0", | |
297 | "abc", | |
298 | "AAA", // all the same | |
299 | "adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf", | |
300 | "abc\0asdfadsfasf", | |
301 | NULL | |
302 | }; | |
303 | ||
304 | BOOST_AUTO_TEST_CASE( test_main ) | |
305 | { | |
306 | const char **p = &test_strings[0]; | |
307 | ||
308 | while ( *p != NULL ) { | |
309 | starts_with ( *p ); | |
310 | ends_with ( *p ); | |
311 | reverse ( *p ); | |
312 | find ( *p ); | |
313 | to_string ( *p ); | |
314 | compare ( *p ); | |
315 | ||
316 | p++; | |
317 | } | |
318 | } |