utree.hpp 22 KB

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