utree.hpp 22 KB

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