| // Boost string_algo library classification.hpp header file ---------------------------// |
| |
| // Copyright Pavol Droba 2002-2003. |
| // |
| // 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/ for updates, documentation, and revision history. |
| |
| #ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP |
| #define BOOST_STRING_CLASSIFICATION_DETAIL_HPP |
| |
| #include <boost/algorithm/string/config.hpp> |
| #include <algorithm> |
| #include <functional> |
| #include <locale> |
| |
| #include <boost/range/begin.hpp> |
| #include <boost/range/end.hpp> |
| |
| #include <boost/algorithm/string/predicate_facade.hpp> |
| #include <boost/type_traits/remove_const.hpp> |
| |
| namespace boost { |
| namespace algorithm { |
| namespace detail { |
| |
| // classification functors -----------------------------------------------// |
| |
| // is_classified functor |
| struct is_classifiedF : |
| public predicate_facade<is_classifiedF> |
| { |
| // Boost.ResultOf support |
| typedef bool result_type; |
| |
| // Constructor from a locale |
| is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : |
| m_Type(Type), m_Locale(Loc) {} |
| // Operation |
| template<typename CharT> |
| bool operator()( CharT Ch ) const |
| { |
| return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch ); |
| } |
| |
| #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL) |
| template<> |
| bool operator()( char const Ch ) const |
| { |
| return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch ); |
| } |
| #endif |
| |
| private: |
| std::ctype_base::mask m_Type; |
| std::locale m_Locale; |
| }; |
| |
| |
| // is_any_of functor |
| /* |
| returns true if the value is from the specified set |
| */ |
| template<typename CharT> |
| struct is_any_ofF : |
| public predicate_facade<is_any_ofF<CharT> > |
| { |
| private: |
| // set cannot operate on const value-type |
| typedef typename ::boost::remove_const<CharT>::type set_value_type; |
| |
| public: |
| // Boost.ResultOf support |
| typedef bool result_type; |
| |
| // Constructor |
| template<typename RangeT> |
| is_any_ofF( const RangeT& Range ) : m_Size(0) |
| { |
| // Prepare storage |
| m_Storage.m_dynSet=0; |
| |
| std::size_t Size=::boost::distance(Range); |
| m_Size=Size; |
| set_value_type* Storage=0; |
| |
| if(use_fixed_storage(m_Size)) |
| { |
| // Use fixed storage |
| Storage=&m_Storage.m_fixSet[0]; |
| } |
| else |
| { |
| // Use dynamic storage |
| m_Storage.m_dynSet=new set_value_type[m_Size]; |
| Storage=m_Storage.m_dynSet; |
| } |
| |
| // Use fixed storage |
| ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage); |
| ::std::sort(Storage, Storage+m_Size); |
| } |
| |
| // Copy constructor |
| is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size) |
| { |
| // Prepare storage |
| m_Storage.m_dynSet=0; |
| const set_value_type* SrcStorage=0; |
| set_value_type* DestStorage=0; |
| |
| if(use_fixed_storage(m_Size)) |
| { |
| // Use fixed storage |
| DestStorage=&m_Storage.m_fixSet[0]; |
| SrcStorage=&Other.m_Storage.m_fixSet[0]; |
| } |
| else |
| { |
| // Use dynamic storage |
| m_Storage.m_dynSet=new set_value_type[m_Size]; |
| DestStorage=m_Storage.m_dynSet; |
| SrcStorage=Other.m_Storage.m_dynSet; |
| } |
| |
| // Use fixed storage |
| ::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size); |
| } |
| |
| // Destructor |
| ~is_any_ofF() |
| { |
| if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) |
| { |
| delete [] m_Storage.m_dynSet; |
| } |
| } |
| |
| // Assignment |
| is_any_ofF& operator=(const is_any_ofF& Other) |
| { |
| // Handle self assignment |
| if(this==&Other) return *this; |
| |
| // Prepare storage |
| const set_value_type* SrcStorage; |
| set_value_type* DestStorage; |
| |
| if(use_fixed_storage(Other.m_Size)) |
| { |
| // Use fixed storage |
| DestStorage=&m_Storage.m_fixSet[0]; |
| SrcStorage=&Other.m_Storage.m_fixSet[0]; |
| |
| // Delete old storage if was present |
| if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) |
| { |
| delete [] m_Storage.m_dynSet; |
| } |
| |
| // Set new size |
| m_Size=Other.m_Size; |
| } |
| else |
| { |
| // Other uses dynamic storage |
| SrcStorage=Other.m_Storage.m_dynSet; |
| |
| // Check what kind of storage are we using right now |
| if(use_fixed_storage(m_Size)) |
| { |
| // Using fixed storage, allocate new |
| set_value_type* pTemp=new set_value_type[Other.m_Size]; |
| DestStorage=pTemp; |
| m_Storage.m_dynSet=pTemp; |
| m_Size=Other.m_Size; |
| } |
| else |
| { |
| // Using dynamic storage, check if can reuse |
| if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size<Other.m_Size*2) |
| { |
| // Reuse the current storage |
| DestStorage=m_Storage.m_dynSet; |
| m_Size=Other.m_Size; |
| } |
| else |
| { |
| // Allocate the new one |
| set_value_type* pTemp=new set_value_type[Other.m_Size]; |
| DestStorage=pTemp; |
| |
| // Delete old storage if necessary |
| if(m_Storage.m_dynSet!=0) |
| { |
| delete [] m_Storage.m_dynSet; |
| } |
| // Store the new storage |
| m_Storage.m_dynSet=pTemp; |
| // Set new size |
| m_Size=Other.m_Size; |
| } |
| } |
| } |
| |
| // Copy the data |
| ::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size); |
| |
| return *this; |
| } |
| |
| // Operation |
| template<typename Char2T> |
| bool operator()( Char2T Ch ) const |
| { |
| const set_value_type* Storage= |
| (use_fixed_storage(m_Size)) |
| ? &m_Storage.m_fixSet[0] |
| : m_Storage.m_dynSet; |
| |
| return ::std::binary_search(Storage, Storage+m_Size, Ch); |
| } |
| private: |
| // check if the size is eligible for fixed storage |
| static bool use_fixed_storage(std::size_t size) |
| { |
| return size<=sizeof(set_value_type*)*2; |
| } |
| |
| |
| private: |
| // storage |
| // The actual used storage is selected on the type |
| union |
| { |
| set_value_type* m_dynSet; |
| set_value_type m_fixSet[sizeof(set_value_type*)*2]; |
| } |
| m_Storage; |
| |
| // storage size |
| ::std::size_t m_Size; |
| }; |
| |
| // is_from_range functor |
| /* |
| returns true if the value is from the specified range. |
| (i.e. x>=From && x>=To) |
| */ |
| template<typename CharT> |
| struct is_from_rangeF : |
| public predicate_facade< is_from_rangeF<CharT> > |
| { |
| // Boost.ResultOf support |
| typedef bool result_type; |
| |
| // Constructor |
| is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {} |
| |
| // Operation |
| template<typename Char2T> |
| bool operator()( Char2T Ch ) const |
| { |
| return ( m_From <= Ch ) && ( Ch <= m_To ); |
| } |
| |
| private: |
| CharT m_From; |
| CharT m_To; |
| }; |
| |
| // class_and composition predicate |
| template<typename Pred1T, typename Pred2T> |
| struct pred_andF : |
| public predicate_facade< pred_andF<Pred1T,Pred2T> > |
| { |
| public: |
| |
| // Boost.ResultOf support |
| typedef bool result_type; |
| |
| // Constructor |
| pred_andF( Pred1T Pred1, Pred2T Pred2 ) : |
| m_Pred1(Pred1), m_Pred2(Pred2) {} |
| |
| // Operation |
| template<typename CharT> |
| bool operator()( CharT Ch ) const |
| { |
| return m_Pred1(Ch) && m_Pred2(Ch); |
| } |
| |
| private: |
| Pred1T m_Pred1; |
| Pred2T m_Pred2; |
| }; |
| |
| // class_or composition predicate |
| template<typename Pred1T, typename Pred2T> |
| struct pred_orF : |
| public predicate_facade< pred_orF<Pred1T,Pred2T> > |
| { |
| public: |
| // Boost.ResultOf support |
| typedef bool result_type; |
| |
| // Constructor |
| pred_orF( Pred1T Pred1, Pred2T Pred2 ) : |
| m_Pred1(Pred1), m_Pred2(Pred2) {} |
| |
| // Operation |
| template<typename CharT> |
| bool operator()( CharT Ch ) const |
| { |
| return m_Pred1(Ch) || m_Pred2(Ch); |
| } |
| |
| private: |
| Pred1T m_Pred1; |
| Pred2T m_Pred2; |
| }; |
| |
| // class_not composition predicate |
| template< typename PredT > |
| struct pred_notF : |
| public predicate_facade< pred_notF<PredT> > |
| { |
| public: |
| // Boost.ResultOf support |
| typedef bool result_type; |
| |
| // Constructor |
| pred_notF( PredT Pred ) : m_Pred(Pred) {} |
| |
| // Operation |
| template<typename CharT> |
| bool operator()( CharT Ch ) const |
| { |
| return !m_Pred(Ch); |
| } |
| |
| private: |
| PredT m_Pred; |
| }; |
| |
| } // namespace detail |
| } // namespace algorithm |
| } // namespace boost |
| |
| |
| #endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP |