File indexing completed on 2025-01-31 10:02:37
0001
0002
0003
0004
0005
0006
0007
0008 #if !defined(BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM)
0009 #define BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM
0010
0011 #include <boost/spirit/home/x3/core/skip_over.hpp>
0012 #include <boost/spirit/home/x3/core/parser.hpp>
0013 #include <boost/spirit/home/x3/string/tst.hpp>
0014 #include <boost/spirit/home/x3/support/unused.hpp>
0015 #include <boost/spirit/home/x3/support/traits/string_traits.hpp>
0016 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
0017 #include <boost/spirit/home/x3/support/no_case.hpp>
0018
0019 #include <boost/spirit/home/support/char_encoding/ascii.hpp>
0020 #include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
0021 #include <boost/spirit/home/support/char_encoding/standard.hpp>
0022 #include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
0023
0024 #include <initializer_list>
0025 #include <iterator> // std::begin
0026 #include <memory> // std::shared_ptr
0027 #include <type_traits>
0028
0029 #if defined(BOOST_MSVC)
0030 # pragma warning(push)
0031 # pragma warning(disable: 4355)
0032 #endif
0033
0034 namespace boost { namespace spirit { namespace x3
0035 {
0036 template <
0037 typename Encoding
0038 , typename T = unused_type
0039 , typename Lookup = tst<typename Encoding::char_type, T> >
0040 struct symbols_parser : parser<symbols_parser<Encoding, T, Lookup>>
0041 {
0042 typedef typename Encoding::char_type char_type;
0043 typedef Encoding encoding;
0044 typedef T value_type;
0045 typedef value_type attribute_type;
0046
0047 static bool const has_attribute =
0048 !std::is_same<unused_type, attribute_type>::value;
0049 static bool const handles_container =
0050 traits::is_container<attribute_type>::value;
0051
0052 symbols_parser(std::string const& name = "symbols")
0053 : add{*this}
0054 , remove{*this}
0055 , lookup(std::make_shared<Lookup>())
0056 , name_(name)
0057 {
0058 }
0059
0060 symbols_parser(symbols_parser const& syms)
0061 : add{*this}
0062 , remove{*this}
0063 , lookup(syms.lookup)
0064 , name_(syms.name_)
0065 {
0066 }
0067
0068 template <typename Symbols>
0069 symbols_parser(Symbols const& syms, std::string const& name = "symbols")
0070 : symbols_parser(name)
0071 {
0072 for (auto& sym : syms)
0073 add(sym);
0074 }
0075
0076 template <typename Symbols, typename Data>
0077 symbols_parser(Symbols const& syms, Data const& data
0078 , std::string const& name = "symbols")
0079 : symbols_parser(name)
0080 {
0081 using std::begin;
0082 auto di = begin(data);
0083 for (auto& sym : syms)
0084 add(sym, *di++);
0085 }
0086
0087 symbols_parser(std::initializer_list<std::pair<char_type const*, T>> syms
0088 , std::string const & name="symbols")
0089 : symbols_parser(name)
0090 {
0091 for (auto& sym : syms)
0092 add(sym.first, sym.second);
0093 }
0094
0095 symbols_parser(std::initializer_list<char_type const*> syms
0096 , std::string const &name="symbols")
0097 : symbols_parser(name)
0098 {
0099 for (auto str : syms)
0100 add(str);
0101 }
0102
0103 symbols_parser&
0104 operator=(symbols_parser const& rhs)
0105 {
0106 name_ = rhs.name_;
0107 lookup = rhs.lookup;
0108 return *this;
0109 }
0110
0111 void clear()
0112 {
0113 lookup->clear();
0114 }
0115
0116 struct adder;
0117 struct remover;
0118
0119 template <typename Str>
0120 adder const&
0121 operator=(Str const& str)
0122 {
0123 lookup->clear();
0124 return add(str);
0125 }
0126
0127 template <typename Str>
0128 friend adder const&
0129 operator+=(symbols_parser& sym, Str const& str)
0130 {
0131 return sym.add(str);
0132 }
0133
0134 template <typename Str>
0135 friend remover const&
0136 operator-=(symbols_parser& sym, Str const& str)
0137 {
0138 return sym.remove(str);
0139 }
0140
0141 template <typename F>
0142 void for_each(F f) const
0143 {
0144 lookup->for_each(f);
0145 }
0146
0147 template <typename Str>
0148 value_type& at(Str const& str)
0149 {
0150 return *lookup->add(traits::get_string_begin<char_type>(str)
0151 , traits::get_string_end<char_type>(str), T());
0152 }
0153
0154 template <typename Iterator>
0155 value_type* prefix_find(Iterator& first, Iterator const& last)
0156 {
0157 return lookup->find(first, last, case_compare<Encoding>());
0158 }
0159
0160 template <typename Iterator>
0161 value_type const* prefix_find(Iterator& first, Iterator const& last) const
0162 {
0163 return lookup->find(first, last, case_compare<Encoding>());
0164 }
0165
0166 template <typename Str>
0167 value_type* find(Str const& str)
0168 {
0169 return find_impl(traits::get_string_begin<char_type>(str)
0170 , traits::get_string_end<char_type>(str));
0171 }
0172
0173 template <typename Str>
0174 value_type const* find(Str const& str) const
0175 {
0176 return find_impl(traits::get_string_begin<char_type>(str)
0177 , traits::get_string_end<char_type>(str));
0178 }
0179
0180 private:
0181
0182 template <typename Iterator>
0183 value_type* find_impl(Iterator begin, Iterator end)
0184 {
0185 value_type* r = lookup->find(begin, end, case_compare<Encoding>());
0186 return begin == end ? r : 0;
0187 }
0188
0189 template <typename Iterator>
0190 value_type const* find_impl(Iterator begin, Iterator end) const
0191 {
0192 value_type const* r = lookup->find(begin, end, case_compare<Encoding>());
0193 return begin == end ? r : 0;
0194 }
0195
0196 public:
0197
0198 template <typename Iterator, typename Context, typename Attribute>
0199 bool parse(Iterator& first, Iterator const& last
0200 , Context const& context, unused_type, Attribute& attr) const
0201 {
0202 x3::skip_over(first, last, context);
0203
0204 if (value_type const* val_ptr
0205 = lookup->find(first, last, get_case_compare<Encoding>(context)))
0206 {
0207 x3::traits::move_to(*val_ptr, attr);
0208 return true;
0209 }
0210 return false;
0211 }
0212
0213 void name(std::string const &str)
0214 {
0215 name_ = str;
0216 }
0217 std::string const &name() const
0218 {
0219 return name_;
0220 }
0221
0222 struct adder
0223 {
0224 template <typename Iterator>
0225 adder const&
0226 operator()(Iterator first, Iterator last, T const& val) const
0227 {
0228 sym.lookup->add(first, last, val);
0229 return *this;
0230 }
0231
0232 template <typename Str>
0233 adder const&
0234 operator()(Str const& s, T const& val = T()) const
0235 {
0236 sym.lookup->add(traits::get_string_begin<char_type>(s)
0237 , traits::get_string_end<char_type>(s), val);
0238 return *this;
0239 }
0240
0241 template <typename Str>
0242 adder const&
0243 operator,(Str const& s) const
0244 {
0245 sym.lookup->add(traits::get_string_begin<char_type>(s)
0246 , traits::get_string_end<char_type>(s), T());
0247 return *this;
0248 }
0249
0250 symbols_parser& sym;
0251 };
0252
0253 struct remover
0254 {
0255 template <typename Iterator>
0256 remover const&
0257 operator()(Iterator const& first, Iterator const& last) const
0258 {
0259 sym.lookup->remove(first, last);
0260 return *this;
0261 }
0262
0263 template <typename Str>
0264 remover const&
0265 operator()(Str const& s) const
0266 {
0267 sym.lookup->remove(traits::get_string_begin<char_type>(s)
0268 , traits::get_string_end<char_type>(s));
0269 return *this;
0270 }
0271
0272 template <typename Str>
0273 remover const&
0274 operator,(Str const& s) const
0275 {
0276 sym.lookup->remove(traits::get_string_begin<char_type>(s)
0277 , traits::get_string_end<char_type>(s));
0278 return *this;
0279 }
0280
0281 symbols_parser& sym;
0282 };
0283
0284 adder add;
0285 remover remove;
0286 std::shared_ptr<Lookup> lookup;
0287 std::string name_;
0288 };
0289
0290 template <typename Encoding, typename T, typename Lookup>
0291 struct get_info<symbols_parser<Encoding, T, Lookup>>
0292 {
0293 typedef std::string result_type;
0294 result_type operator()(symbols_parser< Encoding, T
0295 , Lookup
0296 > const& symbols) const
0297 {
0298 return symbols.name();
0299 }
0300 };
0301
0302 namespace standard
0303 {
0304 template <typename T = unused_type>
0305 using symbols = symbols_parser<char_encoding::standard, T>;
0306 }
0307
0308 using standard::symbols;
0309
0310 #ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
0311 namespace standard_wide
0312 {
0313 template <typename T = unused_type>
0314 using symbols = symbols_parser<char_encoding::standard_wide, T>;
0315 }
0316 #endif
0317
0318 namespace ascii
0319 {
0320 template <typename T = unused_type>
0321 using symbols = symbols_parser<char_encoding::ascii, T>;
0322 }
0323
0324 namespace iso8859_1
0325 {
0326 template <typename T = unused_type>
0327 using symbols = symbols_parser<char_encoding::iso8859_1, T>;
0328 }
0329
0330 }}}
0331
0332 #if defined(BOOST_MSVC)
0333 # pragma warning(pop)
0334 #endif
0335
0336 #endif