354 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			354 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| //  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
 | |
|                     ::std::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
 | |
|                     ::std::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
 | 
