annotate DEPENDENCIES/generic/include/boost/spirit/home/support/utree/utree.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 /*=============================================================================
Chris@16 2 Copyright (c) 2001-2011 Joel de Guzman
Chris@16 3 Copyright (c) 2001-2011 Hartmut Kaiser
Chris@16 4 Copyright (c) 2010-2011 Bryce Lelbach
Chris@16 5
Chris@16 6 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 =============================================================================*/
Chris@16 9 #if !defined(BOOST_SPIRIT_UTREE)
Chris@16 10 #define BOOST_SPIRIT_UTREE
Chris@16 11
Chris@16 12 #include <cstddef>
Chris@16 13 #include <algorithm>
Chris@16 14 #include <string>
Chris@16 15 #include <iostream>
Chris@16 16 #include <ios>
Chris@16 17 #include <sstream>
Chris@16 18 #include <typeinfo>
Chris@16 19
Chris@16 20 #include <boost/io/ios_state.hpp>
Chris@16 21 #include <boost/integer.hpp>
Chris@16 22 #include <boost/throw_exception.hpp>
Chris@16 23 #include <boost/assert.hpp>
Chris@16 24 #include <boost/noncopyable.hpp>
Chris@16 25 #include <boost/iterator/iterator_facade.hpp>
Chris@16 26 #include <boost/range/iterator_range.hpp>
Chris@16 27 #include <boost/type_traits/remove_pointer.hpp>
Chris@16 28 #include <boost/type_traits/is_polymorphic.hpp>
Chris@16 29 #include <boost/utility/enable_if.hpp>
Chris@16 30 #include <boost/utility/result_of.hpp>
Chris@16 31 #include <boost/ref.hpp>
Chris@16 32
Chris@16 33 #include <boost/spirit/home/support/utree/detail/utree_detail1.hpp>
Chris@16 34
Chris@16 35 #if defined(BOOST_MSVC)
Chris@16 36 # pragma warning(push)
Chris@16 37 # pragma warning(disable: 4804)
Chris@16 38 # pragma warning(disable: 4805)
Chris@16 39 # pragma warning(disable: 4244)
Chris@16 40 #endif
Chris@16 41
Chris@16 42 namespace boost { namespace spirit
Chris@16 43 {
Chris@16 44 //[utree_exceptions
Chris@16 45 /*` All exceptions thrown by utree are derived from utree_exception. */
Chris@16 46 struct utree_exception : std::exception {};
Chris@16 47
Chris@16 48 /*`The `bad_type_exception` is thrown whenever somebody calls a member
Chris@16 49 function, which applies to certain stored utree_type's only, but this
Chris@16 50 precondition is violated as the `utree` instance holds some other type.
Chris@16 51 */
Chris@16 52 struct bad_type_exception /*: utree_exception*/;
Chris@16 53
Chris@16 54 /*`The `empty_exception` is thrown whenever a precondition of a list
Chris@16 55 or range utree method is violated due to the list or range being empty.
Chris@16 56 */
Chris@16 57 struct empty_exception /*: utree_exception*/;
Chris@16 58 //]
Chris@16 59
Chris@16 60 //[utree_types
Chris@16 61 /*`Each instance of an `utree` data structure can store exactly one of the
Chris@16 62 following data types at a time:
Chris@16 63 */
Chris@16 64 struct utree_type
Chris@16 65 {
Chris@16 66 enum info
Chris@16 67 {
Chris@16 68 invalid_type, // the utree has not been initialized (it's
Chris@16 69 // default constructed)
Chris@16 70 nil_type, // nil is the sentinel (empty) utree type.
Chris@16 71 list_type, // A doubly linked list of utrees.
Chris@16 72 range_type, // A range of list::iterators.
Chris@16 73 reference_type, // A reference to another utree.
Chris@16 74 any_type, // A pointer or reference to any C++ type.
Chris@16 75 function_type, // A utree holding a stored_function<F> object,
Chris@16 76 // where F is an unary function object taking a
Chris@16 77 // utree as it's parameter and returning a
Chris@16 78 // utree.
Chris@16 79
Chris@16 80 // numeric atoms
Chris@16 81 bool_type, // An utree holding a boolean value
Chris@16 82 int_type, // An utree holding a integer (int) value
Chris@16 83 double_type, // An utree holding a floating point (double) value
Chris@16 84
Chris@16 85 // text atoms (utf8)
Chris@16 86 string_type, // An UTF-8 string
Chris@16 87 string_range_type, // A pair of iterators into an UTF-8 string
Chris@16 88 symbol_type, // An UTF-8 symbol name
Chris@16 89
Chris@16 90 binary_type // Arbitrary binary data
Chris@16 91 };
Chris@16 92 typedef boost::uint_t<sizeof(info)*8>::exact exact_integral_type;
Chris@16 93 typedef boost::uint_t<sizeof(info)*8>::fast fast_integral_type;
Chris@16 94 };
Chris@16 95 //]
Chris@16 96
Chris@16 97 // streaming operator for utree types - essential for diagnostics
Chris@16 98 inline std::ostream& operator<<(std::ostream& out, utree_type::info t)
Chris@16 99 {
Chris@16 100 boost::io::ios_all_saver saver(out);
Chris@16 101 switch (t) {
Chris@16 102 case utree_type::invalid_type: { out << "invalid"; break; }
Chris@16 103 case utree_type::nil_type: { out << "nil"; break; }
Chris@16 104 case utree_type::list_type: { out << "list"; break; }
Chris@16 105 case utree_type::range_type: { out << "range"; break; }
Chris@16 106 case utree_type::reference_type: { out << "reference"; break; }
Chris@16 107 case utree_type::any_type: { out << "any"; break; }
Chris@16 108 case utree_type::function_type: { out << "function"; break; }
Chris@16 109 case utree_type::bool_type: { out << "bool"; break; }
Chris@16 110 case utree_type::int_type: { out << "int"; break; }
Chris@16 111 case utree_type::double_type: { out << "double"; break; }
Chris@16 112 case utree_type::string_type: { out << "string"; break; }
Chris@16 113 case utree_type::string_range_type: { out << "string_range"; break; }
Chris@16 114 case utree_type::symbol_type: { out << "symbol"; break; }
Chris@16 115 case utree_type::binary_type: { out << "binary"; break; }
Chris@16 116 default: { out << "unknown"; break; }
Chris@16 117 }
Chris@16 118 out << std::hex << "[0x"
Chris@16 119 << static_cast<utree_type::fast_integral_type>(t) << "]";
Chris@16 120 return out;
Chris@16 121 }
Chris@16 122
Chris@16 123 struct bad_type_exception : utree_exception
Chris@16 124 {
Chris@16 125 std::string msg;
Chris@16 126
Chris@16 127 bad_type_exception(char const* error, utree_type::info got)
Chris@16 128 : msg()
Chris@16 129 {
Chris@16 130 std::ostringstream oss;
Chris@16 131 oss << "utree: " << error
Chris@16 132 << " (got utree type '" << got << "')";
Chris@16 133 msg = oss.str();
Chris@16 134 }
Chris@16 135
Chris@16 136 bad_type_exception(char const* error, utree_type::info got1,
Chris@16 137 utree_type::info got2)
Chris@16 138 : msg()
Chris@16 139 {
Chris@16 140 std::ostringstream oss;
Chris@16 141 oss << "utree: " << error
Chris@16 142 << " (got utree types '" << got1 << "' and '" << got2 << "')";
Chris@16 143 msg = oss.str();
Chris@16 144 }
Chris@16 145
Chris@16 146 virtual ~bad_type_exception() throw() {}
Chris@16 147
Chris@16 148 virtual char const* what() const throw()
Chris@16 149 { return msg.c_str(); }
Chris@16 150 };
Chris@16 151
Chris@16 152 struct empty_exception : utree_exception
Chris@16 153 {
Chris@16 154 char const* msg;
Chris@16 155
Chris@16 156 empty_exception(char const* error) : msg(error) {}
Chris@16 157
Chris@16 158 virtual ~empty_exception() throw() {}
Chris@16 159
Chris@16 160 virtual char const* what() const throw()
Chris@16 161 { return msg; }
Chris@16 162 };
Chris@16 163
Chris@16 164 ///////////////////////////////////////////////////////////////////////////
Chris@16 165 // A typed string with parametric Base storage. The storage can be any
Chris@16 166 // range or (stl container) of chars.
Chris@16 167 ///////////////////////////////////////////////////////////////////////////
Chris@16 168 template <typename Base, utree_type::info type_>
Chris@16 169 struct basic_string : Base
Chris@16 170 {
Chris@16 171 static utree_type::info const type = type_;
Chris@16 172
Chris@16 173 basic_string()
Chris@16 174 : Base() {}
Chris@16 175
Chris@16 176 basic_string(Base const& base)
Chris@16 177 : Base(base) {}
Chris@16 178
Chris@16 179 template <typename Iterator>
Chris@16 180 basic_string(Iterator bits, std::size_t len)
Chris@16 181 : Base(bits, bits + len) {}
Chris@16 182
Chris@16 183 template <typename Iterator>
Chris@16 184 basic_string(Iterator first, Iterator last)
Chris@16 185 : Base(first, last) {}
Chris@16 186
Chris@16 187 basic_string& operator=(basic_string const& other)
Chris@16 188 {
Chris@16 189 Base::operator=(other);
Chris@16 190 return *this;
Chris@16 191 }
Chris@16 192
Chris@16 193 basic_string& operator=(Base const& other)
Chris@16 194 {
Chris@16 195 Base::operator=(other);
Chris@16 196 return *this;
Chris@16 197 }
Chris@16 198 };
Chris@16 199
Chris@16 200 //[utree_strings
Chris@16 201 /*`The `utree` string types described below are used by the `utree` API
Chris@16 202 only. These are not used to store information in the `utree` itself.
Chris@16 203 Their purpose is to refer to different internal `utree` node types
Chris@16 204 only. For instance, creating a `utree` from a binary data type will
Chris@16 205 create a `binary_type` utree node (see above).
Chris@16 206 */
Chris@16 207 /*`The binary data type can be represented either verbatim as a sequence
Chris@16 208 of bytes or as a pair of iterators into some other stored binary data
Chris@16 209 sequence. Use this string type to access/create a `binary_type` `utree`.
Chris@16 210 */
Chris@16 211 typedef basic_string<
Chris@16 212 boost::iterator_range<char const*>, utree_type::binary_type
Chris@16 213 > binary_range_type;
Chris@16 214 typedef basic_string<
Chris@16 215 std::string, utree_type::binary_type
Chris@16 216 > binary_string_type;
Chris@16 217
Chris@16 218 /*`The UTF-8 string can be represented either verbatim as a sequence of
Chris@16 219 characters or as a pair of iterators into some other stored binary data
Chris@16 220 sequence. Use this string type to access/create a `string_type` `utree`.
Chris@16 221 */
Chris@16 222 typedef basic_string<
Chris@16 223 boost::iterator_range<char const*>, utree_type::string_type
Chris@16 224 > utf8_string_range_type;
Chris@16 225 typedef basic_string<
Chris@16 226 std::string, utree_type::string_type
Chris@16 227 > utf8_string_type;
Chris@16 228
Chris@16 229 /*`The UTF-8 symbol can be represented either verbatim as a sequence of
Chris@16 230 characters or as a pair of iterators into some other stored binary data
Chris@16 231 sequence. Use this string type to access/create a `symbol_type` `utree`.
Chris@16 232 */
Chris@16 233 typedef basic_string<
Chris@16 234 boost::iterator_range<char const*>, utree_type::symbol_type
Chris@16 235 > utf8_symbol_range_type;
Chris@16 236 typedef basic_string<
Chris@16 237 std::string, utree_type::symbol_type
Chris@16 238 > utf8_symbol_type;
Chris@16 239 //]
Chris@16 240
Chris@16 241 ///////////////////////////////////////////////////////////////////////////
Chris@16 242 // Our function type
Chris@16 243 ///////////////////////////////////////////////////////////////////////////
Chris@16 244 class utree;
Chris@16 245
Chris@16 246 //[utree_function_object_interface
Chris@16 247 struct function_base
Chris@16 248 {
Chris@16 249 virtual ~function_base() {}
Chris@16 250 virtual utree operator()(utree const& env) const = 0;
Chris@16 251 virtual utree operator()(utree& env) const = 0;
Chris@16 252
Chris@16 253 // Calling f.clone() must return a newly allocated function_base
Chris@16 254 // instance that is equal to f.
Chris@16 255 virtual function_base* clone() const = 0;
Chris@16 256 };
Chris@16 257
Chris@16 258 template <typename F>
Chris@16 259 struct stored_function : function_base
Chris@16 260 {
Chris@16 261 F f;
Chris@16 262 stored_function(F f = F());
Chris@16 263 virtual ~stored_function();
Chris@16 264 virtual utree operator()(utree const& env) const;
Chris@16 265 virtual utree operator()(utree& env) const;
Chris@16 266 virtual function_base* clone() const;
Chris@16 267 };
Chris@16 268
Chris@16 269 template <typename F>
Chris@16 270 struct referenced_function : function_base
Chris@16 271 {
Chris@16 272 F& f;
Chris@16 273 referenced_function(F& f);
Chris@16 274 virtual ~referenced_function();
Chris@16 275 virtual utree operator()(utree const& env) const;
Chris@16 276 virtual utree operator()(utree& env) const;
Chris@16 277 virtual function_base* clone() const;
Chris@16 278 };
Chris@16 279 //]
Chris@16 280
Chris@16 281 ///////////////////////////////////////////////////////////////////////////
Chris@16 282 // Shallow tag. Instructs utree to hold an iterator_range
Chris@16 283 // as-is without deep copying the range.
Chris@16 284 ///////////////////////////////////////////////////////////////////////////
Chris@16 285 struct shallow_tag {};
Chris@16 286 shallow_tag const shallow = {};
Chris@16 287
Chris@16 288 ///////////////////////////////////////////////////////////////////////////
Chris@16 289 // A void* plus type_info
Chris@16 290 ///////////////////////////////////////////////////////////////////////////
Chris@16 291 class any_ptr
Chris@16 292 {
Chris@16 293 public:
Chris@16 294 template <typename Ptr>
Chris@16 295 typename boost::disable_if<
Chris@16 296 boost::is_polymorphic<
Chris@16 297 typename boost::remove_pointer<Ptr>::type>,
Chris@16 298 Ptr>::type
Chris@16 299 get() const
Chris@16 300 {
Chris@16 301 if (*i == typeid(Ptr))
Chris@16 302 {
Chris@16 303 return static_cast<Ptr>(p);
Chris@16 304 }
Chris@16 305 boost::throw_exception(std::bad_cast());
Chris@16 306 }
Chris@16 307
Chris@16 308 template <typename T>
Chris@16 309 any_ptr(T* p)
Chris@16 310 : p(p), i(&typeid(T*))
Chris@16 311 {}
Chris@16 312
Chris@16 313 friend bool operator==(any_ptr const& a, any_ptr const& b)
Chris@16 314 {
Chris@16 315 return (a.p == b.p) && (*a.i == *b.i);
Chris@16 316 }
Chris@16 317
Chris@16 318 private:
Chris@16 319 // constructor is private
Chris@16 320 any_ptr(void* p, std::type_info const* i)
Chris@16 321 : p(p), i(i) {}
Chris@16 322
Chris@16 323 template <typename UTreeX, typename UTreeY>
Chris@16 324 friend struct detail::visit_impl;
Chris@16 325
Chris@16 326 friend class utree;
Chris@16 327
Chris@16 328 void* p;
Chris@16 329 std::type_info const* i;
Chris@16 330 };
Chris@16 331
Chris@16 332 //[utree
Chris@16 333 class utree {
Chris@16 334 public:
Chris@16 335 ///////////////////////////////////////////////////////////////////////
Chris@16 336 // The invalid type
Chris@16 337 struct invalid_type {};
Chris@16 338
Chris@16 339 ///////////////////////////////////////////////////////////////////////
Chris@16 340 // The nil type
Chris@16 341 struct nil_type {};
Chris@16 342
Chris@16 343 ///////////////////////////////////////////////////////////////////////
Chris@16 344 // The list type, this can be used to initialize an utree to hold an
Chris@16 345 // empty list
Chris@16 346 struct list_type;
Chris@16 347
Chris@16 348 //[utree_container_types
Chris@16 349 typedef utree value_type;
Chris@16 350 typedef utree& reference;
Chris@16 351 typedef utree const& const_reference;
Chris@16 352 typedef std::ptrdiff_t difference_type;
Chris@16 353 typedef std::size_t size_type;
Chris@16 354
Chris@16 355 typedef detail::list::node_iterator<utree> iterator;
Chris@16 356 typedef detail::list::node_iterator<utree const> const_iterator;
Chris@16 357 //]
Chris@16 358
Chris@16 359 typedef detail::list::node_iterator<boost::reference_wrapper<utree> >
Chris@16 360 ref_iterator;
Chris@16 361
Chris@16 362 typedef boost::iterator_range<iterator> range;
Chris@16 363 typedef boost::iterator_range<const_iterator> const_range;
Chris@16 364
Chris@16 365 // dtor
Chris@16 366 ~utree();
Chris@16 367
Chris@16 368 ////////////////////////////////////////////////////////////////////////
Chris@16 369 //[utree_initialization
Chris@16 370 /*`A `utree` can be constructed or initialized from a wide range of
Chris@16 371 data types, allowing to create `utree` instances for every
Chris@16 372 possible node type (see the description of `utree_type::info` above).
Chris@16 373 For this reason it exposes a constructor and an assignment operator
Chris@16 374 for each of the allowed node types as shown below. All constructors
Chris@16 375 are non-explicit on purpose, allowing to use an utree instance as
Chris@16 376 the attribute to almost any Qi parser.
Chris@16 377 */
Chris@16 378 // This constructs an `invalid_type` node. When used in places
Chris@16 379 // where a boost::optional is expected (i.e. as an attribute for the
Chris@16 380 // optional component), this represents the 'empty' state.
Chris@16 381 utree(invalid_type = invalid_type());
Chris@16 382
Chris@16 383 // This initializes a `nil_type` node, which represents a valid,
Chris@16 384 // 'initialized empty' utree (different from invalid_type!).
Chris@16 385 utree(nil_type);
Chris@16 386 reference operator=(nil_type);
Chris@16 387
Chris@16 388 // This initializes a `boolean_type` node, which can hold 'true' or
Chris@16 389 // 'false' only.
Chris@16 390 explicit utree(bool);
Chris@16 391 reference operator=(bool);
Chris@16 392
Chris@16 393 // This initializes an `integer_type` node, which can hold arbitrary
Chris@16 394 // integers. For convenience these functions are overloaded for signed
Chris@16 395 // and unsigned integer types.
Chris@16 396 utree(unsigned int);
Chris@16 397 utree(int);
Chris@16 398 reference operator=(unsigned int);
Chris@16 399 reference operator=(int);
Chris@16 400
Chris@16 401 // This initializes a `double_type` node, which can hold arbitrary
Chris@16 402 // floating point (double) values.
Chris@16 403 utree(double);
Chris@16 404 reference operator=(double);
Chris@16 405
Chris@16 406 // This initializes a `string_type` node, which can hold a narrow
Chris@16 407 // character sequence (usually an UTF-8 string).
Chris@16 408 utree(char);
Chris@16 409 utree(char const*);
Chris@16 410 utree(char const*, std::size_t);
Chris@16 411 utree(std::string const&);
Chris@16 412 reference operator=(char);
Chris@16 413 reference operator=(char const*);
Chris@16 414 reference operator=(std::string const&);
Chris@16 415
Chris@16 416 // This constructs a `string_range_type` node, which does not copy the
Chris@16 417 // data but stores the iterator range to the character sequence the
Chris@16 418 // range has been initialized from.
Chris@16 419 utree(utf8_string_range_type const&, shallow_tag);
Chris@16 420
Chris@16 421 // This initializes a `reference_type` node, which holds a reference to
Chris@16 422 // another utree node. All operations on such a node are automatically
Chris@16 423 // forwarded to the referenced utree instance.
Chris@16 424 utree(boost::reference_wrapper<utree>);
Chris@16 425 reference operator=(boost::reference_wrapper<utree>);
Chris@16 426
Chris@16 427 // This initializes an `any_type` node, which can hold a pointer to an
Chris@16 428 // instance of any type together with the typeid of that type. When
Chris@16 429 // accessing that pointer the typeid will be checked, causing a
Chris@16 430 // std::bad_cast to be thrown if the typeids do not match.
Chris@16 431 utree(any_ptr const&);
Chris@16 432 reference operator=(any_ptr const&);
Chris@16 433
Chris@16 434 // This initializes a `range_type` node, which holds an utree list node
Chris@16 435 // the elements of which are copy constructed (assigned) from the
Chris@16 436 // elements referenced by the given range of iterators.
Chris@16 437 template <class Iterator>
Chris@16 438 utree(boost::iterator_range<Iterator>);
Chris@16 439 template <class Iterator>
Chris@16 440 reference operator=(boost::iterator_range<Iterator>);
Chris@16 441
Chris@16 442 // This initializes a `function_type` node from a polymorphic function
Chris@16 443 // object pointer (takes ownership) or reference.
Chris@16 444 utree(function_base const&);
Chris@16 445 reference operator=(function_base const&);
Chris@16 446 utree(function_base*);
Chris@16 447 reference operator=(function_base*);
Chris@16 448
Chris@16 449 // This initializes either a `string_type`, a `symbol_type`, or a
Chris@16 450 // `binary_type` node (depending on the template parameter `type_`),
Chris@16 451 // which will hold the corresponding narrow character sequence (usually
Chris@16 452 // an UTF-8 string).
Chris@16 453 template <class Base, utree_type::info type_>
Chris@16 454 utree(basic_string<Base, type_> const&);
Chris@16 455 template <class Base, utree_type::info type_>
Chris@16 456 reference operator=(basic_string<Base, type_> const&);
Chris@16 457 //]
Chris@16 458
Chris@16 459 // copy
Chris@16 460 utree(const_reference);
Chris@16 461 reference operator=(const_reference);
Chris@16 462
Chris@16 463 // range
Chris@16 464 utree(range, shallow_tag);
Chris@16 465 utree(const_range, shallow_tag);
Chris@16 466
Chris@16 467 // assign dispatch
Chris@16 468 template <class Iterator>
Chris@16 469 void assign(Iterator, Iterator);
Chris@16 470
Chris@16 471 ////////////////////////////////////////////////////////////////////////
Chris@16 472
Chris@16 473 ////////////////////////////////////////////////////////////////////////
Chris@16 474 // function object visitation interface
Chris@16 475
Chris@16 476 // single dispatch
Chris@16 477 template <class F>
Chris@16 478 typename boost::result_of<F(utree const&)>::type
Chris@16 479 static visit(utree const&, F);
Chris@16 480
Chris@16 481 template <class F>
Chris@16 482 typename boost::result_of<F(utree&)>::type
Chris@16 483 static visit(utree&, F);
Chris@16 484
Chris@16 485 // double dispatch
Chris@16 486 template <class F>
Chris@16 487 typename boost::result_of<F(utree const&, utree const&)>::type
Chris@16 488 static visit(utree const&, utree const&, F);
Chris@16 489
Chris@16 490 template <class F>
Chris@16 491 typename boost::result_of<F(utree&, utree const&)>::type
Chris@16 492 static visit(utree&, utree const&, F);
Chris@16 493
Chris@16 494 template <class F>
Chris@16 495 typename boost::result_of<F(utree const&, utree&)>::type
Chris@16 496 static visit(utree const&, utree&, F);
Chris@16 497
Chris@16 498 template <class F>
Chris@16 499 typename boost::result_of<F(utree&, utree&)>::type
Chris@16 500 static visit(utree&, utree&, F);
Chris@16 501
Chris@16 502 ////////////////////////////////////////////////////////////////////////
Chris@16 503
Chris@16 504 ///////////////////////////////////////////////////////////////////////
Chris@16 505 //[utree_container_functions
Chris@16 506 // STL Container interface
Chris@16 507
Chris@16 508 // insertion
Chris@16 509 template <class T>
Chris@16 510 void push_back(T const&);
Chris@16 511 template <class T>
Chris@16 512 void push_front(T const&);
Chris@16 513 template <class T>
Chris@16 514 iterator insert(iterator, T const&);
Chris@16 515 template <class T>
Chris@16 516 void insert(iterator, std::size_t, T const&);
Chris@16 517 template <class Iterator>
Chris@16 518 void insert(iterator, Iterator, Iterator);
Chris@16 519
Chris@16 520 // erasure
Chris@16 521 void pop_front();
Chris@16 522 void pop_back();
Chris@16 523 iterator erase(iterator);
Chris@16 524 iterator erase(iterator, iterator);
Chris@16 525
Chris@16 526 // front access
Chris@16 527 reference front();
Chris@16 528 const_reference front() const;
Chris@16 529 iterator begin();
Chris@16 530 const_iterator begin() const;
Chris@16 531 ref_iterator ref_begin();
Chris@16 532
Chris@16 533 // back access
Chris@16 534 reference back();
Chris@16 535 const_reference back() const;
Chris@16 536 iterator end();
Chris@16 537 const_iterator end() const;
Chris@16 538 ref_iterator ref_end();
Chris@16 539 //]
Chris@16 540
Chris@16 541 // This clears the utree instance and resets its type to `invalid_type`
Chris@16 542 void clear();
Chris@16 543
Chris@16 544 void swap(utree&);
Chris@16 545
Chris@16 546 bool empty() const;
Chris@16 547
Chris@16 548 size_type size() const;
Chris@16 549 /*`[warning `size()` has O(n) complexity on `utree` ranges. On utree
Chris@16 550 lists, it has O(1) complexity.]`*/
Chris@16 551
Chris@16 552 ////////////////////////////////////////////////////////////////////////
Chris@16 553
Chris@16 554 //[utree_variant_functions
Chris@16 555 // return the data type (`utree_type::info`) of the currently stored
Chris@16 556 // data item
Chris@16 557 utree_type::info which() const;
Chris@16 558
Chris@16 559 // access the currently stored data in a type safe manner, this will
Chris@16 560 // throw a `std::bad_cast()` if the currently stored data item is not
Chris@16 561 // default convertible to `T`.
Chris@16 562 template <class T>
Chris@16 563 T get() const;
Chris@16 564 //]
Chris@16 565
Chris@16 566 reference deref();
Chris@16 567 const_reference deref() const;
Chris@16 568
Chris@16 569 short tag() const;
Chris@16 570 void tag(short);
Chris@16 571
Chris@16 572 utree eval(utree const&) const;
Chris@16 573 utree eval(utree&) const;
Chris@16 574
Chris@16 575 utree operator() (utree const&) const;
Chris@16 576 utree operator() (utree&) const;
Chris@16 577 //<-
Chris@16 578 protected:
Chris@16 579 void ensure_list_type(char const* failed_in = "ensure_list_type()");
Chris@16 580
Chris@16 581 private:
Chris@16 582 typedef utree_type type;
Chris@16 583
Chris@16 584 template <class UTreeX, class UTreeY>
Chris@16 585 friend struct detail::visit_impl;
Chris@16 586 friend struct detail::index_impl;
Chris@16 587
Chris@16 588 type::info get_type() const;
Chris@16 589 void set_type(type::info);
Chris@16 590 void free();
Chris@16 591 void copy(const_reference);
Chris@16 592
Chris@16 593 union {
Chris@16 594 detail::fast_string s;
Chris@16 595 detail::list l;
Chris@16 596 detail::range r;
Chris@16 597 detail::string_range sr;
Chris@16 598 detail::void_ptr v;
Chris@16 599 bool b;
Chris@16 600 int i;
Chris@16 601 double d;
Chris@16 602 utree* p;
Chris@16 603 function_base* pf;
Chris@16 604 };
Chris@16 605 //->
Chris@16 606 };
Chris@16 607 //]
Chris@16 608
Chris@16 609 //[utree_tuple_interface
Chris@16 610 /*<-*/inline/*->*/
Chris@16 611 utree::reference get(utree::reference, utree::size_type);
Chris@16 612 /*<-*/inline/*->*/
Chris@16 613 utree::const_reference get(utree::const_reference, utree::size_type);
Chris@16 614 /*`[warning `get()` has O(n) complexity.]`*/
Chris@16 615 //]
Chris@16 616
Chris@16 617 struct utree::list_type : utree
Chris@16 618 {
Chris@16 619 using utree::operator=;
Chris@16 620
Chris@16 621 list_type() : utree() { ensure_list_type("list_type()"); }
Chris@16 622
Chris@16 623 template <typename T0>
Chris@16 624 list_type(T0 t0) : utree(t0) {}
Chris@16 625
Chris@16 626 template <typename T0, typename T1>
Chris@16 627 list_type(T0 t0, T1 t1) : utree(t0, t1) {}
Chris@16 628 };
Chris@16 629
Chris@16 630 ///////////////////////////////////////////////////////////////////////////
Chris@16 631 // predefined instances for singular types
Chris@16 632 utree::invalid_type const invalid = {};
Chris@16 633 utree::nil_type const nil = {};
Chris@16 634 utree::list_type const empty_list = utree::list_type();
Chris@16 635 }}
Chris@16 636
Chris@16 637 #if defined(BOOST_MSVC)
Chris@16 638 #pragma warning(pop)
Chris@16 639 #endif
Chris@16 640
Chris@16 641 #endif
Chris@16 642