File indexing completed on 2025-01-18 09:53:51
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_SET_HPP_EAN_04_05_2007
0009 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_SET_HPP_EAN_04_05_2007
0010
0011
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015
0016 #include <boost/mpl/assert.hpp>
0017 #include <boost/proto/core.hpp>
0018 #include <boost/xpressive/detail/detail_fwd.hpp>
0019 #include <boost/xpressive/detail/static/static.hpp>
0020 #include <boost/xpressive/detail/utility/chset/chset.hpp>
0021 #include <boost/xpressive/detail/utility/traits_utils.hpp>
0022
0023 namespace boost { namespace xpressive { namespace grammar_detail
0024 {
0025
0026
0027
0028 template<typename Char>
0029 struct CharLiteral
0030 : or_<
0031 terminal<char>
0032 , terminal<Char>
0033 >
0034 {};
0035
0036 template<>
0037 struct CharLiteral<char>
0038 : terminal<char>
0039 {};
0040
0041
0042
0043
0044
0045 template<typename Char>
0046 struct ListSet
0047 : or_<
0048 when<
0049 comma<ListSet<Char>, CharLiteral<Char> >
0050 , make<mpl::next<call<ListSet<Char>(_left)> > >
0051 >
0052 , when<
0053 assign<detail::set_initializer_type, CharLiteral<Char> >
0054 , make<mpl::int_<1> >
0055 >
0056 >
0057 {};
0058
0059 template<typename Char, typename Traits>
0060 void fill_list_set(Char *&, detail::set_initializer_type, Traits const &)
0061 {}
0062
0063 template<typename Char, typename Expr, typename Traits>
0064 void fill_list_set(Char *&buffer, Expr const &expr, Traits const &traits)
0065 {
0066 fill_list_set(buffer, proto::left(expr), traits);
0067 *buffer++ = traits.translate(detail::char_cast<Char>(proto::value(proto::right(expr)), traits));
0068 }
0069
0070
0071
0072 template<typename Char, typename Callable = proto::callable>
0073 struct as_list_set_matcher : proto::transform<as_list_set_matcher<Char, Callable> >
0074 {
0075 template<typename Expr, typename State, typename Data>
0076 struct impl : proto::transform_impl<Expr, State, Data>
0077 {
0078 typedef typename impl::data data_type;
0079 typedef
0080 detail::set_matcher<
0081 typename data_type::traits_type
0082 , typename ListSet<Char>::template impl<Expr, State, Data>::result_type
0083 >
0084 result_type;
0085
0086 result_type operator ()(
0087 typename impl::expr_param expr
0088 , typename impl::state_param
0089 , typename impl::data_param data
0090 ) const
0091 {
0092 result_type set;
0093 typedef typename impl::data data_type;
0094 typename data_type::char_type *buffer = set.set_;
0095 fill_list_set(buffer, expr, data.traits());
0096 return set;
0097 }
0098 };
0099 };
0100
0101
0102
0103
0104 template<typename Grammar, typename CharSet, typename Data>
0105 struct merge_charset
0106 {
0107 typedef typename Data::traits_type traits_type;
0108 typedef typename CharSet::char_type char_type;
0109 typedef typename CharSet::icase_type icase_type;
0110
0111 merge_charset(CharSet &charset, Data &data)
0112 : charset_(charset)
0113 , visitor_(data)
0114 {}
0115
0116 template<typename Expr>
0117 void operator ()(Expr const &expr) const
0118 {
0119 this->call_(expr, typename Expr::proto_tag());
0120 }
0121
0122 private:
0123 merge_charset &operator =(merge_charset const &);
0124
0125 template<typename Expr, typename Tag>
0126 void call_(Expr const &expr, Tag) const
0127 {
0128 this->set_(
0129 typename Grammar::template impl<Expr const &, detail::end_xpression, Data &>()(
0130 expr
0131 , detail::end_xpression()
0132 , this->visitor_
0133 )
0134 );
0135 }
0136
0137 template<typename Expr>
0138 void call_(Expr const &expr, tag::bitwise_or) const
0139 {
0140 (*this)(proto::left(expr));
0141 (*this)(proto::right(expr));
0142 }
0143
0144 template<typename Not>
0145 void set_(detail::literal_matcher<traits_type, icase_type, Not> const &ch) const
0146 {
0147
0148 BOOST_MPL_ASSERT_NOT((Not));
0149 set_char(this->charset_.charset_, ch.ch_, this->visitor_.traits(), icase_type());
0150 }
0151
0152 void set_(detail::range_matcher<traits_type, icase_type> const &rg) const
0153 {
0154
0155 BOOST_ASSERT(!rg.not_);
0156 set_range(this->charset_.charset_, rg.ch_min_, rg.ch_max_, this->visitor_.traits(), icase_type());
0157 }
0158
0159 template<typename Size>
0160 void set_(detail::set_matcher<traits_type, Size> const &set_) const
0161 {
0162
0163 BOOST_ASSERT(!set_.not_);
0164 for(int i = 0; i < Size::value; ++i)
0165 {
0166 set_char(this->charset_.charset_, set_.set_[i], this->visitor_.traits(), icase_type());
0167 }
0168 }
0169
0170 void set_(detail::posix_charset_matcher<traits_type> const &posix) const
0171 {
0172 set_class(this->charset_.charset_, posix.mask_, posix.not_, this->visitor_.traits());
0173 }
0174
0175 CharSet &charset_;
0176 Data &visitor_;
0177 };
0178
0179
0180
0181 template<typename Grammar, typename Callable = proto::callable>
0182 struct as_set_matcher : proto::transform<as_set_matcher<Grammar, Callable> >
0183 {
0184 template<typename Expr, typename State, typename Data>
0185 struct impl : proto::transform_impl<Expr, State, Data>
0186 {
0187 typedef typename impl::data data_type;
0188 typedef typename data_type::char_type char_type;
0189
0190
0191
0192 typedef
0193 typename mpl::if_c<
0194 detail::is_narrow_char<char_type>::value
0195 , detail::basic_chset<char_type>
0196 , detail::compound_charset<typename data_type::traits_type>
0197 >::type
0198 charset_type;
0199
0200 typedef
0201 detail::charset_matcher<
0202 typename data_type::traits_type
0203 , typename data_type::icase_type
0204 , charset_type
0205 >
0206 result_type;
0207
0208 result_type operator ()(
0209 typename impl::expr_param expr
0210 , typename impl::state_param
0211 , typename impl::data_param data
0212 ) const
0213 {
0214 result_type matcher;
0215 merge_charset<Grammar, result_type, typename impl::data> merge(matcher, data);
0216 merge(expr);
0217 return matcher;
0218 }
0219 };
0220 };
0221
0222 }}}
0223
0224 #endif