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