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