From c81ee948b7e66e20a923be437bd1d6e34c589eaf Mon Sep 17 00:00:00 2001 From: Pavol Droba Date: Wed, 18 Jun 2008 21:54:06 +0000 Subject: [PATCH] is_any_ofF performance improvements tabs removed [SVN r46496] --- .../boost/algorithm/string/classification.hpp | 4 +- .../string/detail/classification.hpp | 160 +++++++++++++++++- include/boost/algorithm/string/find.hpp | 2 +- .../boost/algorithm/string/find_format.hpp | 2 +- 4 files changed, 159 insertions(+), 9 deletions(-) diff --git a/include/boost/algorithm/string/classification.hpp b/include/boost/algorithm/string/classification.hpp index a2e2b4d..33ff9be 100644 --- a/include/boost/algorithm/string/classification.hpp +++ b/include/boost/algorithm/string/classification.hpp @@ -202,8 +202,8 @@ namespace boost { BOOST_STRING_TYPENAME range_value::type> is_any_of( const RangeT& Set ) { - return detail::is_any_ofF< - BOOST_STRING_TYPENAME range_value::type>(as_literal(Set)); + iterator_range::type> lit_set(as_literal(Set)); + return detail::is_any_ofF::type>(lit_set); } //! is_from_range predicate diff --git a/include/boost/algorithm/string/detail/classification.hpp b/include/boost/algorithm/string/detail/classification.hpp index 22b3779..3930655 100644 --- a/include/boost/algorithm/string/detail/classification.hpp +++ b/include/boost/algorithm/string/detail/classification.hpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -76,27 +75,178 @@ namespace boost { struct is_any_ofF : public predicate_facade > { + private: + // set cannot operate on const value-type + typedef typename remove_const::type set_value_type; + // Size of the static storage (size of pointer*2) + static const ::std::size_t FIXED_STORAGE_SIZE = sizeof(set_value_type*)*2; + + public: // Boost.Lambda support template struct sig { typedef bool type; }; // Constructor template - is_any_ofF( const RangeT& Range ) : - m_Set( ::boost::begin(Range), ::boost::end(Range) ) {} + 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(m_Size<=FIXED_STORAGE_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(m_Size<=FIXED_STORAGE_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(m_Size>FIXED_STORAGE_SIZE && m_Storage.m_dynSet!=0) + { + delete m_Storage.m_dynSet; + } + } + + // Assignment + is_any_ofF& operator=(const is_any_ofF& Other) + { + // Prepare storage + m_Storage.m_dynSet=0; + m_Size=Other.m_Size; + const set_value_type* SrcStorage=0; + set_value_type* DestStorage=0; + + if(m_Size<=FIXED_STORAGE_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[Size]; + DestStorage=m_Storage.m_dynSet; + SrcStorage=Other.m_Storage.m_dynSet; + } + + // Use fixed storage + ::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size); + + return *this; + } // Operation template bool operator()( Char2T Ch ) const { - return m_Set.find(Ch)!=m_Set.end(); + const set_value_type* Storage= + (m_Size<=FIXED_STORAGE_SIZE) + ? &m_Storage.m_fixSet[0] + : m_Storage.m_dynSet; + + return ::std::binary_search(Storage, Storage+m_Size, Ch); } private: // set cannot operate on const value-type typedef typename remove_const::type set_value_type; - std::set m_Set; + + // storage + // The actual used storage is selected on the type + union + { + set_value_type* m_dynSet; + set_value_type m_fixSet[FIXED_STORAGE_SIZE]; + } + m_Storage; + + // storage size + ::std::size_t m_Size; }; + // fixed size is_any_of functor + /* + returns true if the value is from the specified set + works on the fixed size set + */ + template + struct is_any_of_fixedF : + public predicate_facade > + { + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + template + is_any_of_fixedF( const RangeT& Range ) + { + BOOST_ASSERT(::boost::distance(Range)==Size); + // Copy up-to Size elements + ::std::size_t nIndex=0; + ::boost::range_const_iterator::type It=::boost::begin(Range); + while(nIndex + bool operator()( Char2T Ch ) const + { + return ::std::binary_search(&m_Set[0], &m_Set[Size], Ch); + } + + private: + // set cannot operate on const value-type + typedef typename remove_const::type set_value_type; + set_value_type m_Set[Size]; + }; + + // is_from_range functor /* returns true if the value is from the specified range. diff --git a/include/boost/algorithm/string/find.hpp b/include/boost/algorithm/string/find.hpp index 8daada5..4196585 100644 --- a/include/boost/algorithm/string/find.hpp +++ b/include/boost/algorithm/string/find.hpp @@ -55,7 +55,7 @@ namespace boost { { iterator_range::type> lit_input(as_literal(Input)); - return Finder(::boost::begin(lit_input),::boost::end(lit_input)); + return Finder(::boost::begin(lit_input),::boost::end(lit_input)); } // find_first -----------------------------------------------// diff --git a/include/boost/algorithm/string/find_format.hpp b/include/boost/algorithm/string/find_format.hpp index 453dfaf..7cbaf34 100644 --- a/include/boost/algorithm/string/find_format.hpp +++ b/include/boost/algorithm/string/find_format.hpp @@ -76,7 +76,7 @@ namespace boost { Output, lit_input, Formatter, - Finder( ::boost::begin(lit_input), ::boost::end(lit_input) ) ); + Finder( ::boost::begin(lit_input), ::boost::end(lit_input) ) ); } //! Generic replace algorithm