]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/test/include/boost/test/utils/basic_cstring/basic_cstring.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / test / include / boost / test / utils / basic_cstring / basic_cstring.hpp
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