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