| // (C) Copyright Gennadiy Rozental 2004-2008. |
| // Distributed under the Boost Software License, Version 1.0. |
| // (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| |
| // See http://www.boost.org/libs/test for the library home page. |
| // |
| // File : $RCSfile$ |
| // |
| // Version : $Revision: 57992 $ |
| // |
| // Description : class basic_cstring wraps C string and provide std_string like |
| // interface |
| // *************************************************************************** |
| |
| #ifndef BOOST_TEST_BASIC_CSTRING_HPP_071894GER |
| #define BOOST_TEST_BASIC_CSTRING_HPP_071894GER |
| |
| // Boost.Test |
| #include <ndnboost/test/utils/basic_cstring/basic_cstring_fwd.hpp> |
| #include <ndnboost/test/utils/basic_cstring/bcs_char_traits.hpp> |
| |
| // STL |
| #include <string> |
| |
| #include <ndnboost/test/detail/suppress_warnings.hpp> |
| |
| //____________________________________________________________________________// |
| |
| namespace ndnboost { |
| |
| namespace unit_test { |
| |
| // ************************************************************************** // |
| // ************** basic_cstring ************** // |
| // ************************************************************************** // |
| |
| template<typename CharT> |
| class basic_cstring { |
| typedef basic_cstring<CharT> self_type; |
| public: |
| // Subtypes |
| typedef ut_detail::bcs_char_traits<CharT> traits_type; |
| typedef typename ut_detail::bcs_char_traits<CharT>::std_string std_string; |
| |
| typedef CharT value_type; |
| typedef value_type* pointer; |
| typedef value_type const* const_pointer; |
| typedef value_type& reference; |
| typedef const value_type& const_reference; |
| typedef std::size_t size_type; |
| typedef std::ptrdiff_t difference_type; |
| |
| typedef value_type const* const_iterator; |
| typedef value_type* iterator; |
| |
| // !! should also present reverse_iterator, const_reverse_iterator |
| |
| #if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) |
| enum npos_type { npos = static_cast<size_type>(-1) }; |
| #else |
| // IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes. |
| // But size_type is 8 bytes in 64bit mode. |
| static const size_type npos = -1 ; |
| #endif |
| |
| static pointer null_str(); |
| |
| // Constructors; default copy constructor is generated by compiler |
| basic_cstring(); |
| basic_cstring( std_string const& s ); |
| basic_cstring( pointer s ); |
| basic_cstring( pointer s, size_type arg_size ); |
| basic_cstring( pointer first, pointer last ); |
| |
| // data access methods |
| value_type operator[]( size_type index ) const; |
| value_type at( size_type index ) const; |
| |
| // size operators |
| size_type size() const; |
| bool is_empty() const; |
| void clear(); |
| void resize( size_type new_len ); |
| |
| // !! only for STL container conformance use is_empty instead |
| bool empty() const; |
| |
| // Trimming |
| self_type& trim_right( size_type trim_size ); |
| self_type& trim_left( size_type trim_size ); |
| self_type& trim_right( iterator it ); |
| self_type& trim_left( iterator it ); |
| #ifndef __IBMCPP__ |
| self_type& trim_left( self_type exclusions = self_type() ) ; |
| self_type& trim_right( self_type exclusions = self_type() ) ; |
| self_type& trim( self_type exclusions = self_type() ) ; |
| #else |
| // VisualAge version 6 has in this case a problem with the default arguments. |
| self_type& trim_left( self_type exclusions ) ; |
| self_type& trim_right( self_type exclusions ) ; |
| self_type& trim( self_type exclusions ) ; |
| self_type& trim_left() { trim_left( self_type() ) ; } |
| self_type& trim_right() { trim_right( self_type() ) ; } |
| self_type& trim() { trim( self_type() ) ; } |
| #endif |
| |
| // Assignment operators |
| basic_cstring& operator=( self_type const& s ); |
| basic_cstring& operator=( std_string const& s ); |
| basic_cstring& operator=( pointer s ); |
| |
| template<typename CharT2> |
| basic_cstring& assign( basic_cstring<CharT2> const& s ) { *this = basic_cstring<CharT>( s.begin(), s.end() ); return *this; } |
| basic_cstring& assign( self_type const& s, size_type pos, size_type len ); |
| basic_cstring& assign( std_string const& s ); |
| basic_cstring& assign( std_string const& s, size_type pos, size_type len ); |
| basic_cstring& assign( pointer s ); |
| basic_cstring& assign( pointer s, size_type len ); |
| basic_cstring& assign( pointer f, pointer l ); |
| |
| // swapping |
| void swap( self_type& s ); |
| |
| // Iterators |
| iterator begin(); |
| const_iterator begin() const; |
| iterator end(); |
| const_iterator end() const; |
| |
| // !! should have rbegin, rend |
| |
| // substring search operation |
| size_type find( basic_cstring ) const; |
| size_type rfind( basic_cstring ) const; |
| self_type substr( size_type beg_index, size_type end_index = npos ) const; |
| |
| private: |
| static self_type default_trim_ex(); |
| |
| // Data members |
| iterator m_begin; |
| iterator m_end; |
| }; |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::pointer |
| basic_cstring<CharT>::null_str() |
| { |
| static CharT null = 0; |
| return &null; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline |
| basic_cstring<CharT>::basic_cstring() |
| : m_begin( null_str() ) |
| , m_end( m_begin ) |
| { |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline |
| basic_cstring<CharT>::basic_cstring( std_string const& s ) |
| : m_begin( s.c_str() ) |
| , m_end( m_begin + s.size() ) |
| { |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline |
| basic_cstring<CharT>::basic_cstring( pointer s ) |
| : m_begin( s ? s : null_str() ) |
| , m_end ( m_begin + (s ? traits_type::length( s ) : 0 ) ) |
| { |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline |
| basic_cstring<CharT>::basic_cstring( pointer s, size_type arg_size ) |
| : m_begin( s ), m_end( m_begin + arg_size ) |
| { |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline |
| basic_cstring<CharT>::basic_cstring( pointer first, pointer last ) |
| : m_begin( first ) |
| , m_end( last ) |
| { |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::value_type |
| basic_cstring<CharT>::operator[]( size_type index ) const |
| { |
| return m_begin[index]; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::value_type |
| basic_cstring<CharT>::at( size_type index ) const |
| { |
| if( m_begin + index >= m_end ) |
| return static_cast<value_type>(0); |
| |
| return m_begin[index]; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::size_type |
| basic_cstring<CharT>::size() const |
| { |
| return m_end - m_begin; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline bool |
| basic_cstring<CharT>::is_empty() const |
| { |
| return m_end == m_begin; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline bool |
| basic_cstring<CharT>::empty() const |
| { |
| return is_empty(); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline void |
| basic_cstring<CharT>::clear() |
| { |
| m_begin = m_end; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline void |
| basic_cstring<CharT>::resize( size_type new_len ) |
| { |
| if( m_begin + new_len < m_end ) |
| m_end = m_begin + new_len; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::trim_left( size_type trim_size ) |
| { |
| m_begin += trim_size; |
| if( m_end <= m_begin ) |
| clear(); |
| |
| return *this; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::trim_left( iterator it ) |
| { |
| m_begin = it; |
| if( m_end <= m_begin ) |
| clear(); |
| |
| return *this; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::trim_left( basic_cstring exclusions ) |
| { |
| if( exclusions.is_empty() ) |
| exclusions = default_trim_ex(); |
| |
| iterator it; |
| for( it = begin(); it != end(); ++it ) { |
| if( traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) ) |
| break; |
| } |
| |
| return trim_left( it ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::trim_right( size_type trim_size ) |
| { |
| m_end -= trim_size; |
| if( m_end <= m_begin ) |
| clear(); |
| |
| return *this; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::trim_right( iterator it ) |
| { |
| m_end = it; |
| if( m_end <= m_begin ) |
| clear(); |
| |
| return *this; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::trim_right( basic_cstring exclusions ) |
| { |
| if( exclusions.is_empty() ) |
| exclusions = default_trim_ex(); |
| |
| iterator it; |
| |
| for( it = end()-1; it != begin()-1; --it ) { |
| if( self_type::traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) ) |
| break; |
| } |
| |
| return trim_right( it+1 ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::trim( basic_cstring exclusions ) |
| { |
| trim_left( exclusions ); |
| trim_right( exclusions ); |
| |
| return *this; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::operator=( basic_cstring<CharT> const& s ) |
| { |
| m_begin = s.m_begin; |
| m_end = s.m_end; |
| |
| return *this; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::operator=( std_string const& s ) |
| { |
| return *this = self_type( s ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::operator=( pointer s ) |
| { |
| return *this = self_type( s ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::assign( basic_cstring<CharT> const& s, size_type pos, size_type len ) |
| { |
| return *this = self_type( s.m_begin + pos, len ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::assign( std_string const& s ) |
| { |
| return *this = self_type( s ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::assign( std_string const& s, size_type pos, size_type len ) |
| { |
| return *this = self_type( s.c_str() + pos, len ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::assign( pointer s ) |
| { |
| return *this = self_type( s ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::assign( pointer s, size_type len ) |
| { |
| return *this = self_type( s, len ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT>& |
| basic_cstring<CharT>::assign( pointer f, pointer l ) |
| { |
| return *this = self_type( f, l ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline void |
| basic_cstring<CharT>::swap( basic_cstring<CharT>& s ) |
| { |
| // do not want to include alogrithm |
| pointer tmp1 = m_begin; |
| pointer tmp2 = m_end; |
| |
| m_begin = s.m_begin; |
| m_end = s.m_end; |
| |
| s.m_begin = tmp1; |
| s.m_end = tmp2; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::iterator |
| basic_cstring<CharT>::begin() |
| { |
| return m_begin; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::const_iterator |
| basic_cstring<CharT>::begin() const |
| { |
| return m_begin; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::iterator |
| basic_cstring<CharT>::end() |
| { |
| return m_end; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::const_iterator |
| basic_cstring<CharT>::end() const |
| { |
| return m_end; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::size_type |
| basic_cstring<CharT>::find( basic_cstring<CharT> str ) const |
| { |
| if( str.is_empty() || str.size() > size() ) |
| return static_cast<size_type>(npos); |
| |
| const_iterator it = begin(); |
| const_iterator last = end() - str.size() + 1; |
| |
| while( it != last ) { |
| if( traits_type::compare( it, str.begin(), str.size() ) == 0 ) |
| break; |
| |
| ++it; |
| } |
| |
| return it == last ? static_cast<size_type>(npos) : it - begin(); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::size_type |
| basic_cstring<CharT>::rfind( basic_cstring<CharT> str ) const |
| { |
| if( str.is_empty() || str.size() > size() ) |
| return static_cast<size_type>(npos); |
| |
| const_iterator it = end() - str.size(); |
| const_iterator last = begin()-1; |
| |
| while( it != last ) { |
| if( traits_type::compare( it, str.begin(), str.size() ) == 0 ) |
| break; |
| |
| --it; |
| } |
| |
| return it == last ? static_cast<size_type>(npos) : static_cast<size_type>(it - begin()); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT> |
| basic_cstring<CharT>::substr( size_type beg_index, size_type end_index ) const |
| { |
| return beg_index > size() |
| ? self_type() |
| : end_index > size() |
| ? self_type( m_begin + beg_index, m_end ) |
| : self_type( m_begin + beg_index, m_begin + end_index ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline basic_cstring<CharT> |
| basic_cstring<CharT>::default_trim_ex() |
| { |
| static CharT ws[3] = { CharT(' '), CharT('\t'), CharT('\n') }; // !! wide case |
| |
| return self_type( ws, 3 ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| // ************************************************************************** // |
| // ************** comparison operators ************** // |
| // ************************************************************************** // |
| |
| template<typename CharT1,typename CharT2> |
| inline bool |
| operator==( basic_cstring<CharT1> const& s1, basic_cstring<CharT2> const& s2 ) |
| { |
| typedef typename basic_cstring<CharT1>::traits_type traits_type; |
| return s1.size() == s2.size() && |
| traits_type::compare( s1.begin(), s2.begin(), s1.size() ) == 0; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT1,typename CharT2> |
| inline bool |
| operator==( basic_cstring<CharT1> const& s1, CharT2* s2 ) |
| { |
| #if !defined(__DMC__) |
| return s1 == basic_cstring<CharT2>( s2 ); |
| #else |
| return s1 == basic_cstring<CharT2 const>( s2 ); |
| #endif |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline bool |
| operator==( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 ) |
| { |
| return s1 == basic_cstring<CharT>( s2 ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT1,typename CharT2> |
| inline bool |
| operator==( CharT1* s2, basic_cstring<CharT2> const& s1 ) |
| { |
| return s1 == s2; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline bool |
| operator==( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 ) |
| { |
| return s1 == s2; |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline bool |
| operator!=( basic_cstring<CharT> const& s1, CharT* s2 ) |
| { |
| return !(s1 == s2); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline bool |
| operator!=( CharT* s2, basic_cstring<CharT> const& s1 ) |
| { |
| return !(s1 == s2); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline bool |
| operator!=( basic_cstring<CharT> const& s1, basic_cstring<CharT> const& s2 ) |
| { |
| return !(s1 == s2); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline bool |
| operator!=( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 ) |
| { |
| return !(s1 == s2); |
| } |
| |
| //____________________________________________________________________________// |
| |
| template<typename CharT> |
| inline bool |
| operator!=( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 ) |
| { |
| return !(s1 == s2); |
| } |
| |
| //____________________________________________________________________________// |
| |
| // ************************************************************************** // |
| // ************** first_char ************** // |
| // ************************************************************************** // |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::value_type |
| first_char( basic_cstring<CharT> source ) |
| { |
| typedef typename basic_cstring<CharT>::value_type string_value_type; |
| |
| return source.is_empty() ? static_cast<string_value_type>(0) : *source.begin(); |
| } |
| |
| //____________________________________________________________________________// |
| |
| // ************************************************************************** // |
| // ************** last_char ************** // |
| // ************************************************************************** // |
| |
| template<typename CharT> |
| inline typename basic_cstring<CharT>::value_type |
| last_char( basic_cstring<CharT> source ) |
| { |
| typedef typename basic_cstring<CharT>::value_type string_value_type; |
| |
| return source.is_empty() ? static_cast<string_value_type>(0) : *(source.end()-1); |
| } |
| |
| //____________________________________________________________________________// |
| |
| // ************************************************************************** // |
| // ************** assign_op ************** // |
| // ************************************************************************** // |
| |
| template<typename CharT1, typename CharT2> |
| inline void |
| assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> src, int ) |
| { |
| target.assign( src.begin(), src.size() ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| } // namespace unit_test |
| |
| } // namespace ndnboost |
| |
| //____________________________________________________________________________// |
| |
| #include <ndnboost/test/detail/enable_warnings.hpp> |
| |
| #endif // BOOST_TEST_BASIC_CSTRING_HPP_071894GER |