Back to home page

EIC code displayed by LXR

 
 

    


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

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // as_set.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_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 // MS compatible compilers support #pragma once
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     // CharLiteral
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     // ListSet
0043     //  matches expressions like (set= 'a','b','c')
0044     //  calculates the size of the set
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)> > > // TODO make a custom transform for this...
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     // as_list_set_matcher
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     // merge_charset
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             // BUGBUG fixme!
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             // BUGBUG fixme!
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             // BUGBUG fixme!
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             // if sizeof(char_type)==1, merge everything into a basic_chset
0191             // BUGBUG this is not optimal.
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); // Walks the tree and fills in the charset
0217                 return matcher;
0218             }
0219         };
0220     };
0221 
0222 }}}
0223 
0224 #endif