Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:51

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // chset.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005
0009 #define BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005
0010 
0011 // MS compatible compilers support #pragma once
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015 
0016 #include <vector>
0017 #include <boost/call_traits.hpp>
0018 #include <boost/xpressive/detail/detail_fwd.hpp>
0019 #include <boost/xpressive/detail/utility/algorithm.hpp>
0020 #include <boost/xpressive/detail/utility/chset/basic_chset.ipp>
0021 
0022 namespace boost { namespace xpressive { namespace detail
0023 {
0024 
0025 ///////////////////////////////////////////////////////////////////////////////
0026 // compound_charset
0027 //
0028 template<typename Traits>
0029 struct compound_charset
0030   : private basic_chset<typename Traits::char_type>
0031 {
0032     typedef typename Traits::char_type char_type;
0033     typedef basic_chset<char_type> base_type;
0034     typedef Traits traits_type;
0035     typedef typename Traits::char_class_type char_class_type;
0036 
0037     compound_charset()
0038       : base_type()
0039       , complement_(false)
0040       , has_posix_(false)
0041       , posix_yes_()
0042       , posix_no_()
0043     {
0044     }
0045 
0046     ///////////////////////////////////////////////////////////////////////////////
0047     // accessors
0048     basic_chset<char_type> const &base() const
0049     {
0050         return *this;
0051     }
0052 
0053     bool is_inverted() const
0054     {
0055         return this->complement_;
0056     }
0057 
0058     char_class_type posix_yes() const
0059     {
0060         return this->posix_yes_;
0061     }
0062 
0063     std::vector<char_class_type> const &posix_no() const
0064     {
0065         return this->posix_no_;
0066     }
0067 
0068     ///////////////////////////////////////////////////////////////////////////////
0069     // complement
0070     void inverse()
0071     {
0072         this->complement_ = !this->complement_;
0073     }
0074 
0075     ///////////////////////////////////////////////////////////////////////////////
0076     // set
0077     void set_char(char_type ch, Traits const &tr, bool icase)
0078     {
0079         icase ? this->base_type::set(ch, tr) : this->base_type::set(ch);
0080     }
0081 
0082     void set_range(char_type from, char_type to, Traits const &tr, bool icase)
0083     {
0084         icase ? this->base_type::set(from, to, tr) : this->base_type::set(from, to);
0085     }
0086 
0087     void set_class(char_class_type const &m, bool no)
0088     {
0089         this->has_posix_ = true;
0090 
0091         if(no)
0092         {
0093             this->posix_no_.push_back(m);
0094         }
0095         else
0096         {
0097             this->posix_yes_ |= m;
0098         }
0099     }
0100 
0101     ///////////////////////////////////////////////////////////////////////////////
0102     // test
0103     template<typename ICase>
0104     bool test(char_type ch, Traits const &tr, ICase) const
0105     {
0106         return this->complement_ !=
0107             (this->base_type::test(ch, tr, ICase()) ||
0108             (this->has_posix_ && this->test_posix(ch, tr)));
0109     }
0110 
0111 private:
0112 
0113     ///////////////////////////////////////////////////////////////////////////////
0114     // not_posix_pred
0115     struct not_posix_pred
0116     {
0117         char_type ch_;
0118         Traits const *traits_ptr_;
0119 
0120         bool operator ()(typename call_traits<char_class_type>::param_type m) const
0121         {
0122             return !this->traits_ptr_->isctype(this->ch_, m);
0123         }
0124     };
0125 
0126     ///////////////////////////////////////////////////////////////////////////////
0127     // test_posix
0128     bool test_posix(char_type ch, Traits const &tr) const
0129     {
0130         not_posix_pred const pred = {ch, &tr};
0131         return tr.isctype(ch, this->posix_yes_)
0132             || any(this->posix_no_.begin(), this->posix_no_.end(), pred);
0133     }
0134 
0135     bool complement_;
0136     bool has_posix_;
0137     char_class_type posix_yes_;
0138     std::vector<char_class_type> posix_no_;
0139 };
0140 
0141 
0142 ///////////////////////////////////////////////////////////////////////////////
0143 // helpers
0144 template<typename Char, typename Traits>
0145 inline void set_char(compound_charset<Traits> &chset, Char ch, Traits const &tr, bool icase)
0146 {
0147     chset.set_char(ch, tr, icase);
0148 }
0149 
0150 template<typename Char, typename Traits>
0151 inline void set_range(compound_charset<Traits> &chset, Char from, Char to, Traits const &tr, bool icase)
0152 {
0153     chset.set_range(from, to, tr, icase);
0154 }
0155 
0156 template<typename Traits>
0157 inline void set_class(compound_charset<Traits> &chset, typename Traits::char_class_type char_class, bool no, Traits const &)
0158 {
0159     chset.set_class(char_class, no);
0160 }
0161 
0162 }}} // namespace boost::xpressive::detail
0163 
0164 #endif
0165