boost/xpressive/detail/utility/chset/basic_chset.ipp
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
Copyright (c) 2001-2003 Daniel Nuffer
http://spirit.sourceforge.net/
Use, modification and distribution is subject to 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)
=============================================================================*/
#ifndef BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
#define BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
///////////////////////////////////////////////////////////////////////////////
#include <bitset>
#include <boost/xpressive/detail/utility/chset/basic_chset.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
//
// basic_chset: character set implementation
//
///////////////////////////////////////////////////////////////////////////////
template<typename Char>
inline basic_chset<Char>::basic_chset()
{
}
//////////////////////////////////
template<typename Char>
inline basic_chset<Char>::basic_chset(basic_chset const &arg)
: rr_(arg.rr_)
{
}
//////////////////////////////////
template<typename Char>
inline bool basic_chset<Char>::empty() const
{
return this->rr_.empty();
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline bool basic_chset<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive
{
return this->rr_.test(v);
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline bool basic_chset<Char>::test(Char v, Traits const &traits, mpl::true_) const // case-insensitive
{
return this->rr_.test(v, traits);
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::set(Char from, Char to)
{
this->rr_.set(range<Char>(from, to));
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset<Char>::set(Char from, Char to, Traits const &)
{
this->rr_.set(range<Char>(from, to));
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::set(Char c)
{
this->rr_.set(range<Char>(c, c));
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset<Char>::set(Char c, Traits const &)
{
this->rr_.set(range<Char>(c, c));
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::clear(Char c)
{
this->rr_.clear(range<Char>(c, c));
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset<Char>::clear(Char c, Traits const &)
{
this->rr_.clear(range<Char>(c, c));
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::clear(Char from, Char to)
{
this->rr_.clear(range<Char>(from, to));
}
//////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset<Char>::clear(Char from, Char to, Traits const &)
{
this->rr_.clear(range<Char>(from, to));
}
//////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::clear()
{
this->rr_.clear();
}
/////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::inverse()
{
// BUGBUG is this right? Does this handle icase correctly?
basic_chset<Char> inv;
inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)());
inv -= *this;
this->swap(inv);
}
/////////////////////////////////
template<typename Char>
inline void basic_chset<Char>::swap(basic_chset<Char> &that)
{
this->rr_.swap(that.rr_);
}
/////////////////////////////////
template<typename Char>
inline basic_chset<Char> &
basic_chset<Char>::operator |=(basic_chset<Char> const &that)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
{
this->rr_.set(*iter);
}
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset<Char> &
basic_chset<Char>::operator &=(basic_chset<Char> const &that)
{
basic_chset<Char> inv;
inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)());
inv -= that;
*this -= inv;
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset<Char> &
basic_chset<Char>::operator -=(basic_chset<Char> const &that)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
{
this->rr_.clear(*iter);
}
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset<Char> &
basic_chset<Char>::operator ^=(basic_chset<Char> const &that)
{
basic_chset bma = that;
bma -= *this;
*this -= that;
*this |= bma;
return *this;
}
#if(CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////////
//
// basic_chset: specializations for 8 bit chars using std::bitset
//
///////////////////////////////////////////////////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char>::basic_chset_8bit()
{
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char>::basic_chset_8bit(basic_chset_8bit<Char> const &arg)
: bset_(arg.bset_)
{
}
/////////////////////////////////
template<typename Char>
inline bool basic_chset_8bit<Char>::empty() const
{
return !this->bset_.any();
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline bool basic_chset_8bit<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive
{
return this->bset_.test((unsigned char)v);
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline bool basic_chset_8bit<Char>::test(Char v, Traits const &traits, mpl::true_) const // case-insensitive
{
return this->bset_.test((unsigned char)traits.translate_nocase(v));
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::set(Char from, Char to)
{
for(int i = from; i <= to; ++i)
{
this->bset_.set((unsigned char)i);
}
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset_8bit<Char>::set(Char from, Char to, Traits const &traits)
{
for(int i = from; i <= to; ++i)
{
this->bset_.set((unsigned char)traits.translate_nocase((Char)i));
}
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::set(Char c)
{
this->bset_.set((unsigned char)c);
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset_8bit<Char>::set(Char c, Traits const &traits)
{
this->bset_.set((unsigned char)traits.translate_nocase(c));
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::clear(Char from, Char to)
{
for(int i = from; i <= to; ++i)
{
this->bset_.reset((unsigned char)i);
}
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset_8bit<Char>::clear(Char from, Char to, Traits const &traits)
{
for(int i = from; i <= to; ++i)
{
this->bset_.reset((unsigned char)traits.translate_nocase((Char)i));
}
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::clear(Char c)
{
this->bset_.reset((unsigned char)c);
}
/////////////////////////////////
template<typename Char>
template<typename Traits>
inline void basic_chset_8bit<Char>::clear(Char c, Traits const &traits)
{
this->bset_.reset((unsigned char)traits.tranlsate_nocase(c));
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::clear()
{
this->bset_.reset();
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::inverse()
{
this->bset_.flip();
}
/////////////////////////////////
template<typename Char>
inline void basic_chset_8bit<Char>::swap(basic_chset_8bit<Char> &that)
{
std::swap(this->bset_, that.bset_);
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char> &
basic_chset_8bit<Char>::operator |=(basic_chset_8bit<Char> const &that)
{
this->bset_ |= that.bset_;
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char> &
basic_chset_8bit<Char>::operator &=(basic_chset_8bit<Char> const &that)
{
this->bset_ &= that.bset_;
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char> &
basic_chset_8bit<Char>::operator -=(basic_chset_8bit<Char> const &that)
{
this->bset_ &= ~that.bset_;
return *this;
}
/////////////////////////////////
template<typename Char>
inline basic_chset_8bit<Char> &
basic_chset_8bit<Char>::operator ^=(basic_chset_8bit<Char> const &that)
{
this->bset_ ^= that.bset_;
return *this;
}
template<typename Char>
inline std::bitset<256> const &
basic_chset_8bit<Char>::base() const
{
return this->bset_;
}
#endif // if(CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////////
// helpers
template<typename Char, typename Traits>
inline void set_char(basic_chset<Char> &chset, Char ch, Traits const &traits, bool icase)
{
icase ? chset.set(ch, traits) : chset.set(ch);
}
template<typename Char, typename Traits>
inline void set_range(basic_chset<Char> &chset, Char from, Char to, Traits const &traits, bool icase)
{
icase ? chset.set(from, to, traits) : chset.set(from, to);
}
template<typename Char, typename Traits>
inline void set_class(basic_chset<Char> &chset, typename Traits::char_class_type char_class, bool no, Traits const &traits)
{
BOOST_MPL_ASSERT_RELATION(1, ==, sizeof(Char));
for(std::size_t i = 0; i <= UCHAR_MAX; ++i)
{
typedef typename std::char_traits<Char>::int_type int_type;
Char ch = std::char_traits<Char>::to_char_type(static_cast<int_type>(i));
if(no != traits.isctype(ch, char_class))
{
chset.set(ch);
}
}
}
}}} // namespace boost::xpressive::detail
#endif