annotate DEPENDENCIES/generic/include/boost/spirit/home/karma/string/symbols.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright (c) 2001-2011 Hartmut Kaiser
Chris@16 2 //
Chris@16 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 #if !defined(BOOST_SPIRIT_KARMA_SYMBOLS_NOV_23_2009_1251PM)
Chris@16 7 #define BOOST_SPIRIT_KARMA_SYMBOLS_NOV_23_2009_1251PM
Chris@16 8
Chris@16 9 #include <boost/spirit/home/support/common_terminals.hpp>
Chris@16 10 #include <boost/spirit/home/support/info.hpp>
Chris@16 11 #include <boost/spirit/home/support/unused.hpp>
Chris@16 12 #include <boost/spirit/home/support/attributes_fwd.hpp>
Chris@16 13 #include <boost/spirit/home/support/detail/get_encoding.hpp>
Chris@16 14 #include <boost/spirit/home/karma/detail/attributes.hpp>
Chris@16 15 #include <boost/spirit/home/karma/detail/extract_from.hpp>
Chris@16 16 #include <boost/spirit/home/karma/domain.hpp>
Chris@16 17 #include <boost/spirit/home/karma/meta_compiler.hpp>
Chris@16 18 #include <boost/spirit/home/karma/reference.hpp>
Chris@16 19 #include <boost/spirit/home/karma/generate.hpp>
Chris@16 20 #include <boost/spirit/home/karma/delimit_out.hpp>
Chris@16 21 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
Chris@16 22 #include <boost/spirit/home/karma/detail/string_generate.hpp>
Chris@16 23 #include <boost/config.hpp>
Chris@16 24 #include <boost/shared_ptr.hpp>
Chris@16 25 #include <boost/mpl/if.hpp>
Chris@16 26 #include <map>
Chris@16 27 #include <set>
Chris@16 28
Chris@16 29 #if defined(BOOST_MSVC)
Chris@16 30 # pragma warning(push)
Chris@16 31 # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
Chris@16 32 #endif
Chris@16 33
Chris@16 34 ///////////////////////////////////////////////////////////////////////////////
Chris@16 35 namespace boost { namespace spirit { namespace traits
Chris@16 36 {
Chris@16 37 template <typename T, typename Attribute, typename Enable>
Chris@16 38 struct symbols_lookup
Chris@16 39 {
Chris@16 40 typedef
Chris@16 41 mpl::eval_if<fusion::traits::is_sequence<T>
Chris@16 42 , traits::detail::value_at_c<T, 0>
Chris@16 43 , detail::add_const_ref<T> > sequence_type;
Chris@16 44 typedef typename
Chris@16 45 mpl::eval_if<traits::is_container<T>
Chris@16 46 , traits::container_value<T>
Chris@16 47 , sequence_type>::type type;
Chris@16 48
Chris@16 49 // fusion sequence
Chris@16 50 template <typename T_>
Chris@16 51 static type call(T_ const& t, mpl::false_, mpl::true_)
Chris@16 52 {
Chris@16 53 return fusion::at_c<0>(t);
Chris@16 54 }
Chris@16 55
Chris@16 56 // container
Chris@16 57 template <typename T_, typename IsSequence>
Chris@16 58 static type call(T_ const& t, mpl::true_, IsSequence)
Chris@16 59 {
Chris@16 60 return t[0];
Chris@16 61 }
Chris@16 62
Chris@16 63 // not a container and not a fusion sequence
Chris@16 64 template <typename T_>
Chris@16 65 static type call(T_ const& t, mpl::false_, mpl::false_)
Chris@16 66 {
Chris@16 67 return t;
Chris@16 68 }
Chris@16 69
Chris@16 70 static type call(T const& t)
Chris@16 71 {
Chris@16 72 typedef typename traits::is_container<T>::type is_container;
Chris@16 73 typedef typename fusion::traits::is_sequence<T>::type is_sequence;
Chris@16 74
Chris@16 75 return call(t, is_container(), is_sequence());
Chris@16 76 }
Chris@16 77 };
Chris@16 78
Chris@16 79 template <typename Attribute>
Chris@16 80 struct symbols_lookup<Attribute, Attribute>
Chris@16 81 {
Chris@16 82 typedef Attribute const& type;
Chris@16 83
Chris@16 84 static type call(Attribute const& t)
Chris@16 85 {
Chris@16 86 return t;
Chris@16 87 }
Chris@16 88 };
Chris@16 89
Chris@16 90 template <typename Attribute, typename T, typename Enable>
Chris@16 91 struct symbols_value
Chris@16 92 {
Chris@16 93 typedef
Chris@16 94 mpl::eval_if<fusion::traits::is_sequence<T>
Chris@16 95 , traits::detail::value_at_c<T, 1>
Chris@16 96 , mpl::identity<unused_type> > sequence_type;
Chris@16 97 typedef typename
Chris@16 98 mpl::eval_if<traits::is_container<T>
Chris@16 99 , traits::container_value<T>
Chris@16 100 , sequence_type>::type type;
Chris@16 101
Chris@16 102 // fusion sequence
Chris@16 103 template <typename T_>
Chris@16 104 static type call(T_ const& t, mpl::false_, mpl::true_)
Chris@16 105 {
Chris@16 106 return fusion::at_c<1>(t);
Chris@16 107 }
Chris@16 108
Chris@16 109 // container
Chris@16 110 template <typename T_, typename IsSequence>
Chris@16 111 static type call(T_ const& t, mpl::true_, IsSequence)
Chris@16 112 {
Chris@16 113 return t[1];
Chris@16 114 }
Chris@16 115
Chris@16 116 // not a container nor a fusion sequence
Chris@16 117 template <typename T_>
Chris@16 118 static type call(T_ const&, mpl::false_, mpl::false_)
Chris@16 119 {
Chris@16 120 return unused;
Chris@16 121 }
Chris@16 122
Chris@16 123 static type call(T const& t)
Chris@16 124 {
Chris@16 125 typedef typename traits::is_container<T>::type is_container;
Chris@16 126 typedef typename fusion::traits::is_sequence<T>::type is_sequence;
Chris@16 127
Chris@16 128 return call(t, is_container(), is_sequence());
Chris@16 129 }
Chris@16 130 };
Chris@16 131
Chris@16 132 template <typename Attribute>
Chris@16 133 struct symbols_value<Attribute, Attribute>
Chris@16 134 {
Chris@16 135 typedef unused_type type;
Chris@16 136
Chris@16 137 static type call(Attribute const&)
Chris@16 138 {
Chris@16 139 return unused;
Chris@16 140 }
Chris@16 141 };
Chris@16 142 }}}
Chris@16 143
Chris@16 144 ///////////////////////////////////////////////////////////////////////////////
Chris@16 145 namespace boost { namespace spirit { namespace karma
Chris@16 146 {
Chris@16 147 ///////////////////////////////////////////////////////////////////////////
Chris@16 148 template <typename T, typename Attribute>
Chris@16 149 struct symbols_lookup
Chris@16 150 : mpl::if_<
Chris@16 151 traits::not_is_unused<T>
Chris@16 152 , std::map<Attribute, T>
Chris@16 153 , std::set<Attribute>
Chris@16 154 >
Chris@16 155 {};
Chris@16 156
Chris@16 157 ///////////////////////////////////////////////////////////////////////////
Chris@16 158 namespace detail
Chris@16 159 {
Chris@16 160 ///////////////////////////////////////////////////////////////////////
Chris@16 161 template <typename CharEncoding, typename Tag>
Chris@16 162 struct generate_encoded
Chris@16 163 {
Chris@16 164 typedef typename
Chris@16 165 proto::terminal<tag::char_code<Tag, CharEncoding> >::type
Chris@16 166 encoding_type;
Chris@16 167
Chris@16 168 template <typename OutputIterator, typename Expr, typename Attribute>
Chris@16 169 static bool call(OutputIterator& sink, Expr const& expr
Chris@16 170 , Attribute const& attr)
Chris@16 171 {
Chris@16 172 encoding_type const encoding = encoding_type();
Chris@16 173 return karma::generate(sink, encoding[expr], attr);
Chris@16 174 }
Chris@16 175 };
Chris@16 176
Chris@16 177 template <>
Chris@16 178 struct generate_encoded<unused_type, unused_type>
Chris@16 179 {
Chris@16 180 template <typename OutputIterator, typename Expr, typename Attribute>
Chris@16 181 static bool call(OutputIterator& sink, Expr const& expr
Chris@16 182 , Attribute const& attr)
Chris@16 183 {
Chris@16 184 return karma::generate(sink, expr, attr);
Chris@16 185 }
Chris@16 186 };
Chris@16 187 }
Chris@16 188
Chris@16 189 template <
Chris@16 190 typename Attribute = char, typename T = unused_type
Chris@16 191 , typename Lookup = typename symbols_lookup<T, Attribute>::type
Chris@16 192 , typename CharEncoding = unused_type, typename Tag = unused_type>
Chris@16 193 struct symbols
Chris@16 194 : proto::extends<
Chris@16 195 typename proto::terminal<
Chris@16 196 reference<symbols<Attribute, T, Lookup, CharEncoding, Tag> >
Chris@16 197 >::type
Chris@16 198 , symbols<Attribute, T, Lookup, CharEncoding, Tag> >
Chris@16 199 , primitive_generator<
Chris@16 200 symbols<Attribute, T, Lookup, CharEncoding, Tag> >
Chris@16 201 {
Chris@16 202 typedef T value_type; // the value associated with each entry
Chris@16 203
Chris@16 204 typedef reference<symbols> reference_;
Chris@16 205 typedef typename proto::terminal<reference_>::type terminal;
Chris@16 206 typedef proto::extends<terminal, symbols> base_type;
Chris@16 207
Chris@16 208 template <typename Context, typename Unused>
Chris@16 209 struct attribute
Chris@16 210 {
Chris@16 211 typedef Attribute type;
Chris@16 212 };
Chris@16 213
Chris@16 214 symbols(std::string const& name = "symbols")
Chris@16 215 : base_type(terminal::make(reference_(*this)))
Chris@16 216 , add(*this)
Chris@16 217 , remove(*this)
Chris@16 218 , lookup(new Lookup())
Chris@16 219 , name_(name)
Chris@16 220 {}
Chris@16 221
Chris@16 222 symbols(symbols const& syms)
Chris@16 223 : base_type(terminal::make(reference_(*this)))
Chris@16 224 , add(*this)
Chris@16 225 , remove(*this)
Chris@16 226 , lookup(syms.lookup)
Chris@16 227 , name_(syms.name_)
Chris@16 228 {}
Chris@16 229
Chris@16 230 template <typename CharEncoding_, typename Tag_>
Chris@16 231 symbols(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& syms)
Chris@16 232 : base_type(terminal::make(reference_(*this)))
Chris@16 233 , add(*this)
Chris@16 234 , remove(*this)
Chris@16 235 , lookup(syms.lookup)
Chris@16 236 , name_(syms.name_)
Chris@16 237 {}
Chris@16 238
Chris@16 239 template <typename Symbols, typename Data>
Chris@16 240 symbols(Symbols const& syms, Data const& data
Chris@16 241 , std::string const& name = "symbols")
Chris@16 242 : base_type(terminal::make(reference_(*this)))
Chris@16 243 , add(*this)
Chris@16 244 , remove(*this)
Chris@16 245 , lookup(new Lookup())
Chris@16 246 , name_(name)
Chris@16 247 {
Chris@16 248 typename range_const_iterator<Symbols>::type si = boost::begin(syms);
Chris@16 249 typename range_const_iterator<Data>::type di = boost::begin(data);
Chris@16 250 while (si != boost::end(syms))
Chris@16 251 add(*si++, *di++);
Chris@16 252 }
Chris@16 253
Chris@16 254 symbols&
Chris@16 255 operator=(symbols const& rhs)
Chris@16 256 {
Chris@16 257 *lookup = *rhs.lookup;
Chris@16 258 name_ = rhs.name_;
Chris@16 259 return *this;
Chris@16 260 }
Chris@16 261
Chris@16 262 template <typename CharEncoding_, typename Tag_>
Chris@16 263 symbols&
Chris@16 264 operator=(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& rhs)
Chris@16 265 {
Chris@16 266 *lookup = *rhs.lookup;
Chris@16 267 name_ = rhs.name_;
Chris@16 268 return *this;
Chris@16 269 }
Chris@16 270
Chris@16 271 void clear()
Chris@16 272 {
Chris@16 273 lookup->clear();
Chris@16 274 }
Chris@16 275
Chris@16 276 struct adder;
Chris@16 277 struct remover;
Chris@16 278
Chris@16 279 template <typename Attr, typename T_>
Chris@16 280 adder const&
Chris@16 281 operator=(std::pair<Attr, T_> const& p)
Chris@16 282 {
Chris@16 283 lookup->clear();
Chris@16 284 return add(p.first, p.second);
Chris@16 285 }
Chris@16 286
Chris@16 287 template <typename Attr, typename T_>
Chris@16 288 friend adder const&
Chris@16 289 operator+= (symbols& sym, std::pair<Attr, T_> const& p)
Chris@16 290 {
Chris@16 291 return sym.add(p.first, p.second);
Chris@16 292 }
Chris@16 293
Chris@16 294 template <typename Attr>
Chris@16 295 friend remover const&
Chris@16 296 operator-= (symbols& sym, Attr const& attr)
Chris@16 297 {
Chris@16 298 return sym.remove(attr);
Chris@16 299 }
Chris@16 300
Chris@16 301 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
Chris@16 302 // non-const version needed to suppress proto's += kicking in
Chris@16 303 template <typename Attr, typename T_>
Chris@16 304 friend adder const&
Chris@16 305 operator+= (symbols& sym, std::pair<Attr, T_>& p)
Chris@16 306 {
Chris@16 307 return sym.add(p.first, p.second);
Chris@16 308 }
Chris@16 309
Chris@16 310 // non-const version needed to suppress proto's -= kicking in
Chris@16 311 template <typename Attr>
Chris@16 312 friend remover const&
Chris@16 313 operator-= (symbols& sym, Attr& attr)
Chris@16 314 {
Chris@16 315 return sym.remove(attr);
Chris@16 316 }
Chris@16 317 #else
Chris@16 318 // for rvalue references
Chris@16 319 template <typename Attr, typename T_>
Chris@16 320 friend adder const&
Chris@16 321 operator+= (symbols& sym, std::pair<Attr, T_>&& p)
Chris@16 322 {
Chris@16 323 return sym.add(p.first, p.second);
Chris@16 324 }
Chris@16 325
Chris@16 326 // for rvalue references
Chris@16 327 template <typename Attr>
Chris@16 328 friend remover const&
Chris@16 329 operator-= (symbols& sym, Attr&& attr)
Chris@16 330 {
Chris@16 331 return sym.remove(attr);
Chris@16 332 }
Chris@16 333 #endif
Chris@16 334 template <typename F>
Chris@16 335 void for_each(F f) const
Chris@16 336 {
Chris@16 337 std::for_each(lookup->begin(), lookup->end(), f);
Chris@16 338 }
Chris@16 339
Chris@16 340 template <typename Attr>
Chris@16 341 value_type* find(Attr const& attr)
Chris@16 342 {
Chris@16 343 typename Lookup::iterator it = lookup->find(attr);
Chris@16 344 return (it != lookup->end()) ? &(*it).second : 0;
Chris@16 345 }
Chris@16 346
Chris@16 347 template <typename Attr>
Chris@16 348 value_type& at(Attr const& attr)
Chris@16 349 {
Chris@16 350 return (*lookup)[attr];
Chris@16 351 }
Chris@16 352
Chris@16 353 ///////////////////////////////////////////////////////////////////////
Chris@16 354 template <typename OutputIterator, typename Context, typename Delimiter
Chris@16 355 , typename Attr>
Chris@16 356 bool generate(OutputIterator& sink, Context&, Delimiter const& d
Chris@16 357 , Attr const& attr) const
Chris@16 358 {
Chris@16 359 typename Lookup::iterator it = lookup->find(
Chris@16 360 traits::symbols_lookup<Attr, Attribute>::call(attr));
Chris@16 361 if (it == lookup->end())
Chris@16 362 return false;
Chris@16 363
Chris@16 364 return karma::detail::generate_encoded<CharEncoding, Tag>::call(
Chris@16 365 sink, (*it).second
Chris@16 366 , traits::symbols_value<Attribute, Attr>::call(attr)) &&
Chris@16 367 karma::delimit_out(sink, d);
Chris@16 368 }
Chris@16 369
Chris@16 370 template <typename Context>
Chris@16 371 info what(Context&) const
Chris@16 372 {
Chris@16 373 return info(name_);
Chris@16 374 }
Chris@16 375
Chris@16 376 void name(std::string const &str)
Chris@16 377 {
Chris@16 378 name_ = str;
Chris@16 379 }
Chris@16 380 std::string const &name() const
Chris@16 381 {
Chris@16 382 return name_;
Chris@16 383 }
Chris@16 384
Chris@16 385 ///////////////////////////////////////////////////////////////////////
Chris@16 386 struct adder
Chris@16 387 {
Chris@16 388 template <typename, typename = unused_type>
Chris@16 389 struct result { typedef adder const& type; };
Chris@16 390
Chris@16 391 adder(symbols& sym)
Chris@16 392 : sym(sym)
Chris@16 393 {
Chris@16 394 }
Chris@16 395
Chris@16 396 template <typename Attr>
Chris@16 397 adder const&
Chris@16 398 operator()(Attr const& attr, T const& val = T()) const
Chris@16 399 {
Chris@16 400 sym.lookup->insert(typename Lookup::value_type(attr, val));
Chris@16 401 return *this;
Chris@16 402 }
Chris@16 403
Chris@16 404 template <typename Attr>
Chris@16 405 adder const&
Chris@16 406 operator, (Attr const& attr) const
Chris@16 407 {
Chris@16 408 sym.lookup->insert(typename Lookup::value_type(attr, T()));
Chris@16 409 return *this;
Chris@16 410 }
Chris@16 411
Chris@16 412 symbols& sym;
Chris@16 413
Chris@16 414 private:
Chris@16 415 // silence MSVC warning C4512: assignment operator could not be generated
Chris@16 416 adder& operator= (adder const&);
Chris@16 417 };
Chris@16 418
Chris@16 419 struct remover
Chris@16 420 {
Chris@16 421 template <typename>
Chris@16 422 struct result { typedef remover const& type; };
Chris@16 423
Chris@16 424 remover(symbols& sym)
Chris@16 425 : sym(sym)
Chris@16 426 {
Chris@16 427 }
Chris@16 428
Chris@16 429 template <typename Attr>
Chris@16 430 remover const&
Chris@16 431 operator()(Attr const& attr) const
Chris@16 432 {
Chris@16 433 sym.lookup->erase(attr);
Chris@16 434 return *this;
Chris@16 435 }
Chris@16 436
Chris@16 437 template <typename Attr>
Chris@16 438 remover const&
Chris@16 439 operator, (Attr const& attr) const
Chris@16 440 {
Chris@16 441 sym.lookup->erase(attr);
Chris@16 442 return *this;
Chris@16 443 }
Chris@16 444
Chris@16 445 symbols& sym;
Chris@16 446
Chris@16 447 private:
Chris@16 448 // silence MSVC warning C4512: assignment operator could not be generated
Chris@16 449 remover& operator= (remover const&);
Chris@16 450 };
Chris@16 451
Chris@16 452 adder add;
Chris@16 453 remover remove;
Chris@16 454 shared_ptr<Lookup> lookup;
Chris@16 455 std::string name_;
Chris@16 456 };
Chris@16 457
Chris@16 458 ///////////////////////////////////////////////////////////////////////////
Chris@16 459 // specialization for unused stored type
Chris@16 460 template <
Chris@16 461 typename Attribute, typename Lookup
Chris@16 462 , typename CharEncoding, typename Tag>
Chris@16 463 struct symbols<Attribute, unused_type, Lookup, CharEncoding, Tag>
Chris@16 464 : proto::extends<
Chris@16 465 typename proto::terminal<
Chris@16 466 spirit::karma::reference<
Chris@16 467 symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> >
Chris@16 468 >::type
Chris@16 469 , symbols<Attribute, unused_type, Lookup, CharEncoding, Tag>
Chris@16 470 >
Chris@16 471 , spirit::karma::generator<
Chris@16 472 symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> >
Chris@16 473 {
Chris@16 474 typedef unused_type value_type; // the value associated with each entry
Chris@16 475
Chris@16 476 typedef spirit::karma::reference<symbols> reference_;
Chris@16 477 typedef typename proto::terminal<reference_>::type terminal;
Chris@16 478 typedef proto::extends<terminal, symbols> base_type;
Chris@16 479
Chris@16 480 template <typename Context, typename Unused>
Chris@16 481 struct attribute
Chris@16 482 {
Chris@16 483 typedef Attribute type;
Chris@16 484 };
Chris@16 485
Chris@16 486 symbols(std::string const& name = "symbols")
Chris@16 487 : base_type(terminal::make(reference_(*this)))
Chris@16 488 , add(*this)
Chris@16 489 , remove(*this)
Chris@16 490 , lookup(new Lookup())
Chris@16 491 , name_(name)
Chris@16 492 {}
Chris@16 493
Chris@16 494 symbols(symbols const& syms)
Chris@16 495 : base_type(terminal::make(reference_(*this)))
Chris@16 496 , add(*this)
Chris@16 497 , remove(*this)
Chris@16 498 , lookup(syms.lookup)
Chris@16 499 , name_(syms.name_)
Chris@16 500 {}
Chris@16 501
Chris@16 502 template <typename CharEncoding_, typename Tag_>
Chris@16 503 symbols(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& syms)
Chris@16 504 : base_type(terminal::make(reference_(*this)))
Chris@16 505 , add(*this)
Chris@16 506 , remove(*this)
Chris@16 507 , lookup(syms.lookup)
Chris@16 508 , name_(syms.name_)
Chris@16 509 {}
Chris@16 510
Chris@16 511 template <typename Symbols, typename Data>
Chris@16 512 symbols(Symbols const& syms, Data const& data
Chris@16 513 , std::string const& name = "symbols")
Chris@16 514 : base_type(terminal::make(reference_(*this)))
Chris@16 515 , add(*this)
Chris@16 516 , remove(*this)
Chris@16 517 , lookup(new Lookup())
Chris@16 518 , name_(name)
Chris@16 519 {
Chris@16 520 typename range_const_iterator<Symbols>::type si = boost::begin(syms);
Chris@16 521 typename range_const_iterator<Data>::type di = boost::begin(data);
Chris@16 522 while (si != boost::end(syms))
Chris@16 523 add(*si++, *di++);
Chris@16 524 }
Chris@16 525
Chris@16 526 symbols&
Chris@16 527 operator=(symbols const& rhs)
Chris@16 528 {
Chris@16 529 *lookup = *rhs.lookup;
Chris@16 530 name_ = rhs.name_;
Chris@16 531 return *this;
Chris@16 532 }
Chris@16 533
Chris@16 534 template <typename CharEncoding_, typename Tag_>
Chris@16 535 symbols&
Chris@16 536 operator=(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& rhs)
Chris@16 537 {
Chris@16 538 *lookup = *rhs.lookup;
Chris@16 539 name_ = rhs.name_;
Chris@16 540 return *this;
Chris@16 541 }
Chris@16 542
Chris@16 543 void clear()
Chris@16 544 {
Chris@16 545 lookup->clear();
Chris@16 546 }
Chris@16 547
Chris@16 548 struct adder;
Chris@16 549 struct remover;
Chris@16 550
Chris@16 551 template <typename Attr>
Chris@16 552 adder const&
Chris@16 553 operator=(Attr const& attr)
Chris@16 554 {
Chris@16 555 lookup->clear();
Chris@16 556 return add(attr);
Chris@16 557 }
Chris@16 558
Chris@16 559 template <typename Attr>
Chris@16 560 friend adder const&
Chris@16 561 operator+= (symbols& sym, Attr const& attr)
Chris@16 562 {
Chris@16 563 return sym.add(attr);
Chris@16 564 }
Chris@16 565
Chris@16 566 template <typename Attr>
Chris@16 567 friend remover const&
Chris@16 568 operator-= (symbols& sym, Attr const& attr)
Chris@16 569 {
Chris@16 570 return sym.remove(attr);
Chris@16 571 }
Chris@16 572
Chris@16 573 // non-const version needed to suppress proto's += kicking in
Chris@16 574 template <typename Attr>
Chris@16 575 friend adder const&
Chris@16 576 operator+= (symbols& sym, Attr& attr)
Chris@16 577 {
Chris@16 578 return sym.add(attr);
Chris@16 579 }
Chris@16 580
Chris@16 581 // non-const version needed to suppress proto's -= kicking in
Chris@16 582 template <typename Attr>
Chris@16 583 friend remover const&
Chris@16 584 operator-= (symbols& sym, Attr& attr)
Chris@16 585 {
Chris@16 586 return sym.remove(attr);
Chris@16 587 }
Chris@16 588
Chris@16 589 template <typename F>
Chris@16 590 void for_each(F f) const
Chris@16 591 {
Chris@16 592 std::for_each(lookup->begin(), lookup->end(), f);
Chris@16 593 }
Chris@16 594
Chris@16 595 template <typename Attr>
Chris@16 596 value_type const* find(Attr const& attr)
Chris@16 597 {
Chris@16 598 typename Lookup::iterator it = lookup->find(attr);
Chris@16 599 return (it != lookup->end()) ? &unused : 0;
Chris@16 600 }
Chris@16 601
Chris@16 602 template <typename Attr>
Chris@16 603 value_type at(Attr const& attr)
Chris@16 604 {
Chris@16 605 typename Lookup::iterator it = lookup->find(attr);
Chris@16 606 if (it == lookup->end())
Chris@16 607 add(attr);
Chris@16 608 return unused;
Chris@16 609 }
Chris@16 610
Chris@16 611 ///////////////////////////////////////////////////////////////////////
Chris@16 612 template <typename OutputIterator, typename Context, typename Delimiter
Chris@16 613 , typename Attr>
Chris@16 614 bool generate(OutputIterator& sink, Context&, Delimiter const& d
Chris@16 615 , Attr const& attr) const
Chris@16 616 {
Chris@16 617 typename Lookup::iterator it = lookup->find(
Chris@16 618 traits::symbols_lookup<Attr, Attribute>::call(attr));
Chris@16 619 if (it == lookup->end())
Chris@16 620 return false;
Chris@16 621
Chris@16 622 return karma::detail::generate_encoded<CharEncoding, Tag>::
Chris@16 623 call(sink
Chris@16 624 , traits::symbols_lookup<Attr, Attribute>::call(attr)
Chris@16 625 , unused) &&
Chris@16 626 karma::delimit_out(sink, d);
Chris@16 627 }
Chris@16 628
Chris@16 629 template <typename Context>
Chris@16 630 info what(Context&) const
Chris@16 631 {
Chris@16 632 return info(name_);
Chris@16 633 }
Chris@16 634
Chris@16 635 void name(std::string const &str)
Chris@16 636 {
Chris@16 637 name_ = str;
Chris@16 638 }
Chris@16 639 std::string const &name() const
Chris@16 640 {
Chris@16 641 return name_;
Chris@16 642 }
Chris@16 643
Chris@16 644 ///////////////////////////////////////////////////////////////////////
Chris@16 645 struct adder
Chris@16 646 {
Chris@16 647 template <typename, typename = unused_type>
Chris@16 648 struct result { typedef adder const& type; };
Chris@16 649
Chris@16 650 adder(symbols& sym)
Chris@16 651 : sym(sym)
Chris@16 652 {
Chris@16 653 }
Chris@16 654
Chris@16 655 template <typename Attr>
Chris@16 656 adder const&
Chris@16 657 operator()(Attr const& attr) const
Chris@16 658 {
Chris@16 659 sym.lookup->insert(attr);
Chris@16 660 return *this;
Chris@16 661 }
Chris@16 662
Chris@16 663 template <typename Attr>
Chris@16 664 adder const&
Chris@16 665 operator, (Attr const& attr) const
Chris@16 666 {
Chris@16 667 sym.lookup->insert(attr);
Chris@16 668 return *this;
Chris@16 669 }
Chris@16 670
Chris@16 671 symbols& sym;
Chris@16 672
Chris@16 673 private:
Chris@16 674 // silence MSVC warning C4512: assignment operator could not be generated
Chris@16 675 adder& operator= (adder const&);
Chris@16 676 };
Chris@16 677
Chris@16 678 struct remover
Chris@16 679 {
Chris@16 680 template <typename>
Chris@16 681 struct result { typedef remover const& type; };
Chris@16 682
Chris@16 683 remover(symbols& sym)
Chris@16 684 : sym(sym)
Chris@16 685 {
Chris@16 686 }
Chris@16 687
Chris@16 688 template <typename Attr>
Chris@16 689 remover const&
Chris@16 690 operator()(Attr const& attr) const
Chris@16 691 {
Chris@16 692 sym.lookup->erase(attr);
Chris@16 693 return *this;
Chris@16 694 }
Chris@16 695
Chris@16 696 template <typename Attr>
Chris@16 697 remover const&
Chris@16 698 operator, (Attr const& attr) const
Chris@16 699 {
Chris@16 700 sym.lookup->erase(attr);
Chris@16 701 return *this;
Chris@16 702 }
Chris@16 703
Chris@16 704 symbols& sym;
Chris@16 705
Chris@16 706 private:
Chris@16 707 // silence MSVC warning C4512: assignment operator could not be generated
Chris@16 708 remover& operator= (remover const&);
Chris@16 709 };
Chris@16 710
Chris@16 711 adder add;
Chris@16 712 remover remove;
Chris@16 713 shared_ptr<Lookup> lookup;
Chris@16 714 std::string name_;
Chris@16 715 };
Chris@16 716
Chris@16 717 ///////////////////////////////////////////////////////////////////////////
Chris@16 718 // Generator generators: make_xxx function (objects)
Chris@16 719 ///////////////////////////////////////////////////////////////////////////
Chris@16 720 template <typename Attribute, typename T, typename Lookup
Chris@16 721 , typename CharEnconding, typename Tag, typename Modifiers>
Chris@16 722 struct make_primitive<
Chris@16 723 reference<symbols<Attribute, T, Lookup, CharEnconding, Tag> >
Chris@16 724 , Modifiers>
Chris@16 725 {
Chris@16 726 static bool const lower =
Chris@16 727 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
Chris@16 728 static bool const upper =
Chris@16 729 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
Chris@16 730
Chris@16 731 typedef reference<
Chris@16 732 symbols<Attribute, T, Lookup, CharEnconding, Tag>
Chris@16 733 > reference_;
Chris@16 734
Chris@16 735 typedef typename mpl::if_c<
Chris@16 736 lower || upper
Chris@16 737 , symbols<
Chris@16 738 Attribute, T, Lookup
Chris@16 739 , typename spirit::detail::get_encoding_with_case<
Chris@16 740 Modifiers, unused_type, lower || upper>::type
Chris@16 741 , typename detail::get_casetag<Modifiers, lower || upper>::type>
Chris@16 742 , reference_>::type
Chris@16 743 result_type;
Chris@16 744
Chris@16 745 result_type operator()(reference_ ref, unused_type) const
Chris@16 746 {
Chris@16 747 return result_type(ref.ref.get());
Chris@16 748 }
Chris@16 749 };
Chris@16 750 }}}
Chris@16 751
Chris@16 752 namespace boost { namespace spirit { namespace traits
Chris@16 753 {
Chris@16 754 ///////////////////////////////////////////////////////////////////////////
Chris@16 755 template <typename Attribute, typename T, typename Lookup
Chris@16 756 , typename CharEncoding, typename Tag
Chris@16 757 , typename Attr, typename Context, typename Iterator>
Chris@16 758 struct handles_container<karma::symbols<Attribute, T, Lookup, CharEncoding, Tag>
Chris@16 759 , Attr, Context, Iterator>
Chris@16 760 : traits::is_container<Attr> {};
Chris@16 761 }}}
Chris@16 762
Chris@16 763 #if defined(BOOST_MSVC)
Chris@16 764 # pragma warning(pop)
Chris@16 765 #endif
Chris@16 766
Chris@16 767 #endif
Chris@16 768