forked from boostorg/algorithm
		
	
		
			
				
	
	
		
			354 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			354 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//  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
 |