is_any_ofF performance improvements

tabs removed



[SVN r46496]
This commit is contained in:
Pavol Droba
2008-06-18 21:54:06 +00:00
parent ba5e4c30c6
commit c81ee948b7
4 changed files with 159 additions and 9 deletions

View File

@ -202,8 +202,8 @@ namespace boost {
BOOST_STRING_TYPENAME range_value<RangeT>::type>
is_any_of( const RangeT& Set )
{
return detail::is_any_ofF<
BOOST_STRING_TYPENAME range_value<RangeT>::type>(as_literal(Set));
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_set(as_literal(Set));
return detail::is_any_ofF<BOOST_STRING_TYPENAME range_value<RangeT>::type>(lit_set);
}
//! is_from_range predicate

View File

@ -15,7 +15,6 @@
#include <algorithm>
#include <functional>
#include <locale>
#include <set>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@ -76,27 +75,178 @@ namespace boost {
struct is_any_ofF :
public predicate_facade<is_any_ofF<CharT> >
{
private:
// set cannot operate on const value-type
typedef typename remove_const<CharT>::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 <class Args> struct sig { typedef bool type; };
// Constructor
template<typename RangeT>
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<typename Char2T>
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<CharT>::type set_value_type;
std::set<set_value_type> 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<typename CharT, unsigned int Size>
struct is_any_of_fixedF :
public predicate_facade<is_any_of_fixedF<CharT, Size> >
{
// Boost.Lambda support
template <class Args> struct sig { typedef bool type; };
// Constructor
template<typename RangeT>
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<RangeT>::type It=::boost::begin(Range);
while(nIndex<Size && It!=::boost::end(Range))
{
m_Set[nIndex]=*It;
}
::std::sort(&m_Set[0], &m_Set[Size]);
}
// Operation
template<typename Char2T>
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<CharT>::type set_value_type;
set_value_type m_Set[Size];
};
// is_from_range functor
/*
returns true if the value is from the specified range.