| /*============================================================================= |
| 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 &tr, mpl::true_) const // case-insensitive |
| { |
| return this->rr_.test(v, tr); |
| } |
| |
| ////////////////////////////////// |
| 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 &tr, mpl::true_) const // case-insensitive |
| { |
| return this->bset_.test((unsigned char)tr.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 &tr) |
| { |
| for(int i = from; i <= to; ++i) |
| { |
| this->bset_.set((unsigned char)tr.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 &tr) |
| { |
| this->bset_.set((unsigned char)tr.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 &tr) |
| { |
| for(int i = from; i <= to; ++i) |
| { |
| this->bset_.reset((unsigned char)tr.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 &tr) |
| { |
| this->bset_.reset((unsigned char)tr.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 &tr, bool icase) |
| { |
| icase ? chset.set(ch, tr) : chset.set(ch); |
| } |
| |
| template<typename Char, typename Traits> |
| inline void set_range(basic_chset<Char> &chset, Char from, Char to, Traits const &tr, bool icase) |
| { |
| icase ? chset.set(from, to, tr) : 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 &tr) |
| { |
| 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 != tr.isctype(ch, char_class)) |
| { |
| chset.set(ch); |
| } |
| } |
| } |
| |
| }}} // namespace boost::xpressive::detail |
| |
| #endif |
| |