Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // chset.hpp Chris@16: // Chris@16: // Copyright 2008 Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005 Chris@16: #define BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005 Chris@16: Chris@16: // MS compatible compilers support #pragma once Chris@101: #if defined(_MSC_VER) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace xpressive { namespace detail Chris@16: { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // compound_charset Chris@16: // Chris@16: template Chris@16: struct compound_charset Chris@16: : private basic_chset Chris@16: { Chris@16: typedef typename Traits::char_type char_type; Chris@16: typedef basic_chset base_type; Chris@16: typedef Traits traits_type; Chris@16: typedef typename Traits::char_class_type char_class_type; Chris@16: Chris@16: compound_charset() Chris@16: : base_type() Chris@16: , complement_(false) Chris@16: , has_posix_(false) Chris@16: , posix_yes_() Chris@16: , posix_no_() Chris@16: { Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // accessors Chris@16: basic_chset const &base() const Chris@16: { Chris@16: return *this; Chris@16: } Chris@16: Chris@16: bool is_inverted() const Chris@16: { Chris@16: return this->complement_; Chris@16: } Chris@16: Chris@16: char_class_type posix_yes() const Chris@16: { Chris@16: return this->posix_yes_; Chris@16: } Chris@16: Chris@16: std::vector const &posix_no() const Chris@16: { Chris@16: return this->posix_no_; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // complement Chris@16: void inverse() Chris@16: { Chris@16: this->complement_ = !this->complement_; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // set Chris@16: void set_char(char_type ch, Traits const &tr, bool icase) Chris@16: { Chris@16: icase ? this->base_type::set(ch, tr) : this->base_type::set(ch); Chris@16: } Chris@16: Chris@16: void set_range(char_type from, char_type to, Traits const &tr, bool icase) Chris@16: { Chris@16: icase ? this->base_type::set(from, to, tr) : this->base_type::set(from, to); Chris@16: } Chris@16: Chris@16: void set_class(char_class_type const &m, bool no) Chris@16: { Chris@16: this->has_posix_ = true; Chris@16: Chris@16: if(no) Chris@16: { Chris@16: this->posix_no_.push_back(m); Chris@16: } Chris@16: else Chris@16: { Chris@16: this->posix_yes_ |= m; Chris@16: } Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // test Chris@16: template Chris@16: bool test(char_type ch, Traits const &tr, ICase) const Chris@16: { Chris@16: return this->complement_ != Chris@16: (this->base_type::test(ch, tr, ICase()) || Chris@16: (this->has_posix_ && this->test_posix(ch, tr))); Chris@16: } Chris@16: Chris@16: private: Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // not_posix_pred Chris@16: struct not_posix_pred Chris@16: { Chris@16: char_type ch_; Chris@16: Traits const *traits_ptr_; Chris@16: Chris@16: bool operator ()(typename call_traits::param_type m) const Chris@16: { Chris@16: return !this->traits_ptr_->isctype(this->ch_, m); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // test_posix Chris@16: bool test_posix(char_type ch, Traits const &tr) const Chris@16: { Chris@16: not_posix_pred const pred = {ch, &tr}; Chris@16: return tr.isctype(ch, this->posix_yes_) Chris@16: || any(this->posix_no_.begin(), this->posix_no_.end(), pred); Chris@16: } Chris@16: Chris@16: bool complement_; Chris@16: bool has_posix_; Chris@16: char_class_type posix_yes_; Chris@16: std::vector posix_no_; Chris@16: }; Chris@16: Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // helpers Chris@16: template Chris@16: inline void set_char(compound_charset &chset, Char ch, Traits const &tr, bool icase) Chris@16: { Chris@16: chset.set_char(ch, tr, icase); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void set_range(compound_charset &chset, Char from, Char to, Traits const &tr, bool icase) Chris@16: { Chris@16: chset.set_range(from, to, tr, icase); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void set_class(compound_charset &chset, typename Traits::char_class_type char_class, bool no, Traits const &) Chris@16: { Chris@16: chset.set_class(char_class, no); Chris@16: } Chris@16: Chris@16: }}} // namespace boost::xpressive::detail Chris@16: Chris@16: #endif Chris@16: