/////////////////////////////////////////////////////////////////////////////// // chset.hpp // // Copyright 2007 Eric Niebler. Distributed under 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_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005 #define BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005 // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include #include #include #include #include namespace boost { namespace xpressive { namespace detail { /////////////////////////////////////////////////////////////////////////////// // compound_charset // template struct compound_charset : private basic_chset { typedef typename Traits::char_type char_type; typedef basic_chset base_type; typedef Traits traits_type; typedef typename Traits::char_class_type char_class_type; compound_charset() : base_type() , complement_(false) , has_posix_(false) , posix_yes_() , posix_no_() { } /////////////////////////////////////////////////////////////////////////////// // accessors basic_chset const &base() const { return *this; } bool is_inverted() const { return this->complement_; } char_class_type posix_yes() const { return this->posix_yes_; } std::vector const &posix_no() const { return this->posix_no_; } /////////////////////////////////////////////////////////////////////////////// // complement void inverse() { this->complement_ = !this->complement_; } /////////////////////////////////////////////////////////////////////////////// // set void set_char(char_type ch, Traits const &traits, bool icase) { icase ? this->base_type::set(ch, traits) : this->base_type::set(ch); } void set_range(char_type from, char_type to, Traits const &traits, bool icase) { icase ? this->base_type::set(from, to, traits) : this->base_type::set(from, to); } void set_class(char_class_type const &m, bool no) { this->has_posix_ = true; if(no) { this->posix_no_.push_back(m); } else { this->posix_yes_ |= m; } } /////////////////////////////////////////////////////////////////////////////// // test template bool test(char_type ch, Traits const &traits, ICase) const { return this->complement_ != (this->base_type::test(ch, traits, ICase()) || (this->has_posix_ && this->test_posix(ch, traits))); } private: /////////////////////////////////////////////////////////////////////////////// // not_posix_pred struct not_posix_pred { char_type ch_; Traits const *traits_ptr_; bool operator ()(typename call_traits::param_type m) const { return !this->traits_ptr_->isctype(this->ch_, m); } }; /////////////////////////////////////////////////////////////////////////////// // test_posix bool test_posix(char_type ch, Traits const &traits) const { not_posix_pred const pred = {ch, &traits}; return traits.isctype(ch, this->posix_yes_) || any(this->posix_no_.begin(), this->posix_no_.end(), pred); } bool complement_; bool has_posix_; char_class_type posix_yes_; std::vector posix_no_; }; /////////////////////////////////////////////////////////////////////////////// // helpers template inline void set_char(compound_charset &chset, Char ch, Traits const &traits, bool icase) { chset.set_char(ch, traits, icase); } template inline void set_range(compound_charset &chset, Char from, Char to, Traits const &traits, bool icase) { chset.set_range(from, to, traits, icase); } template inline void set_class(compound_charset &chset, typename Traits::char_class_type char_class, bool no, Traits const &) { chset.set_class(char_class, no); } }}} // namespace boost::xpressive::detail #endif