1 | // (C) Copyright Gennadiy Rozental 2001. |
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 : class basic_cstring wraps C string and provide std_string like |
13 | // interface |
14 | // *************************************************************************** |
15 | |
16 | #ifndef BOOST_TEST_UTILS_BASIC_CSTRING_HPP |
17 | #define BOOST_TEST_UTILS_BASIC_CSTRING_HPP |
18 | |
19 | // Boost.Test |
20 | #include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp> |
21 | #include <boost/test/utils/basic_cstring/bcs_char_traits.hpp> |
22 | |
23 | // Boost |
24 | #include <boost/type_traits/remove_cv.hpp> |
25 | |
26 | // STL |
27 | #include <string> |
28 | |
29 | #include <boost/test/detail/suppress_warnings.hpp> |
30 | |
31 | //____________________________________________________________________________// |
32 | |
33 | namespace boost { |
34 | |
35 | namespace unit_test { |
36 | |
37 | // ************************************************************************** // |
38 | // ************** basic_cstring ************** // |
39 | // ************************************************************************** // |
40 | |
41 | template<typename CharT> |
42 | class basic_cstring { |
43 | typedef basic_cstring<CharT> self_type; |
44 | public: |
45 | // Subtypes |
46 | typedef ut_detail::bcs_char_traits<CharT> traits_type; |
47 | typedef typename ut_detail::bcs_char_traits<CharT>::std_string std_string; |
48 | |
49 | typedef CharT value_type; |
50 | typedef typename remove_cv<value_type>::type value_ret_type; |
51 | typedef value_type* pointer; |
52 | typedef value_type const* const_pointer; |
53 | typedef value_type& reference; |
54 | typedef const value_type& const_reference; |
55 | typedef std::size_t size_type; |
56 | typedef std::ptrdiff_t difference_type; |
57 | |
58 | typedef value_type const* const_iterator; |
59 | typedef value_type* iterator; |
60 | |
61 | // !! should also present reverse_iterator, const_reverse_iterator |
62 | |
63 | #if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) |
64 | enum npos_type { npos = static_cast<size_type>(-1) }; |
65 | #else |
66 | // IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes. |
67 | // But size_type is 8 bytes in 64bit mode. |
68 | static const size_type npos = -1 ; |
69 | #endif |
70 | |
71 | static pointer null_str(); |
72 | |
73 | // Constructors; default copy constructor is generated by compiler |
74 | basic_cstring(); |
75 | basic_cstring( std_string const& s ); |
76 | basic_cstring( pointer s ); |
77 | template<typename LenType> |
78 | basic_cstring( pointer s, LenType len ) : m_begin( s ), m_end( m_begin + len ) {} |
79 | basic_cstring( pointer first, pointer last ); |
80 | |
81 | // data access methods |
82 | value_ret_type operator[]( size_type index ) const; |
83 | value_ret_type at( size_type index ) const; |
84 | |
85 | // size operators |
86 | size_type size() const; |
87 | bool is_empty() const; |
88 | void clear(); |
89 | void resize( size_type new_len ); |
90 | |
91 | // !! only for STL container conformance use is_empty instead |
92 | bool empty() const; |
93 | |
94 | // Trimming |
95 | self_type& trim_right( size_type trim_size ); |
96 | self_type& trim_left( size_type trim_size ); |
97 | self_type& trim_right( iterator it ); |
98 | self_type& trim_left( iterator it ); |
99 | #if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(800)) |
100 | self_type& trim_left( self_type exclusions = self_type() ) ; |
101 | self_type& trim_right( self_type exclusions = self_type() ) ; |
102 | self_type& trim( self_type exclusions = self_type() ) ; |
103 | #else |
104 | // VA C++/XL C++ v6 and v8 has in this case a problem with the default arguments. |
105 | self_type& trim_left( self_type exclusions ); |
106 | self_type& trim_right( self_type exclusions ); |
107 | self_type& trim( self_type exclusions ); |
108 | self_type& trim_left() { return trim_left( self_type() ); } |
109 | self_type& trim_right() { return trim_right( self_type() ); } |
110 | self_type& trim() { return trim( self_type() ); } |
111 | #endif |
112 | |
113 | // Assignment operators |
114 | basic_cstring& operator=( self_type const& s ); |
115 | basic_cstring& operator=( std_string const& s ); |
116 | basic_cstring& operator=( pointer s ); |
117 | |
118 | template<typename CharT2> |
119 | basic_cstring& assign( basic_cstring<CharT2> const& s ) |
120 | { |
121 | return *this = basic_cstring<CharT>( s.begin(), s.end() ); |
122 | } |
123 | template<typename PosType, typename LenType> |
124 | basic_cstring& assign( self_type const& s, PosType pos, LenType len ) |
125 | { |
126 | return *this = self_type( s.m_begin + pos, len ); |
127 | } |
128 | |
129 | basic_cstring& assign( std_string const& s ); |
130 | template<typename PosType, typename LenType> |
131 | basic_cstring& assign( std_string const& s, PosType pos, LenType len ) |
132 | { |
133 | return *this = self_type( s.c_str() + pos, len ); |
134 | } |
135 | basic_cstring& assign( pointer s ); |
136 | template<typename LenType> |
137 | basic_cstring& assign( pointer s, LenType len ) |
138 | { |
139 | return *this = self_type( s, len ); |
140 | } |
141 | basic_cstring& assign( pointer f, pointer l ); |
142 | |
143 | // swapping |
144 | void swap( self_type& s ); |
145 | |
146 | // Iterators |
147 | iterator begin(); |
148 | const_iterator begin() const; |
149 | iterator end(); |
150 | const_iterator end() const; |
151 | |
152 | // !! should have rbegin, rend |
153 | |
154 | // substring search operation |
155 | size_type find( basic_cstring ) const; |
156 | size_type rfind( basic_cstring ) const; |
157 | self_type substr( size_type beg_index, size_type end_index = npos ) const; |
158 | |
159 | private: |
160 | static self_type default_trim_ex(); |
161 | |
162 | // Data members |
163 | iterator m_begin; |
164 | iterator m_end; |
165 | }; |
166 | |
167 | //____________________________________________________________________________// |
168 | |
169 | template<typename CharT> |
170 | inline typename basic_cstring<CharT>::pointer |
171 | basic_cstring<CharT>::null_str() |
172 | { |
173 | static CharT null = 0; |
174 | return &null; |
175 | } |
176 | |
177 | //____________________________________________________________________________// |
178 | |
179 | template<typename CharT> |
180 | inline |
181 | basic_cstring<CharT>::basic_cstring() |
182 | : m_begin( null_str() ) |
183 | , m_end( m_begin ) |
184 | { |
185 | } |
186 | |
187 | //____________________________________________________________________________// |
188 | |
189 | template<typename CharT> |
190 | inline |
191 | basic_cstring<CharT>::basic_cstring( std_string const& s ) |
192 | : m_begin( s.c_str() ) |
193 | , m_end( m_begin + s.size() ) |
194 | { |
195 | } |
196 | |
197 | //____________________________________________________________________________// |
198 | |
199 | template<typename CharT> |
200 | inline |
201 | basic_cstring<CharT>::basic_cstring( pointer s ) |
202 | : m_begin( s ? s : null_str() ) |
203 | , m_end ( m_begin + (s ? traits_type::length( s ) : 0 ) ) |
204 | { |
205 | } |
206 | |
207 | //____________________________________________________________________________// |
208 | |
209 | template<typename CharT> |
210 | inline |
211 | basic_cstring<CharT>::basic_cstring( pointer first, pointer last ) |
212 | : m_begin( first ) |
213 | , m_end( last ) |
214 | { |
215 | } |
216 | |
217 | //____________________________________________________________________________// |
218 | |
219 | template<typename CharT> |
220 | inline typename basic_cstring<CharT>::value_ret_type |
221 | basic_cstring<CharT>::operator[]( size_type index ) const |
222 | { |
223 | return m_begin[index]; |
224 | } |
225 | |
226 | //____________________________________________________________________________// |
227 | |
228 | template<typename CharT> |
229 | inline typename basic_cstring<CharT>::value_ret_type |
230 | basic_cstring<CharT>::at( size_type index ) const |
231 | { |
232 | if( m_begin + index >= m_end ) |
233 | return static_cast<value_type>(0); |
234 | |
235 | return m_begin[index]; |
236 | } |
237 | |
238 | //____________________________________________________________________________// |
239 | |
240 | template<typename CharT> |
241 | inline typename basic_cstring<CharT>::size_type |
242 | basic_cstring<CharT>::size() const |
243 | { |
244 | return static_cast<size_type>(m_end - m_begin); |
245 | } |
246 | |
247 | //____________________________________________________________________________// |
248 | |
249 | template<typename CharT> |
250 | inline bool |
251 | basic_cstring<CharT>::is_empty() const |
252 | { |
253 | return m_end == m_begin; |
254 | } |
255 | |
256 | //____________________________________________________________________________// |
257 | |
258 | template<typename CharT> |
259 | inline bool |
260 | basic_cstring<CharT>::empty() const |
261 | { |
262 | return is_empty(); |
263 | } |
264 | |
265 | //____________________________________________________________________________// |
266 | |
267 | template<typename CharT> |
268 | inline void |
269 | basic_cstring<CharT>::clear() |
270 | { |
271 | m_begin = m_end; |
272 | } |
273 | |
274 | //____________________________________________________________________________// |
275 | |
276 | template<typename CharT> |
277 | inline void |
278 | basic_cstring<CharT>::resize( size_type new_len ) |
279 | { |
280 | if( m_begin + new_len < m_end ) |
281 | m_end = m_begin + new_len; |
282 | } |
283 | |
284 | //____________________________________________________________________________// |
285 | |
286 | template<typename CharT> |
287 | inline basic_cstring<CharT>& |
288 | basic_cstring<CharT>::trim_left( size_type trim_size ) |
289 | { |
290 | m_begin += trim_size; |
291 | if( m_end <= m_begin ) |
292 | clear(); |
293 | |
294 | return *this; |
295 | } |
296 | |
297 | //____________________________________________________________________________// |
298 | |
299 | template<typename CharT> |
300 | inline basic_cstring<CharT>& |
301 | basic_cstring<CharT>::trim_left( iterator it ) |
302 | { |
303 | m_begin = it; |
304 | if( m_end <= m_begin ) |
305 | clear(); |
306 | |
307 | return *this; |
308 | } |
309 | |
310 | //____________________________________________________________________________// |
311 | |
312 | template<typename CharT> |
313 | inline basic_cstring<CharT>& |
314 | basic_cstring<CharT>::trim_left( basic_cstring exclusions ) |
315 | { |
316 | if( exclusions.is_empty() ) |
317 | exclusions = default_trim_ex(); |
318 | |
319 | iterator it; |
320 | for( it = begin(); it != end(); ++it ) { |
321 | if( traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) ) |
322 | break; |
323 | } |
324 | |
325 | return trim_left( it ); |
326 | } |
327 | |
328 | //____________________________________________________________________________// |
329 | |
330 | template<typename CharT> |
331 | inline basic_cstring<CharT>& |
332 | basic_cstring<CharT>::trim_right( size_type trim_size ) |
333 | { |
334 | m_end -= trim_size; |
335 | if( m_end <= m_begin ) |
336 | clear(); |
337 | |
338 | return *this; |
339 | } |
340 | |
341 | //____________________________________________________________________________// |
342 | |
343 | template<typename CharT> |
344 | inline basic_cstring<CharT>& |
345 | basic_cstring<CharT>::trim_right( iterator it ) |
346 | { |
347 | m_end = it; |
348 | if( m_end <= m_begin ) |
349 | clear(); |
350 | |
351 | return *this; |
352 | } |
353 | |
354 | //____________________________________________________________________________// |
355 | |
356 | template<typename CharT> |
357 | inline basic_cstring<CharT>& |
358 | basic_cstring<CharT>::trim_right( basic_cstring exclusions ) |
359 | { |
360 | if( exclusions.is_empty() ) |
361 | exclusions = default_trim_ex(); |
362 | |
363 | iterator it; |
364 | |
365 | for( it = end()-1; it != begin()-1; --it ) { |
366 | if( self_type::traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) ) |
367 | break; |
368 | } |
369 | |
370 | return trim_right( it+1 ); |
371 | } |
372 | |
373 | //____________________________________________________________________________// |
374 | |
375 | template<typename CharT> |
376 | inline basic_cstring<CharT>& |
377 | basic_cstring<CharT>::trim( basic_cstring exclusions ) |
378 | { |
379 | trim_left( exclusions ); |
380 | trim_right( exclusions ); |
381 | |
382 | return *this; |
383 | } |
384 | |
385 | //____________________________________________________________________________// |
386 | |
387 | template<typename CharT> |
388 | inline basic_cstring<CharT>& |
389 | basic_cstring<CharT>::operator=( basic_cstring<CharT> const& s ) |
390 | { |
391 | m_begin = s.m_begin; |
392 | m_end = s.m_end; |
393 | |
394 | return *this; |
395 | } |
396 | |
397 | //____________________________________________________________________________// |
398 | |
399 | template<typename CharT> |
400 | inline basic_cstring<CharT>& |
401 | basic_cstring<CharT>::operator=( std_string const& s ) |
402 | { |
403 | return *this = self_type( s ); |
404 | } |
405 | |
406 | //____________________________________________________________________________// |
407 | |
408 | template<typename CharT> |
409 | inline basic_cstring<CharT>& |
410 | basic_cstring<CharT>::operator=( pointer s ) |
411 | { |
412 | return *this = self_type( s ); |
413 | } |
414 | |
415 | //____________________________________________________________________________// |
416 | |
417 | template<typename CharT> |
418 | inline basic_cstring<CharT>& |
419 | basic_cstring<CharT>::assign( std_string const& s ) |
420 | { |
421 | return *this = self_type( s ); |
422 | } |
423 | |
424 | //____________________________________________________________________________// |
425 | |
426 | template<typename CharT> |
427 | inline basic_cstring<CharT>& |
428 | basic_cstring<CharT>::assign( pointer s ) |
429 | { |
430 | return *this = self_type( s ); |
431 | } |
432 | |
433 | //____________________________________________________________________________// |
434 | |
435 | template<typename CharT> |
436 | inline basic_cstring<CharT>& |
437 | basic_cstring<CharT>::assign( pointer f, pointer l ) |
438 | { |
439 | return *this = self_type( f, l ); |
440 | } |
441 | |
442 | //____________________________________________________________________________// |
443 | |
444 | template<typename CharT> |
445 | inline void |
446 | basic_cstring<CharT>::swap( basic_cstring<CharT>& s ) |
447 | { |
448 | // do not want to include alogrithm |
449 | pointer tmp1 = m_begin; |
450 | pointer tmp2 = m_end; |
451 | |
452 | m_begin = s.m_begin; |
453 | m_end = s.m_end; |
454 | |
455 | s.m_begin = tmp1; |
456 | s.m_end = tmp2; |
457 | } |
458 | |
459 | //____________________________________________________________________________// |
460 | |
461 | template<typename CharT> |
462 | inline typename basic_cstring<CharT>::iterator |
463 | basic_cstring<CharT>::begin() |
464 | { |
465 | return m_begin; |
466 | } |
467 | |
468 | //____________________________________________________________________________// |
469 | |
470 | template<typename CharT> |
471 | inline typename basic_cstring<CharT>::const_iterator |
472 | basic_cstring<CharT>::begin() const |
473 | { |
474 | return m_begin; |
475 | } |
476 | |
477 | //____________________________________________________________________________// |
478 | |
479 | template<typename CharT> |
480 | inline typename basic_cstring<CharT>::iterator |
481 | basic_cstring<CharT>::end() |
482 | { |
483 | return m_end; |
484 | } |
485 | |
486 | //____________________________________________________________________________// |
487 | |
488 | template<typename CharT> |
489 | inline typename basic_cstring<CharT>::const_iterator |
490 | basic_cstring<CharT>::end() const |
491 | { |
492 | return m_end; |
493 | } |
494 | |
495 | //____________________________________________________________________________// |
496 | |
497 | template<typename CharT> |
498 | inline typename basic_cstring<CharT>::size_type |
499 | basic_cstring<CharT>::find( basic_cstring<CharT> str ) const |
500 | { |
501 | if( str.is_empty() || str.size() > size() ) |
502 | return static_cast<size_type>(npos); |
503 | |
504 | const_iterator it = begin(); |
505 | const_iterator last = end() - str.size() + 1; |
506 | |
507 | while( it != last ) { |
508 | if( traits_type::compare( it, str.begin(), str.size() ) == 0 ) |
509 | break; |
510 | |
511 | ++it; |
512 | } |
513 | |
514 | return it == last ? npos : static_cast<size_type>(it - begin()); |
515 | } |
516 | |
517 | //____________________________________________________________________________// |
518 | |
519 | template<typename CharT> |
520 | inline typename basic_cstring<CharT>::size_type |
521 | basic_cstring<CharT>::rfind( basic_cstring<CharT> str ) const |
522 | { |
523 | if( str.is_empty() || str.size() > size() ) |
524 | return static_cast<size_type>(npos); |
525 | |
526 | const_iterator it = end() - str.size(); |
527 | const_iterator last = begin()-1; |
528 | |
529 | while( it != last ) { |
530 | if( traits_type::compare( it, str.begin(), str.size() ) == 0 ) |
531 | break; |
532 | |
533 | --it; |
534 | } |
535 | |
536 | return it == last ? static_cast<size_type>(npos) : static_cast<size_type>(it - begin()); |
537 | } |
538 | |
539 | //____________________________________________________________________________// |
540 | |
541 | template<typename CharT> |
542 | inline basic_cstring<CharT> |
543 | basic_cstring<CharT>::substr( size_type beg_index, size_type end_index ) const |
544 | { |
545 | return beg_index > size() |
546 | ? self_type() |
547 | : end_index > size() |
548 | ? self_type( m_begin + beg_index, m_end ) |
549 | : self_type( m_begin + beg_index, m_begin + end_index ); |
550 | } |
551 | |
552 | //____________________________________________________________________________// |
553 | |
554 | template<typename CharT> |
555 | inline basic_cstring<CharT> |
556 | basic_cstring<CharT>::default_trim_ex() |
557 | { |
558 | static CharT ws[3] = { CharT(' '), CharT('\t'), CharT('\n') }; // !! wide case |
559 | |
560 | return self_type( ws, 3 ); |
561 | } |
562 | |
563 | //____________________________________________________________________________// |
564 | |
565 | // ************************************************************************** // |
566 | // ************** comparison operators ************** // |
567 | // ************************************************************************** // |
568 | |
569 | template<typename CharT1,typename CharT2> |
570 | inline bool |
571 | operator==( basic_cstring<CharT1> const& s1, basic_cstring<CharT2> const& s2 ) |
572 | { |
573 | typedef typename basic_cstring<CharT1>::traits_type traits_type; |
574 | return s1.size() == s2.size() && |
575 | traits_type::compare( s1.begin(), s2.begin(), s1.size() ) == 0; |
576 | } |
577 | |
578 | //____________________________________________________________________________// |
579 | |
580 | template<typename CharT1,typename CharT2> |
581 | inline bool |
582 | operator==( basic_cstring<CharT1> const& s1, CharT2* s2 ) |
583 | { |
584 | #if !defined(__DMC__) |
585 | return s1 == basic_cstring<CharT2>( s2 ); |
586 | #else |
587 | return s1 == basic_cstring<CharT2 const>( s2 ); |
588 | #endif |
589 | } |
590 | |
591 | //____________________________________________________________________________// |
592 | |
593 | template<typename CharT> |
594 | inline bool |
595 | operator==( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 ) |
596 | { |
597 | return s1 == basic_cstring<CharT>( s2 ); |
598 | } |
599 | |
600 | //____________________________________________________________________________// |
601 | |
602 | template<typename CharT1,typename CharT2> |
603 | inline bool |
604 | operator==( CharT1* s2, basic_cstring<CharT2> const& s1 ) |
605 | { |
606 | return s1 == s2; |
607 | } |
608 | |
609 | //____________________________________________________________________________// |
610 | |
611 | template<typename CharT> |
612 | inline bool |
613 | operator==( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 ) |
614 | { |
615 | return s1 == s2; |
616 | } |
617 | |
618 | //____________________________________________________________________________// |
619 | |
620 | template<typename CharT> |
621 | inline bool |
622 | operator!=( basic_cstring<CharT> const& s1, CharT* s2 ) |
623 | { |
624 | return !(s1 == s2); |
625 | } |
626 | |
627 | //____________________________________________________________________________// |
628 | |
629 | template<typename CharT> |
630 | inline bool |
631 | operator!=( CharT* s2, basic_cstring<CharT> const& s1 ) |
632 | { |
633 | return !(s1 == s2); |
634 | } |
635 | |
636 | //____________________________________________________________________________// |
637 | |
638 | template<typename CharT> |
639 | inline bool |
640 | operator!=( basic_cstring<CharT> const& s1, basic_cstring<CharT> const& s2 ) |
641 | { |
642 | return !(s1 == s2); |
643 | } |
644 | |
645 | //____________________________________________________________________________// |
646 | |
647 | template<typename CharT> |
648 | inline bool |
649 | operator!=( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 ) |
650 | { |
651 | return !(s1 == s2); |
652 | } |
653 | |
654 | //____________________________________________________________________________// |
655 | |
656 | template<typename CharT> |
657 | inline bool |
658 | operator!=( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 ) |
659 | { |
660 | return !(s1 == s2); |
661 | } |
662 | |
663 | //____________________________________________________________________________// |
664 | |
665 | // ************************************************************************** // |
666 | // ************** first_char ************** // |
667 | // ************************************************************************** // |
668 | |
669 | template<typename CharT> |
670 | inline typename basic_cstring<CharT>::value_ret_type |
671 | first_char( basic_cstring<CharT> source ) |
672 | { |
673 | typedef typename basic_cstring<CharT>::value_ret_type res_type; |
674 | |
675 | return source.is_empty() ? static_cast<res_type>(0) : *source.begin(); |
676 | } |
677 | |
678 | //____________________________________________________________________________// |
679 | |
680 | // ************************************************************************** // |
681 | // ************** last_char ************** // |
682 | // ************************************************************************** // |
683 | |
684 | template<typename CharT> |
685 | inline typename basic_cstring<CharT>::value_ret_type |
686 | last_char( basic_cstring<CharT> source ) |
687 | { |
688 | typedef typename basic_cstring<CharT>::value_ret_type res_type; |
689 | |
690 | return source.is_empty() ? static_cast<res_type>(0) : *(source.end()-1); |
691 | } |
692 | |
693 | //____________________________________________________________________________// |
694 | |
695 | // ************************************************************************** // |
696 | // ************** assign_op ************** // |
697 | // ************************************************************************** // |
698 | |
699 | template<typename CharT1, typename CharT2> |
700 | inline void |
701 | assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> src, int ) |
702 | { |
703 | target.assign( src.begin(), src.size() ); |
704 | } |
705 | |
706 | //____________________________________________________________________________// |
707 | |
708 | template<typename CharT1, typename CharT2> |
709 | inline std::basic_string<CharT1>& |
710 | operator+=( std::basic_string<CharT1>& target, basic_cstring<CharT2> const& str ) |
711 | { |
712 | target.append( str.begin(), str.end() ); |
713 | return target; |
714 | } |
715 | |
716 | //____________________________________________________________________________// |
717 | |
718 | template<typename CharT1, typename CharT2> |
719 | inline std::basic_string<CharT1> |
720 | operator+( std::basic_string<CharT1> const& lhs, basic_cstring<CharT2> const& rhs ) |
721 | { |
722 | std::basic_string<CharT1> res( lhs ); |
723 | |
724 | res.append( rhs.begin(), rhs.end() ); |
725 | return res; |
726 | } |
727 | |
728 | //____________________________________________________________________________// |
729 | |
730 | } // namespace unit_test |
731 | |
732 | } // namespace boost |
733 | |
734 | //____________________________________________________________________________// |
735 | |
736 | #include <boost/test/detail/enable_warnings.hpp> |
737 | |
738 | #endif // BOOST_TEST_UTILS_BASIC_CSTRING_HPP |
739 | |