utree.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  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 <ios>
  14. #include <sstream>
  15. #include <typeinfo>
  16. #include <boost/io/ios_state.hpp>
  17. #include <boost/integer.hpp>
  18. #include <boost/throw_exception.hpp>
  19. #include <boost/assert.hpp>
  20. #include <boost/noncopyable.hpp>
  21. #include <boost/iterator/iterator_facade.hpp>
  22. #include <boost/range/iterator_range_core.hpp>
  23. #include <boost/type_traits/remove_pointer.hpp>
  24. #include <boost/type_traits/is_polymorphic.hpp>
  25. #include <boost/utility/enable_if.hpp>
  26. #include <boost/utility/result_of.hpp>
  27. #include <boost/ref.hpp>
  28. #include <boost/config.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 BOOST_SYMBOL_VISIBLE 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() BOOST_NOEXCEPT_OR_NOTHROW {}
  130. virtual char const* what() const BOOST_NOEXCEPT_OR_NOTHROW
  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() BOOST_NOEXCEPT_OR_NOTHROW {}
  138. virtual char const* what() const BOOST_NOEXCEPT_OR_NOTHROW
  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=(Base const& other)
  160. {
  161. Base::operator=(other);
  162. return *this;
  163. }
  164. };
  165. //[utree_strings
  166. /*`The `utree` string types described below are used by the `utree` API
  167. only. These are not used to store information in the `utree` itself.
  168. Their purpose is to refer to different internal `utree` node types
  169. only. For instance, creating a `utree` from a binary data type will
  170. create a `binary_type` utree node (see above).
  171. */
  172. /*`The binary data type can be represented either verbatim as a sequence
  173. of bytes or as a pair of iterators into some other stored binary data
  174. sequence. Use this string type to access/create a `binary_type` `utree`.
  175. */
  176. typedef basic_string<
  177. boost::iterator_range<char const*>, utree_type::binary_type
  178. > binary_range_type;
  179. typedef basic_string<
  180. std::string, utree_type::binary_type
  181. > binary_string_type;
  182. /*`The UTF-8 string can be represented either verbatim as a sequence of
  183. characters or as a pair of iterators into some other stored binary data
  184. sequence. Use this string type to access/create a `string_type` `utree`.
  185. */
  186. typedef basic_string<
  187. boost::iterator_range<char const*>, utree_type::string_type
  188. > utf8_string_range_type;
  189. typedef basic_string<
  190. std::string, utree_type::string_type
  191. > utf8_string_type;
  192. /*`The UTF-8 symbol can be represented either verbatim as a sequence of
  193. characters or as a pair of iterators into some other stored binary data
  194. sequence. Use this string type to access/create a `symbol_type` `utree`.
  195. */
  196. typedef basic_string<
  197. boost::iterator_range<char const*>, utree_type::symbol_type
  198. > utf8_symbol_range_type;
  199. typedef basic_string<
  200. std::string, utree_type::symbol_type
  201. > utf8_symbol_type;
  202. //]
  203. ///////////////////////////////////////////////////////////////////////////
  204. // Our function type
  205. ///////////////////////////////////////////////////////////////////////////
  206. class utree;
  207. //[utree_function_object_interface
  208. struct function_base
  209. {
  210. virtual ~function_base() {}
  211. virtual utree operator()(utree const& env) const = 0;
  212. virtual utree operator()(utree& env) const = 0;
  213. // Calling f.clone() must return a newly allocated function_base
  214. // instance that is equal to f.
  215. virtual function_base* clone() const = 0;
  216. };
  217. template <typename F>
  218. struct stored_function : function_base
  219. {
  220. F f;
  221. stored_function(F f = F());
  222. virtual ~stored_function();
  223. virtual utree operator()(utree const& env) const;
  224. virtual utree operator()(utree& env) const;
  225. virtual function_base* clone() const;
  226. };
  227. template <typename F>
  228. struct referenced_function : function_base
  229. {
  230. F& f;
  231. referenced_function(F& f);
  232. virtual ~referenced_function();
  233. virtual utree operator()(utree const& env) const;
  234. virtual utree operator()(utree& env) const;
  235. virtual function_base* clone() const;
  236. };
  237. //]
  238. ///////////////////////////////////////////////////////////////////////////
  239. // Shallow tag. Instructs utree to hold an iterator_range
  240. // as-is without deep copying the range.
  241. ///////////////////////////////////////////////////////////////////////////
  242. struct shallow_tag {};
  243. shallow_tag const shallow = {};
  244. ///////////////////////////////////////////////////////////////////////////
  245. // A void* plus type_info
  246. ///////////////////////////////////////////////////////////////////////////
  247. class any_ptr
  248. {
  249. public:
  250. template <typename Ptr>
  251. typename boost::disable_if<
  252. boost::is_polymorphic<
  253. typename boost::remove_pointer<Ptr>::type>,
  254. Ptr>::type
  255. get() const
  256. {
  257. if (*i == typeid(Ptr))
  258. {
  259. return static_cast<Ptr>(p);
  260. }
  261. boost::throw_exception(std::bad_cast());
  262. }
  263. template <typename T>
  264. any_ptr(T* p)
  265. : p(p), i(&typeid(T*))
  266. {}
  267. friend bool operator==(any_ptr const& a, any_ptr const& b)
  268. {
  269. return (a.p == b.p) && (*a.i == *b.i);
  270. }
  271. private:
  272. // constructor is private
  273. any_ptr(void* p, std::type_info const* i)
  274. : p(p), i(i) {}
  275. template <typename UTreeX, typename UTreeY>
  276. friend struct detail::visit_impl;
  277. friend class utree;
  278. void* p;
  279. std::type_info const* i;
  280. };
  281. //[utree
  282. class utree {
  283. public:
  284. ///////////////////////////////////////////////////////////////////////
  285. // The invalid type
  286. struct invalid_type {};
  287. ///////////////////////////////////////////////////////////////////////
  288. // The nil type
  289. struct nil_type {};
  290. ///////////////////////////////////////////////////////////////////////
  291. // The list type, this can be used to initialize an utree to hold an
  292. // empty list
  293. struct list_type;
  294. //[utree_container_types
  295. typedef utree value_type;
  296. typedef utree& reference;
  297. typedef utree const& const_reference;
  298. typedef std::ptrdiff_t difference_type;
  299. typedef std::size_t size_type;
  300. typedef detail::list::node_iterator<utree> iterator;
  301. typedef detail::list::node_iterator<utree const> const_iterator;
  302. //]
  303. typedef detail::list::node_iterator<boost::reference_wrapper<utree> >
  304. ref_iterator;
  305. typedef boost::iterator_range<iterator> range;
  306. typedef boost::iterator_range<const_iterator> const_range;
  307. // dtor
  308. ~utree();
  309. ////////////////////////////////////////////////////////////////////////
  310. //[utree_initialization
  311. /*`A `utree` can be constructed or initialized from a wide range of
  312. data types, allowing to create `utree` instances for every
  313. possible node type (see the description of `utree_type::info` above).
  314. For this reason it exposes a constructor and an assignment operator
  315. for each of the allowed node types as shown below. All constructors
  316. are non-explicit on purpose, allowing to use an utree instance as
  317. the attribute to almost any Qi parser.
  318. */
  319. // This constructs an `invalid_type` node. When used in places
  320. // where a boost::optional is expected (i.e. as an attribute for the
  321. // optional component), this represents the 'empty' state.
  322. utree(invalid_type = invalid_type());
  323. // This initializes a `nil_type` node, which represents a valid,
  324. // 'initialized empty' utree (different from invalid_type!).
  325. utree(nil_type);
  326. reference operator=(nil_type);
  327. // This initializes a `boolean_type` node, which can hold 'true' or
  328. // 'false' only.
  329. explicit utree(bool);
  330. reference operator=(bool);
  331. // This initializes an `integer_type` node, which can hold arbitrary
  332. // integers. For convenience these functions are overloaded for signed
  333. // and unsigned integer types.
  334. utree(unsigned int);
  335. utree(int);
  336. reference operator=(unsigned int);
  337. reference operator=(int);
  338. // This initializes a `double_type` node, which can hold arbitrary
  339. // floating point (double) values.
  340. utree(double);
  341. reference operator=(double);
  342. // This initializes a `string_type` node, which can hold a narrow
  343. // character sequence (usually an UTF-8 string).
  344. utree(char);
  345. utree(char const*);
  346. utree(char const*, std::size_t);
  347. utree(std::string const&);
  348. reference operator=(char);
  349. reference operator=(char const*);
  350. reference operator=(std::string const&);
  351. // This constructs a `string_range_type` node, which does not copy the
  352. // data but stores the iterator range to the character sequence the
  353. // range has been initialized from.
  354. utree(utf8_string_range_type const&, shallow_tag);
  355. // This initializes a `reference_type` node, which holds a reference to
  356. // another utree node. All operations on such a node are automatically
  357. // forwarded to the referenced utree instance.
  358. utree(boost::reference_wrapper<utree>);
  359. reference operator=(boost::reference_wrapper<utree>);
  360. // This initializes an `any_type` node, which can hold a pointer to an
  361. // instance of any type together with the typeid of that type. When
  362. // accessing that pointer the typeid will be checked, causing a
  363. // std::bad_cast to be thrown if the typeids do not match.
  364. utree(any_ptr const&);
  365. reference operator=(any_ptr const&);
  366. // This initializes a `range_type` node, which holds an utree list node
  367. // the elements of which are copy constructed (assigned) from the
  368. // elements referenced by the given range of iterators.
  369. template <class Iterator>
  370. utree(boost::iterator_range<Iterator>);
  371. template <class Iterator>
  372. reference operator=(boost::iterator_range<Iterator>);
  373. // This initializes a `function_type` node from a polymorphic function
  374. // object pointer (takes ownership) or reference.
  375. utree(function_base const&);
  376. reference operator=(function_base const&);
  377. utree(function_base*);
  378. reference operator=(function_base*);
  379. // This initializes either a `string_type`, a `symbol_type`, or a
  380. // `binary_type` node (depending on the template parameter `type_`),
  381. // which will hold the corresponding narrow character sequence (usually
  382. // an UTF-8 string).
  383. template <class Base, utree_type::info type_>
  384. utree(basic_string<Base, type_> const&);
  385. template <class Base, utree_type::info type_>
  386. reference operator=(basic_string<Base, type_> const&);
  387. //]
  388. // copy
  389. utree(const_reference);
  390. reference operator=(const_reference);
  391. // range
  392. utree(range, shallow_tag);
  393. utree(const_range, shallow_tag);
  394. // assign dispatch
  395. template <class Iterator>
  396. void assign(Iterator, Iterator);
  397. ////////////////////////////////////////////////////////////////////////
  398. ////////////////////////////////////////////////////////////////////////
  399. // function object visitation interface
  400. // single dispatch
  401. template <class F>
  402. typename boost::result_of<F(utree const&)>::type
  403. static visit(utree const&, F);
  404. template <class F>
  405. typename boost::result_of<F(utree&)>::type
  406. static visit(utree&, F);
  407. // double dispatch
  408. template <class F>
  409. typename boost::result_of<F(utree const&, utree const&)>::type
  410. static visit(utree const&, utree const&, F);
  411. template <class F>
  412. typename boost::result_of<F(utree&, utree const&)>::type
  413. static visit(utree&, utree const&, F);
  414. template <class F>
  415. typename boost::result_of<F(utree const&, utree&)>::type
  416. static visit(utree const&, utree&, F);
  417. template <class F>
  418. typename boost::result_of<F(utree&, utree&)>::type
  419. static visit(utree&, utree&, F);
  420. ////////////////////////////////////////////////////////////////////////
  421. ///////////////////////////////////////////////////////////////////////
  422. //[utree_container_functions
  423. // STL Container interface
  424. // insertion
  425. template <class T>
  426. void push_back(T const&);
  427. template <class T>
  428. void push_front(T const&);
  429. template <class T>
  430. iterator insert(iterator, T const&);
  431. template <class T>
  432. void insert(iterator, std::size_t, T const&);
  433. template <class Iterator>
  434. void insert(iterator, Iterator, Iterator);
  435. // erasure
  436. void pop_front();
  437. void pop_back();
  438. iterator erase(iterator);
  439. iterator erase(iterator, iterator);
  440. // front access
  441. reference front();
  442. const_reference front() const;
  443. iterator begin();
  444. const_iterator begin() const;
  445. ref_iterator ref_begin();
  446. // back access
  447. reference back();
  448. const_reference back() const;
  449. iterator end();
  450. const_iterator end() const;
  451. ref_iterator ref_end();
  452. //]
  453. // This clears the utree instance and resets its type to `invalid_type`
  454. void clear();
  455. void swap(utree&);
  456. bool empty() const;
  457. size_type size() const;
  458. /*`[warning `size()` has O(n) complexity on `utree` ranges. On utree
  459. lists, it has O(1) complexity.]`*/
  460. ////////////////////////////////////////////////////////////////////////
  461. //[utree_variant_functions
  462. // return the data type (`utree_type::info`) of the currently stored
  463. // data item
  464. utree_type::info which() const;
  465. // access the currently stored data in a type safe manner, this will
  466. // throw a `std::bad_cast()` if the currently stored data item is not
  467. // default convertible to `T`.
  468. template <class T>
  469. T get() const;
  470. //]
  471. reference deref();
  472. const_reference deref() const;
  473. short tag() const;
  474. void tag(short);
  475. utree eval(utree const&) const;
  476. utree eval(utree&) const;
  477. utree operator() (utree const&) const;
  478. utree operator() (utree&) const;
  479. //<-
  480. protected:
  481. void ensure_list_type(char const* failed_in = "ensure_list_type()");
  482. private:
  483. typedef utree_type type;
  484. template <class UTreeX, class UTreeY>
  485. friend struct detail::visit_impl;
  486. friend struct detail::index_impl;
  487. type::info get_type() const;
  488. void set_type(type::info);
  489. void free();
  490. void copy(const_reference);
  491. union {
  492. detail::fast_string s;
  493. detail::list l;
  494. detail::range r;
  495. detail::string_range sr;
  496. detail::void_ptr v;
  497. bool b;
  498. int i;
  499. double d;
  500. utree* p;
  501. function_base* pf;
  502. };
  503. //->
  504. };
  505. //]
  506. //[utree_tuple_interface
  507. /*<-*/inline/*->*/
  508. utree::reference get(utree::reference, utree::size_type);
  509. /*<-*/inline/*->*/
  510. utree::const_reference get(utree::const_reference, utree::size_type);
  511. /*`[warning `get()` has O(n) complexity.]`*/
  512. //]
  513. struct utree::list_type : utree
  514. {
  515. using utree::operator=;
  516. list_type() : utree() { ensure_list_type("list_type()"); }
  517. template <typename T0>
  518. list_type(T0 t0) : utree(t0) {}
  519. template <typename T0, typename T1>
  520. list_type(T0 t0, T1 t1) : utree(t0, t1) {}
  521. };
  522. ///////////////////////////////////////////////////////////////////////////
  523. // predefined instances for singular types
  524. utree::invalid_type const invalid = {};
  525. utree::nil_type const nil = {};
  526. utree::list_type const empty_list = utree::list_type();
  527. }}
  528. #if defined(BOOST_MSVC)
  529. #pragma warning(pop)
  530. #endif
  531. #endif