1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
///////////////////////////////////////////////////////////////////////////////
// chset.hpp
//
// Copyright 2008 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)
# pragma once
#endif
#include <vector>
#include <boost/call_traits.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/detail/utility/algorithm.hpp>
#include <boost/xpressive/detail/utility/chset/basic_chset.ipp>
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// compound_charset
//
template<typename Traits>
struct compound_charset
: private basic_chset<typename Traits::char_type>
{
typedef typename Traits::char_type char_type;
typedef basic_chset<char_type> 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<char_type> const &base() const
{
return *this;
}
bool is_inverted() const
{
return this->complement_;
}
char_class_type posix_yes() const
{
return this->posix_yes_;
}
std::vector<char_class_type> const &posix_no() const
{
return this->posix_no_;
}
///////////////////////////////////////////////////////////////////////////////
// complement
void inverse()
{
this->complement_ = !this->complement_;
}
///////////////////////////////////////////////////////////////////////////////
// set
void set_char(char_type ch, Traits const &tr, bool icase)
{
icase ? this->base_type::set(ch, tr) : this->base_type::set(ch);
}
void set_range(char_type from, char_type to, Traits const &tr, bool icase)
{
icase ? this->base_type::set(from, to, tr) : 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<typename ICase>
bool test(char_type ch, Traits const &tr, ICase) const
{
return this->complement_ !=
(this->base_type::test(ch, tr, ICase()) ||
(this->has_posix_ && this->test_posix(ch, tr)));
}
private:
///////////////////////////////////////////////////////////////////////////////
// not_posix_pred
struct not_posix_pred
{
char_type ch_;
Traits const *traits_ptr_;
bool operator ()(typename call_traits<char_class_type>::param_type m) const
{
return !this->traits_ptr_->isctype(this->ch_, m);
}
};
///////////////////////////////////////////////////////////////////////////////
// test_posix
bool test_posix(char_type ch, Traits const &tr) const
{
not_posix_pred const pred = {ch, &tr};
return tr.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<char_class_type> posix_no_;
};
///////////////////////////////////////////////////////////////////////////////
// helpers
template<typename Char, typename Traits>
inline void set_char(compound_charset<Traits> &chset, Char ch, Traits const &tr, bool icase)
{
chset.set_char(ch, tr, icase);
}
template<typename Char, typename Traits>
inline void set_range(compound_charset<Traits> &chset, Char from, Char to, Traits const &tr, bool icase)
{
chset.set_range(from, to, tr, icase);
}
template<typename Traits>
inline void set_class(compound_charset<Traits> &chset, typename Traits::char_class_type char_class, bool no, Traits const &)
{
chset.set_class(char_class, no);
}
}}} // namespace boost::xpressive::detail
#endif
|