mirror of
https://github.com/boostorg/algorithm.git
synced 2025-07-01 15:00:59 +02:00
is_any_ofF performance improvements
tabs removed [SVN r46496]
This commit is contained in:
@ -202,8 +202,8 @@ namespace boost {
|
|||||||
BOOST_STRING_TYPENAME range_value<RangeT>::type>
|
BOOST_STRING_TYPENAME range_value<RangeT>::type>
|
||||||
is_any_of( const RangeT& Set )
|
is_any_of( const RangeT& Set )
|
||||||
{
|
{
|
||||||
return detail::is_any_ofF<
|
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_set(as_literal(Set));
|
||||||
BOOST_STRING_TYPENAME range_value<RangeT>::type>(as_literal(Set));
|
return detail::is_any_ofF<BOOST_STRING_TYPENAME range_value<RangeT>::type>(lit_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! is_from_range predicate
|
//! is_from_range predicate
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include <boost/range/begin.hpp>
|
#include <boost/range/begin.hpp>
|
||||||
#include <boost/range/end.hpp>
|
#include <boost/range/end.hpp>
|
||||||
@ -76,27 +75,178 @@ namespace boost {
|
|||||||
struct is_any_ofF :
|
struct is_any_ofF :
|
||||||
public predicate_facade<is_any_ofF<CharT> >
|
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
|
// Boost.Lambda support
|
||||||
template <class Args> struct sig { typedef bool type; };
|
template <class Args> struct sig { typedef bool type; };
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
template<typename RangeT>
|
template<typename RangeT>
|
||||||
is_any_ofF( const RangeT& Range ) :
|
is_any_ofF( const RangeT& Range ) : m_Size(0)
|
||||||
m_Set( ::boost::begin(Range), ::boost::end(Range) ) {}
|
{
|
||||||
|
// 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
|
// Operation
|
||||||
template<typename Char2T>
|
template<typename Char2T>
|
||||||
bool operator()( Char2T Ch ) const
|
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:
|
private:
|
||||||
// set cannot operate on const value-type
|
// set cannot operate on const value-type
|
||||||
typedef typename remove_const<CharT>::type set_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
|
// is_from_range functor
|
||||||
/*
|
/*
|
||||||
returns true if the value is from the specified range.
|
returns true if the value is from the specified range.
|
||||||
|
Reference in New Issue
Block a user