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)
6 // See http://www.boost.org/libs/test for the library home page.
10 // Version : $Revision$
12 // Description : class basic_cstring wraps C string and provide std_string like
14 // ***************************************************************************
16 #ifndef BOOST_TEST_UTILS_BASIC_CSTRING_HPP
17 #define BOOST_TEST_UTILS_BASIC_CSTRING_HPP
20 #include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp>
21 #include <boost/test/utils/basic_cstring/bcs_char_traits.hpp>
24 #include <boost/type_traits/remove_cv.hpp>
29 #include <boost/test/detail/suppress_warnings.hpp>
31 //____________________________________________________________________________//
37 // ************************************************************************** //
38 // ************** basic_cstring ************** //
39 // ************************************************************************** //
41 template<typename CharT>
43 typedef basic_cstring<CharT> self_type;
46 typedef ut_detail::bcs_char_traits<CharT> traits_type;
47 typedef typename ut_detail::bcs_char_traits<CharT>::std_string std_string;
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;
58 typedef value_type const* const_iterator;
59 typedef value_type* iterator;
61 // !! should also present reverse_iterator, const_reverse_iterator
63 #if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
64 enum npos_type { npos = static_cast<size_type>(-1) };
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 ;
71 static pointer null_str();
73 // Constructors; default copy constructor is generated by compiler
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 );
81 // data access methods
82 value_ret_type operator[]( size_type index ) const;
83 value_ret_type at( size_type index ) const;
86 size_type size() const;
87 bool is_empty() const;
89 void resize( size_type new_len );
91 // !! only for STL container conformance use is_empty instead
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() ) ;
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() ); }
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 );
118 template<typename CharT2>
119 basic_cstring& assign( basic_cstring<CharT2> const& s )
121 return *this = basic_cstring<CharT>( s.begin(), s.end() );
123 template<typename PosType, typename LenType>
124 basic_cstring& assign( self_type const& s, PosType pos, LenType len )
126 return *this = self_type( s.m_begin + pos, len );
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 )
133 return *this = self_type( s.c_str() + pos, len );
135 basic_cstring& assign( pointer s );
136 template<typename LenType>
137 basic_cstring& assign( pointer s, LenType len )
139 return *this = self_type( s, len );
141 basic_cstring& assign( pointer f, pointer l );
144 void swap( self_type& s );
148 const_iterator begin() const;
150 const_iterator end() const;
152 // !! should have rbegin, rend
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;
160 static self_type default_trim_ex();
167 //____________________________________________________________________________//
169 template<typename CharT>
170 inline typename basic_cstring<CharT>::pointer
171 basic_cstring<CharT>::null_str()
173 static CharT null = 0;
177 //____________________________________________________________________________//
179 template<typename CharT>
181 basic_cstring<CharT>::basic_cstring()
182 : m_begin( null_str() )
187 //____________________________________________________________________________//
189 template<typename CharT>
191 basic_cstring<CharT>::basic_cstring( std_string const& s )
192 : m_begin( s.c_str() )
193 , m_end( m_begin + s.size() )
197 //____________________________________________________________________________//
199 template<typename CharT>
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 ) )
207 //____________________________________________________________________________//
209 template<typename CharT>
211 basic_cstring<CharT>::basic_cstring( pointer first, pointer last )
217 //____________________________________________________________________________//
219 template<typename CharT>
220 inline typename basic_cstring<CharT>::value_ret_type
221 basic_cstring<CharT>::operator[]( size_type index ) const
223 return m_begin[index];
226 //____________________________________________________________________________//
228 template<typename CharT>
229 inline typename basic_cstring<CharT>::value_ret_type
230 basic_cstring<CharT>::at( size_type index ) const
232 if( m_begin + index >= m_end )
233 return static_cast<value_type>(0);
235 return m_begin[index];
238 //____________________________________________________________________________//
240 template<typename CharT>
241 inline typename basic_cstring<CharT>::size_type
242 basic_cstring<CharT>::size() const
244 return static_cast<size_type>(m_end - m_begin);
247 //____________________________________________________________________________//
249 template<typename CharT>
251 basic_cstring<CharT>::is_empty() const
253 return m_end == m_begin;
256 //____________________________________________________________________________//
258 template<typename CharT>
260 basic_cstring<CharT>::empty() const
265 //____________________________________________________________________________//
267 template<typename CharT>
269 basic_cstring<CharT>::clear()
274 //____________________________________________________________________________//
276 template<typename CharT>
278 basic_cstring<CharT>::resize( size_type new_len )
280 if( m_begin + new_len < m_end )
281 m_end = m_begin + new_len;
284 //____________________________________________________________________________//
286 template<typename CharT>
287 inline basic_cstring<CharT>&
288 basic_cstring<CharT>::trim_left( size_type trim_size )
290 m_begin += trim_size;
291 if( m_end <= m_begin )
297 //____________________________________________________________________________//
299 template<typename CharT>
300 inline basic_cstring<CharT>&
301 basic_cstring<CharT>::trim_left( iterator it )
304 if( m_end <= m_begin )
310 //____________________________________________________________________________//
312 template<typename CharT>
313 inline basic_cstring<CharT>&
314 basic_cstring<CharT>::trim_left( basic_cstring exclusions )
316 if( exclusions.is_empty() )
317 exclusions = default_trim_ex();
320 for( it = begin(); it != end(); ++it ) {
321 if( traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) )
325 return trim_left( it );
328 //____________________________________________________________________________//
330 template<typename CharT>
331 inline basic_cstring<CharT>&
332 basic_cstring<CharT>::trim_right( size_type trim_size )
335 if( m_end <= m_begin )
341 //____________________________________________________________________________//
343 template<typename CharT>
344 inline basic_cstring<CharT>&
345 basic_cstring<CharT>::trim_right( iterator it )
348 if( m_end <= m_begin )
354 //____________________________________________________________________________//
356 template<typename CharT>
357 inline basic_cstring<CharT>&
358 basic_cstring<CharT>::trim_right( basic_cstring exclusions )
360 if( exclusions.is_empty() )
361 exclusions = default_trim_ex();
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) )
370 return trim_right( it+1 );
373 //____________________________________________________________________________//
375 template<typename CharT>
376 inline basic_cstring<CharT>&
377 basic_cstring<CharT>::trim( basic_cstring exclusions )
379 trim_left( exclusions );
380 trim_right( exclusions );
385 //____________________________________________________________________________//
387 template<typename CharT>
388 inline basic_cstring<CharT>&
389 basic_cstring<CharT>::operator=( basic_cstring<CharT> const& s )
397 //____________________________________________________________________________//
399 template<typename CharT>
400 inline basic_cstring<CharT>&
401 basic_cstring<CharT>::operator=( std_string const& s )
403 return *this = self_type( s );
406 //____________________________________________________________________________//
408 template<typename CharT>
409 inline basic_cstring<CharT>&
410 basic_cstring<CharT>::operator=( pointer s )
412 return *this = self_type( s );
415 //____________________________________________________________________________//
417 template<typename CharT>
418 inline basic_cstring<CharT>&
419 basic_cstring<CharT>::assign( std_string const& s )
421 return *this = self_type( s );
424 //____________________________________________________________________________//
426 template<typename CharT>
427 inline basic_cstring<CharT>&
428 basic_cstring<CharT>::assign( pointer s )
430 return *this = self_type( s );
433 //____________________________________________________________________________//
435 template<typename CharT>
436 inline basic_cstring<CharT>&
437 basic_cstring<CharT>::assign( pointer f, pointer l )
439 return *this = self_type( f, l );
442 //____________________________________________________________________________//
444 template<typename CharT>
446 basic_cstring<CharT>::swap( basic_cstring<CharT>& s )
448 // do not want to include alogrithm
449 pointer tmp1 = m_begin;
450 pointer tmp2 = m_end;
459 //____________________________________________________________________________//
461 template<typename CharT>
462 inline typename basic_cstring<CharT>::iterator
463 basic_cstring<CharT>::begin()
468 //____________________________________________________________________________//
470 template<typename CharT>
471 inline typename basic_cstring<CharT>::const_iterator
472 basic_cstring<CharT>::begin() const
477 //____________________________________________________________________________//
479 template<typename CharT>
480 inline typename basic_cstring<CharT>::iterator
481 basic_cstring<CharT>::end()
486 //____________________________________________________________________________//
488 template<typename CharT>
489 inline typename basic_cstring<CharT>::const_iterator
490 basic_cstring<CharT>::end() const
495 //____________________________________________________________________________//
497 template<typename CharT>
498 inline typename basic_cstring<CharT>::size_type
499 basic_cstring<CharT>::find( basic_cstring<CharT> str ) const
501 if( str.is_empty() || str.size() > size() )
502 return static_cast<size_type>(npos);
504 const_iterator it = begin();
505 const_iterator last = end() - str.size() + 1;
507 while( it != last ) {
508 if( traits_type::compare( it, str.begin(), str.size() ) == 0 )
514 return it == last ? npos : static_cast<size_type>(it - begin());
517 //____________________________________________________________________________//
519 template<typename CharT>
520 inline typename basic_cstring<CharT>::size_type
521 basic_cstring<CharT>::rfind( basic_cstring<CharT> str ) const
523 if( str.is_empty() || str.size() > size() )
524 return static_cast<size_type>(npos);
526 const_iterator it = end() - str.size();
527 const_iterator last = begin()-1;
529 while( it != last ) {
530 if( traits_type::compare( it, str.begin(), str.size() ) == 0 )
536 return it == last ? static_cast<size_type>(npos) : static_cast<size_type>(it - begin());
539 //____________________________________________________________________________//
541 template<typename CharT>
542 inline basic_cstring<CharT>
543 basic_cstring<CharT>::substr( size_type beg_index, size_type end_index ) const
545 return beg_index > size()
548 ? self_type( m_begin + beg_index, m_end )
549 : self_type( m_begin + beg_index, m_begin + end_index );
552 //____________________________________________________________________________//
554 template<typename CharT>
555 inline basic_cstring<CharT>
556 basic_cstring<CharT>::default_trim_ex()
558 static CharT ws[3] = { CharT(' '), CharT('\t'), CharT('\n') }; // !! wide case
560 return self_type( ws, 3 );
563 //____________________________________________________________________________//
565 // ************************************************************************** //
566 // ************** comparison operators ************** //
567 // ************************************************************************** //
569 template<typename CharT1,typename CharT2>
571 operator==( basic_cstring<CharT1> const& s1, basic_cstring<CharT2> const& s2 )
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;
578 //____________________________________________________________________________//
580 template<typename CharT1,typename CharT2>
582 operator==( basic_cstring<CharT1> const& s1, CharT2* s2 )
584 #if !defined(__DMC__)
585 return s1 == basic_cstring<CharT2>( s2 );
587 return s1 == basic_cstring<CharT2 const>( s2 );
591 //____________________________________________________________________________//
593 template<typename CharT>
595 operator==( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
597 return s1 == basic_cstring<CharT>( s2 );
600 //____________________________________________________________________________//
602 template<typename CharT1,typename CharT2>
604 operator==( CharT1* s2, basic_cstring<CharT2> const& s1 )
609 //____________________________________________________________________________//
611 template<typename CharT>
613 operator==( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
618 //____________________________________________________________________________//
620 template<typename CharT>
622 operator!=( basic_cstring<CharT> const& s1, CharT* s2 )
627 //____________________________________________________________________________//
629 template<typename CharT>
631 operator!=( CharT* s2, basic_cstring<CharT> const& s1 )
636 //____________________________________________________________________________//
638 template<typename CharT>
640 operator!=( basic_cstring<CharT> const& s1, basic_cstring<CharT> const& s2 )
645 //____________________________________________________________________________//
647 template<typename CharT>
649 operator!=( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
654 //____________________________________________________________________________//
656 template<typename CharT>
658 operator!=( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
663 //____________________________________________________________________________//
665 // ************************************************************************** //
666 // ************** first_char ************** //
667 // ************************************************************************** //
669 template<typename CharT>
670 inline typename basic_cstring<CharT>::value_ret_type
671 first_char( basic_cstring<CharT> source )
673 typedef typename basic_cstring<CharT>::value_ret_type res_type;
675 return source.is_empty() ? static_cast<res_type>(0) : *source.begin();
678 //____________________________________________________________________________//
680 // ************************************************************************** //
681 // ************** last_char ************** //
682 // ************************************************************************** //
684 template<typename CharT>
685 inline typename basic_cstring<CharT>::value_ret_type
686 last_char( basic_cstring<CharT> source )
688 typedef typename basic_cstring<CharT>::value_ret_type res_type;
690 return source.is_empty() ? static_cast<res_type>(0) : *(source.end()-1);
693 //____________________________________________________________________________//
695 // ************************************************************************** //
696 // ************** assign_op ************** //
697 // ************************************************************************** //
699 template<typename CharT1, typename CharT2>
701 assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> src, int )
703 target.assign( src.begin(), src.size() );
706 //____________________________________________________________________________//
708 template<typename CharT1, typename CharT2>
709 inline std::basic_string<CharT1>&
710 operator+=( std::basic_string<CharT1>& target, basic_cstring<CharT2> const& str )
712 target.append( str.begin(), str.end() );
716 //____________________________________________________________________________//
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 )
722 std::basic_string<CharT1> res( lhs );
724 res.append( rhs.begin(), rhs.end() );
728 //____________________________________________________________________________//
730 } // namespace unit_test
734 //____________________________________________________________________________//
736 #include <boost/test/detail/enable_warnings.hpp>
738 #endif // BOOST_TEST_UTILS_BASIC_CSTRING_HPP