/Src/Dependencies/Boost/boost/spirit/home/support/utree/detail/utree_detail2.hpp

http://hadesmem.googlecode.com/ · C++ Header · 1632 lines · 1359 code · 239 blank · 34 comment · 201 complexity · d3668eb17577ee94ff366a27d83b3303 MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  4. Copyright (c) 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_DETAIL2)
  9. #define BOOST_SPIRIT_UTREE_DETAIL2
  10. #if defined(BOOST_MSVC)
  11. # pragma warning(push)
  12. # pragma warning(disable: 4800)
  13. #endif
  14. #include <boost/type_traits/remove_pointer.hpp>
  15. #include <boost/type_traits/is_pointer.hpp>
  16. #include <boost/utility/enable_if.hpp>
  17. #include <boost/throw_exception.hpp>
  18. #include <boost/iterator/iterator_traits.hpp>
  19. namespace boost { namespace spirit { namespace detail
  20. {
  21. inline char& fast_string::info()
  22. {
  23. return buff[small_string_size];
  24. }
  25. inline char fast_string::info() const
  26. {
  27. return buff[small_string_size];
  28. }
  29. inline int fast_string::get_type() const
  30. {
  31. return info() >> 1;
  32. }
  33. inline void fast_string::set_type(int t)
  34. {
  35. info() = (t << 1) | (info() & 1);
  36. }
  37. inline short fast_string::tag() const
  38. {
  39. return (int(buff[small_string_size-2]) << 8) + (unsigned char)buff[small_string_size-1];
  40. }
  41. inline void fast_string::tag(short tag)
  42. {
  43. buff[small_string_size-2] = tag >> 8;
  44. buff[small_string_size-1] = tag & 0xff;
  45. }
  46. inline bool fast_string::is_heap_allocated() const
  47. {
  48. return info() & 1;
  49. }
  50. inline std::size_t fast_string::size() const
  51. {
  52. if (is_heap_allocated())
  53. return heap.size;
  54. else
  55. return max_string_len - buff[max_string_len];
  56. }
  57. inline char const* fast_string::str() const
  58. {
  59. if (is_heap_allocated())
  60. return heap.str;
  61. else
  62. return buff;
  63. }
  64. template <typename Iterator>
  65. inline void fast_string::construct(Iterator f, Iterator l)
  66. {
  67. unsigned const size = l-f;
  68. char* str;
  69. if (size < max_string_len)
  70. {
  71. // if it fits, store it in-situ; small_string_size minus the length
  72. // of the string is placed in buff[small_string_size - 1]
  73. str = buff;
  74. buff[max_string_len] = static_cast<char>(max_string_len - size);
  75. info() &= ~0x1;
  76. }
  77. else
  78. {
  79. // else, store it in the heap
  80. str = new char[size + 1]; // add one for the null char
  81. heap.str = str;
  82. heap.size = size;
  83. info() |= 0x1;
  84. }
  85. for (std::size_t i = 0; i != size; ++i)
  86. {
  87. *str++ = *f++;
  88. }
  89. *str = '\0'; // add the null char
  90. }
  91. inline void fast_string::swap(fast_string& other)
  92. {
  93. std::swap(*this, other);
  94. }
  95. inline void fast_string::free()
  96. {
  97. if (is_heap_allocated())
  98. {
  99. delete [] heap.str;
  100. }
  101. }
  102. inline void fast_string::copy(fast_string const& other)
  103. {
  104. construct(other.str(), other.str() + other.size());
  105. }
  106. inline void fast_string::initialize()
  107. {
  108. for (std::size_t i = 0; i != buff_size / (sizeof(long)/sizeof(char)); ++i)
  109. lbuff[i] = 0;
  110. }
  111. struct list::node : boost::noncopyable
  112. {
  113. template <typename T>
  114. node(T const& val, node* next, node* prev)
  115. : val(val), next(next), prev(prev) {}
  116. void unlink()
  117. {
  118. prev->next = next;
  119. next->prev = prev;
  120. }
  121. utree val;
  122. node* next;
  123. node* prev;
  124. };
  125. template <typename Value>
  126. class list::node_iterator
  127. : public boost::iterator_facade<
  128. node_iterator<Value>
  129. , Value
  130. , boost::bidirectional_traversal_tag>
  131. {
  132. public:
  133. node_iterator()
  134. : node(0), prev(0) {}
  135. node_iterator(list::node* node, list::node* prev)
  136. : node(node), prev(prev) {}
  137. private:
  138. friend class boost::iterator_core_access;
  139. friend class boost::spirit::utree;
  140. friend struct boost::spirit::detail::list;
  141. void increment()
  142. {
  143. if (node != 0) // not at end
  144. {
  145. prev = node;
  146. node = node->next;
  147. }
  148. }
  149. void decrement()
  150. {
  151. if (prev != 0) // not at begin
  152. {
  153. node = prev;
  154. prev = prev->prev;
  155. }
  156. }
  157. bool equal(node_iterator const& other) const
  158. {
  159. return node == other.node;
  160. }
  161. typename node_iterator::reference dereference() const
  162. {
  163. return node->val;
  164. }
  165. list::node* node;
  166. list::node* prev;
  167. };
  168. template <typename Value>
  169. class list::node_iterator<boost::reference_wrapper<Value> >
  170. : public boost::iterator_facade<
  171. node_iterator<boost::reference_wrapper<Value> >
  172. , boost::reference_wrapper<Value>
  173. , boost::bidirectional_traversal_tag>
  174. {
  175. public:
  176. node_iterator()
  177. : node(0), prev(0), curr(nil_node) {}
  178. node_iterator(list::node* node, list::node* prev)
  179. : node(node), prev(prev), curr(node ? node->val : nil_node) {}
  180. private:
  181. friend class boost::iterator_core_access;
  182. friend class boost::spirit::utree;
  183. friend struct boost::spirit::detail::list;
  184. void increment()
  185. {
  186. if (node != 0) // not at end
  187. {
  188. prev = node;
  189. node = node->next;
  190. curr = boost::ref(node ? node->val : nil_node);
  191. }
  192. }
  193. void decrement()
  194. {
  195. if (prev != 0) // not at begin
  196. {
  197. node = prev;
  198. prev = prev->prev;
  199. curr = boost::ref(node ? node->val : nil_node);
  200. }
  201. }
  202. bool equal(node_iterator const& other) const
  203. {
  204. return node == other.node;
  205. }
  206. typename node_iterator::reference dereference() const
  207. {
  208. return curr;
  209. }
  210. list::node* node;
  211. list::node* prev;
  212. static Value nil_node;
  213. mutable boost::reference_wrapper<Value> curr;
  214. };
  215. template <typename Value>
  216. Value list::node_iterator<boost::reference_wrapper<Value> >::nil_node = Value();
  217. inline void list::free()
  218. {
  219. node* p = first;
  220. while (p != 0)
  221. {
  222. node* next = p->next;
  223. delete p;
  224. p = next;
  225. }
  226. }
  227. inline void list::copy(list const& other)
  228. {
  229. node* p = other.first;
  230. while (p != 0)
  231. {
  232. push_back(p->val);
  233. p = p->next;
  234. }
  235. }
  236. inline void list::default_construct()
  237. {
  238. first = last = 0;
  239. size = 0;
  240. }
  241. template <typename T, typename Iterator>
  242. inline void list::insert(T const& val, Iterator pos)
  243. {
  244. if (!pos.node)
  245. {
  246. push_back(val);
  247. return;
  248. }
  249. detail::list::node* new_node =
  250. new detail::list::node(val, pos.node, pos.node->prev);
  251. if (pos.node->prev)
  252. pos.node->prev->next = new_node;
  253. else
  254. first = new_node;
  255. pos.node->prev = new_node;
  256. ++size;
  257. }
  258. template <typename T>
  259. inline void list::push_front(T const& val)
  260. {
  261. detail::list::node* new_node;
  262. if (first == 0)
  263. {
  264. new_node = new detail::list::node(val, 0, 0);
  265. first = last = new_node;
  266. ++size;
  267. }
  268. else
  269. {
  270. new_node = new detail::list::node(val, first, first->prev);
  271. first->prev = new_node;
  272. first = new_node;
  273. ++size;
  274. }
  275. }
  276. template <typename T>
  277. inline void list::push_back(T const& val)
  278. {
  279. if (last == 0)
  280. push_front(val);
  281. else {
  282. detail::list::node* new_node =
  283. new detail::list::node(val, last->next, last);
  284. last->next = new_node;
  285. last = new_node;
  286. ++size;
  287. }
  288. }
  289. inline void list::pop_front()
  290. {
  291. BOOST_ASSERT(size != 0);
  292. if (first == last) // there's only one item
  293. {
  294. delete first;
  295. size = 0;
  296. first = last = 0;
  297. }
  298. else
  299. {
  300. node* np = first;
  301. first = first->next;
  302. first->prev = 0;
  303. delete np;
  304. --size;
  305. }
  306. }
  307. inline void list::pop_back()
  308. {
  309. BOOST_ASSERT(size != 0);
  310. if (first == last) // there's only one item
  311. {
  312. delete first;
  313. size = 0;
  314. first = last = 0;
  315. }
  316. else
  317. {
  318. node* np = last;
  319. last = last->prev;
  320. last->next = 0;
  321. delete np;
  322. --size;
  323. }
  324. }
  325. inline list::node* list::erase(node* pos)
  326. {
  327. BOOST_ASSERT(pos != 0);
  328. if (pos == first)
  329. {
  330. pop_front();
  331. return first;
  332. }
  333. else if (pos == last)
  334. {
  335. pop_back();
  336. return 0;
  337. }
  338. else
  339. {
  340. node* next(pos->next);
  341. pos->unlink();
  342. delete pos;
  343. --size;
  344. return next;
  345. }
  346. }
  347. ///////////////////////////////////////////////////////////////////////////
  348. // simple binder for binary visitation (we don't want to bring in the big guns)
  349. template <typename F, typename X>
  350. struct bind_impl
  351. {
  352. typedef typename F::result_type result_type;
  353. X& x; // always by reference
  354. F f;
  355. bind_impl(F f, X& x) : x(x), f(f) {}
  356. template <typename Y>
  357. typename F::result_type operator()(Y& y) const
  358. {
  359. return f(x, y);
  360. }
  361. template <typename Y>
  362. typename F::result_type operator()(Y const& y) const
  363. {
  364. return f(x, y);
  365. }
  366. };
  367. template <typename F, typename X>
  368. bind_impl<F, X const> bind(F f, X const& x)
  369. {
  370. return bind_impl<F, X const>(f, x);
  371. }
  372. template <typename F, typename X>
  373. bind_impl<F, X> bind(F f, X& x)
  374. {
  375. return bind_impl<F, X>(f, x);
  376. }
  377. template <typename UTreeX, typename UTreeY = UTreeX>
  378. struct visit_impl
  379. {
  380. template <typename F>
  381. typename F::result_type
  382. static apply(UTreeX& x, F f) // single dispatch
  383. {
  384. typedef typename
  385. boost::mpl::if_<boost::is_const<UTreeX>,
  386. typename UTreeX::const_iterator,
  387. typename UTreeX::iterator>::type
  388. iterator;
  389. typedef boost::iterator_range<iterator> list_range;
  390. typedef utree_type type;
  391. switch (x.get_type())
  392. {
  393. default:
  394. BOOST_THROW_EXCEPTION(
  395. bad_type_exception("corrupt utree type", x.get_type()));
  396. break;
  397. case type::invalid_type:
  398. return f(invalid);
  399. case type::nil_type:
  400. return f(nil);
  401. case type::bool_type:
  402. return f(x.b);
  403. case type::int_type:
  404. return f(x.i);
  405. case type::double_type:
  406. return f(x.d);
  407. case type::list_type:
  408. return f(list_range(iterator(x.l.first, 0), iterator(0, x.l.last)));
  409. case type::range_type:
  410. return f(list_range(iterator(x.r.first, 0), iterator(0, x.r.last)));
  411. case type::string_type:
  412. return f(utf8_string_range_type(x.s.str(), x.s.size()));
  413. case type::string_range_type:
  414. return f(utf8_string_range_type(x.sr.first, x.sr.last));
  415. case type::symbol_type:
  416. return f(utf8_symbol_range_type(x.s.str(), x.s.size()));
  417. case type::binary_type:
  418. return f(binary_range_type(x.s.str(), x.s.size()));
  419. case type::reference_type:
  420. return apply(*x.p, f);
  421. case type::any_type:
  422. return f(any_ptr(x.v.p, x.v.i));
  423. case type::function_type:
  424. return f(*x.pf);
  425. }
  426. }
  427. template <typename F>
  428. typename F::result_type
  429. static apply(UTreeX& x, UTreeY& y, F f) // double dispatch
  430. {
  431. typedef typename
  432. boost::mpl::if_<boost::is_const<UTreeX>,
  433. typename UTreeX::const_iterator,
  434. typename UTreeX::iterator>::type
  435. iterator;
  436. typedef boost::iterator_range<iterator> list_range;
  437. typedef utree_type type;
  438. switch (x.get_type())
  439. {
  440. default:
  441. BOOST_THROW_EXCEPTION(
  442. bad_type_exception("corrupt utree type", x.get_type()));
  443. break;
  444. case type::invalid_type:
  445. return visit_impl::apply(y, detail::bind(f, invalid));
  446. case type::nil_type:
  447. return visit_impl::apply(y, detail::bind(f, nil));
  448. case type::bool_type:
  449. return visit_impl::apply(y, detail::bind(f, x.b));
  450. case type::int_type:
  451. return visit_impl::apply(y, detail::bind(f, x.i));
  452. case type::double_type:
  453. return visit_impl::apply(y, detail::bind(f, x.d));
  454. case type::list_type:
  455. return visit_impl::apply(
  456. y, detail::bind<F, list_range>(f,
  457. list_range(iterator(x.l.first, 0), iterator(0, x.l.last))));
  458. case type::range_type:
  459. return visit_impl::apply(
  460. y, detail::bind<F, list_range>(f,
  461. list_range(iterator(x.r.first, 0), iterator(0, x.r.last))));
  462. case type::string_type:
  463. return visit_impl::apply(y, detail::bind(
  464. f, utf8_string_range_type(x.s.str(), x.s.size())));
  465. case type::string_range_type:
  466. return visit_impl::apply(y, detail::bind(
  467. f, utf8_string_range_type(x.sr.first, x.sr.last)));
  468. case type::symbol_type:
  469. return visit_impl::apply(y, detail::bind(
  470. f, utf8_symbol_range_type(x.s.str(), x.s.size())));
  471. case type::binary_type:
  472. return visit_impl::apply(y, detail::bind(
  473. f, binary_range_type(x.s.str(), x.s.size())));
  474. case type::reference_type:
  475. return apply(*x.p, y, f);
  476. case type::any_type:
  477. return visit_impl::apply(
  478. y, detail::bind(f, any_ptr(x.v.p, x.v.i)));
  479. case type::function_type:
  480. return visit_impl::apply(y, detail::bind(f, *x.pf));
  481. }
  482. }
  483. };
  484. struct index_impl
  485. {
  486. static utree& apply(utree& ut, std::size_t i)
  487. {
  488. switch (ut.get_type())
  489. {
  490. case utree_type::reference_type:
  491. return apply(ut.deref(), i);
  492. case utree_type::range_type:
  493. return apply(ut.r.first, i);
  494. case utree_type::list_type:
  495. return apply(ut.l.first, i);
  496. default:
  497. BOOST_THROW_EXCEPTION(
  498. bad_type_exception
  499. ("index operation performed on non-list utree type",
  500. ut.get_type()));
  501. }
  502. }
  503. static utree const& apply(utree const& ut, std::size_t i)
  504. {
  505. switch (ut.get_type())
  506. {
  507. case utree_type::reference_type:
  508. return apply(ut.deref(), i);
  509. case utree_type::range_type:
  510. return apply(ut.r.first, i);
  511. case utree_type::list_type:
  512. return apply(ut.l.first, i);
  513. default:
  514. BOOST_THROW_EXCEPTION(
  515. bad_type_exception
  516. ("index operation performed on non-list utree type",
  517. ut.get_type()));
  518. }
  519. }
  520. static utree& apply(list::node* node, std::size_t i)
  521. {
  522. for (; i > 0; --i)
  523. node = node->next;
  524. return node->val;
  525. }
  526. static utree const& apply(list::node const* node, std::size_t i)
  527. {
  528. for (; i > 0; --i)
  529. node = node->next;
  530. return node->val;
  531. }
  532. };
  533. }}}
  534. namespace boost { namespace spirit
  535. {
  536. template <typename F>
  537. stored_function<F>::stored_function(F f)
  538. : f(f)
  539. {
  540. }
  541. template <typename F>
  542. stored_function<F>::~stored_function()
  543. {
  544. }
  545. template <typename F>
  546. utree stored_function<F>::operator()(utree const& env) const
  547. {
  548. return f(env);
  549. }
  550. template <typename F>
  551. utree stored_function<F>::operator()(utree& env) const
  552. {
  553. return f(env);
  554. }
  555. template <typename F>
  556. function_base*
  557. stored_function<F>::clone() const
  558. {
  559. return new stored_function<F>(f);
  560. }
  561. template <typename F>
  562. referenced_function<F>::referenced_function(F& f)
  563. : f(f)
  564. {
  565. }
  566. template <typename F>
  567. referenced_function<F>::~referenced_function()
  568. {
  569. }
  570. template <typename F>
  571. utree referenced_function<F>::operator()(utree const& env) const
  572. {
  573. return f(env);
  574. }
  575. template <typename F>
  576. utree referenced_function<F>::operator()(utree& env) const
  577. {
  578. return f(env);
  579. }
  580. template <typename F>
  581. function_base*
  582. referenced_function<F>::clone() const
  583. {
  584. return new referenced_function<F>(f);
  585. }
  586. inline utree::utree(utree::invalid_type)
  587. {
  588. s.initialize();
  589. set_type(type::invalid_type);
  590. }
  591. inline utree::utree(utree::nil_type)
  592. {
  593. s.initialize();
  594. set_type(type::nil_type);
  595. }
  596. inline utree::utree(bool b_)
  597. {
  598. s.initialize();
  599. b = b_;
  600. set_type(type::bool_type);
  601. }
  602. inline utree::utree(char c)
  603. {
  604. s.initialize();
  605. // char constructs a single element string
  606. s.construct(&c, &c+1);
  607. set_type(type::string_type);
  608. }
  609. inline utree::utree(unsigned int i_)
  610. {
  611. s.initialize();
  612. i = i_;
  613. set_type(type::int_type);
  614. }
  615. inline utree::utree(int i_)
  616. {
  617. s.initialize();
  618. i = i_;
  619. set_type(type::int_type);
  620. }
  621. inline utree::utree(double d_)
  622. {
  623. s.initialize();
  624. d = d_;
  625. set_type(type::double_type);
  626. }
  627. inline utree::utree(char const* str)
  628. {
  629. s.initialize();
  630. s.construct(str, str + strlen(str));
  631. set_type(type::string_type);
  632. }
  633. inline utree::utree(char const* str, std::size_t len)
  634. {
  635. s.initialize();
  636. s.construct(str, str + len);
  637. set_type(type::string_type);
  638. }
  639. inline utree::utree(std::string const& str)
  640. {
  641. s.initialize();
  642. s.construct(str.begin(), str.end());
  643. set_type(type::string_type);
  644. }
  645. template <typename Base, utree_type::info type_>
  646. inline utree::utree(basic_string<Base, type_> const& bin)
  647. {
  648. s.initialize();
  649. s.construct(bin.begin(), bin.end());
  650. set_type(type_);
  651. }
  652. inline utree::utree(boost::reference_wrapper<utree> ref)
  653. {
  654. s.initialize();
  655. p = ref.get_pointer();
  656. set_type(type::reference_type);
  657. }
  658. inline utree::utree(any_ptr const& p)
  659. {
  660. s.initialize();
  661. v.p = p.p;
  662. v.i = p.i;
  663. set_type(type::any_type);
  664. }
  665. inline utree::utree(function_base const& pf_)
  666. {
  667. s.initialize();
  668. pf = pf_.clone();
  669. set_type(type::function_type);
  670. }
  671. inline utree::utree(function_base* pf_)
  672. {
  673. s.initialize();
  674. pf = pf_;
  675. set_type(type::function_type);
  676. }
  677. template <typename Iter>
  678. inline utree::utree(boost::iterator_range<Iter> r)
  679. {
  680. s.initialize();
  681. assign(r.begin(), r.end());
  682. }
  683. inline utree::utree(range r, shallow_tag)
  684. {
  685. s.initialize();
  686. this->r.first = r.begin().node;
  687. this->r.last = r.end().prev;
  688. set_type(type::range_type);
  689. }
  690. inline utree::utree(const_range r, shallow_tag)
  691. {
  692. s.initialize();
  693. this->r.first = r.begin().node;
  694. this->r.last = r.end().prev;
  695. set_type(type::range_type);
  696. }
  697. inline utree::utree(utf8_string_range_type const& str, shallow_tag)
  698. {
  699. s.initialize();
  700. this->sr.first = str.begin();
  701. this->sr.last = str.end();
  702. set_type(type::string_range_type);
  703. }
  704. inline utree::utree(utree const& other)
  705. {
  706. s.initialize();
  707. copy(other);
  708. }
  709. inline utree::~utree()
  710. {
  711. free();
  712. }
  713. inline utree& utree::operator=(utree const& other)
  714. {
  715. if (this != &other)
  716. {
  717. free();
  718. copy(other);
  719. }
  720. return *this;
  721. }
  722. inline utree& utree::operator=(nil_type)
  723. {
  724. free();
  725. set_type(type::nil_type);
  726. return *this;
  727. }
  728. inline utree& utree::operator=(bool b_)
  729. {
  730. free();
  731. b = b_;
  732. set_type(type::bool_type);
  733. return *this;
  734. }
  735. inline utree& utree::operator=(char c)
  736. {
  737. // char constructs a single element string
  738. free();
  739. s.construct(&c, &c+1);
  740. set_type(type::string_type);
  741. return *this;
  742. }
  743. inline utree& utree::operator=(unsigned int i_)
  744. {
  745. free();
  746. i = i_;
  747. set_type(type::int_type);
  748. return *this;
  749. }
  750. inline utree& utree::operator=(int i_)
  751. {
  752. free();
  753. i = i_;
  754. set_type(type::int_type);
  755. return *this;
  756. }
  757. inline utree& utree::operator=(double d_)
  758. {
  759. free();
  760. d = d_;
  761. set_type(type::double_type);
  762. return *this;
  763. }
  764. inline utree& utree::operator=(char const* s_)
  765. {
  766. free();
  767. s.construct(s_, s_ + strlen(s_));
  768. set_type(type::string_type);
  769. return *this;
  770. }
  771. inline utree& utree::operator=(std::string const& s_)
  772. {
  773. free();
  774. s.construct(s_.begin(), s_.end());
  775. set_type(type::string_type);
  776. return *this;
  777. }
  778. template <typename Base, utree_type::info type_>
  779. inline utree& utree::operator=(basic_string<Base, type_> const& bin)
  780. {
  781. free();
  782. s.construct(bin.begin(), bin.end());
  783. set_type(type_);
  784. return *this;
  785. }
  786. inline utree& utree::operator=(boost::reference_wrapper<utree> ref)
  787. {
  788. free();
  789. p = ref.get_pointer();
  790. set_type(type::reference_type);
  791. return *this;
  792. }
  793. inline utree& utree::operator=(any_ptr const& p)
  794. {
  795. free();
  796. v.p = p.p;
  797. v.i = p.i;
  798. set_type(type::any_type);
  799. return *this;
  800. }
  801. inline utree& utree::operator=(function_base const& pf_)
  802. {
  803. free();
  804. pf = pf_.clone();
  805. set_type(type::function_type);
  806. return *this;
  807. }
  808. inline utree& utree::operator=(function_base* pf_)
  809. {
  810. free();
  811. pf = pf_;
  812. set_type(type::function_type);
  813. return *this;
  814. }
  815. template <typename Iter>
  816. inline utree& utree::operator=(boost::iterator_range<Iter> r)
  817. {
  818. free();
  819. assign(r.begin(), r.end());
  820. return *this;
  821. }
  822. template <typename F>
  823. typename boost::result_of<F(utree const&)>::type
  824. inline utree::visit(utree const& x, F f)
  825. {
  826. return detail::visit_impl<utree const>::apply(x, f);
  827. }
  828. template <typename F>
  829. typename boost::result_of<F(utree&)>::type
  830. inline utree::visit(utree& x, F f)
  831. {
  832. return detail::visit_impl<utree>::apply(x, f);
  833. }
  834. template <typename F>
  835. typename boost::result_of<F(utree const&, utree const&)>::type
  836. inline utree::visit(utree const& x, utree const& y, F f)
  837. {
  838. return detail::visit_impl<utree const, utree const>::apply(x, y, f);
  839. }
  840. template <typename F>
  841. typename boost::result_of<F(utree const&, utree&)>::type
  842. inline utree::visit(utree const& x, utree& y, F f)
  843. {
  844. return detail::visit_impl<utree const, utree>::apply(x, y, f);
  845. }
  846. template <typename F>
  847. typename boost::result_of<F(utree&, utree const&)>::type
  848. inline utree::visit(utree& x, utree const& y, F f)
  849. {
  850. return detail::visit_impl<utree, utree const>::apply(x, y, f);
  851. }
  852. template <typename F>
  853. typename boost::result_of<F(utree&, utree&)>::type
  854. inline utree::visit(utree& x, utree& y, F f)
  855. {
  856. return detail::visit_impl<utree, utree>::apply(x, y, f);
  857. }
  858. inline utree::reference get(utree::reference ut, utree::size_type i)
  859. { return detail::index_impl::apply(ut, i); }
  860. inline utree::const_reference
  861. get(utree::const_reference ut, utree::size_type i)
  862. { return detail::index_impl::apply(ut, i); }
  863. template <typename T>
  864. inline void utree::push_front(T const& val)
  865. {
  866. if (get_type() == type::reference_type)
  867. return p->push_front(val);
  868. ensure_list_type("push_front()");
  869. l.push_front(val);
  870. }
  871. template <typename T>
  872. inline void utree::push_back(T const& val)
  873. {
  874. if (get_type() == type::reference_type)
  875. return p->push_back(val);
  876. ensure_list_type("push_back()");
  877. l.push_back(val);
  878. }
  879. template <typename T>
  880. inline utree::iterator utree::insert(iterator pos, T const& val)
  881. {
  882. if (get_type() == type::reference_type)
  883. return p->insert(pos, val);
  884. ensure_list_type("insert()");
  885. if (!pos.node)
  886. {
  887. l.push_back(val);
  888. return utree::iterator(l.first, 0); // begin();
  889. }
  890. l.insert(val, pos);
  891. return utree::iterator(pos.node->prev, pos.node->prev->prev);
  892. }
  893. template <typename T>
  894. inline void utree::insert(iterator pos, std::size_t n, T const& val)
  895. {
  896. if (get_type() == type::reference_type)
  897. return p->insert(pos, n, val);
  898. ensure_list_type("insert()");
  899. for (std::size_t i = 0; i != n; ++i)
  900. insert(pos, val);
  901. }
  902. template <typename Iterator>
  903. inline void utree::insert(iterator pos, Iterator first, Iterator last)
  904. {
  905. if (get_type() == type::reference_type)
  906. return p->insert(pos, first, last);
  907. ensure_list_type("insert()");
  908. while (first != last)
  909. insert(pos, *first++);
  910. }
  911. template <typename Iterator>
  912. inline void utree::assign(Iterator first, Iterator last)
  913. {
  914. if (get_type() == type::reference_type)
  915. return p->assign(first, last);
  916. clear();
  917. set_type(type::list_type);
  918. while (first != last)
  919. {
  920. push_back(*first);
  921. ++first;
  922. }
  923. }
  924. inline void utree::clear()
  925. {
  926. if (get_type() == type::reference_type)
  927. return p->clear();
  928. // clear will always make this an invalid type
  929. free();
  930. set_type(type::invalid_type);
  931. }
  932. inline void utree::pop_front()
  933. {
  934. if (get_type() == type::reference_type)
  935. return p->pop_front();
  936. if (get_type() != type::list_type)
  937. BOOST_THROW_EXCEPTION(
  938. bad_type_exception
  939. ("pop_front() called on non-list utree type",
  940. get_type()));
  941. l.pop_front();
  942. }
  943. inline void utree::pop_back()
  944. {
  945. if (get_type() == type::reference_type)
  946. return p->pop_back();
  947. if (get_type() != type::list_type)
  948. BOOST_THROW_EXCEPTION(
  949. bad_type_exception
  950. ("pop_back() called on non-list utree type",
  951. get_type()));
  952. l.pop_back();
  953. }
  954. inline utree::iterator utree::erase(iterator pos)
  955. {
  956. if (get_type() == type::reference_type)
  957. return p->erase(pos);
  958. if (get_type() != type::list_type)
  959. BOOST_THROW_EXCEPTION(
  960. bad_type_exception
  961. ("erase() called on non-list utree type",
  962. get_type()));
  963. detail::list::node* np = l.erase(pos.node);
  964. return iterator(np, np?np->prev:l.last);
  965. }
  966. inline utree::iterator utree::erase(iterator first, iterator last)
  967. {
  968. if (get_type() == type::reference_type)
  969. return p->erase(first, last);
  970. if (get_type() != type::list_type)
  971. BOOST_THROW_EXCEPTION(
  972. bad_type_exception
  973. ("erase() called on non-list utree type",
  974. get_type()));
  975. while (first != last)
  976. erase(first++);
  977. return last;
  978. }
  979. inline utree::iterator utree::begin()
  980. {
  981. if (get_type() == type::reference_type)
  982. return p->begin();
  983. else if (get_type() == type::range_type)
  984. return iterator(r.first, 0);
  985. // otherwise...
  986. ensure_list_type("begin()");
  987. return iterator(l.first, 0);
  988. }
  989. inline utree::iterator utree::end()
  990. {
  991. if (get_type() == type::reference_type)
  992. return p->end();
  993. else if (get_type() == type::range_type)
  994. return iterator(0, r.first);
  995. // otherwise...
  996. ensure_list_type("end()");
  997. return iterator(0, l.last);
  998. }
  999. inline utree::ref_iterator utree::ref_begin()
  1000. {
  1001. if (get_type() == type::reference_type)
  1002. return p->ref_begin();
  1003. else if (get_type() == type::range_type)
  1004. return ref_iterator(r.first, 0);
  1005. // otherwise...
  1006. ensure_list_type("ref_begin()");
  1007. return ref_iterator(l.first, 0);
  1008. }
  1009. inline utree::ref_iterator utree::ref_end()
  1010. {
  1011. if (get_type() == type::reference_type)
  1012. return p->ref_end();
  1013. else if (get_type() == type::range_type)
  1014. return ref_iterator(0, r.first);
  1015. // otherwise...
  1016. ensure_list_type("ref_end()");
  1017. return ref_iterator(0, l.last);
  1018. }
  1019. inline utree::const_iterator utree::begin() const
  1020. {
  1021. if (get_type() == type::reference_type)
  1022. return ((utree const*)p)->begin();
  1023. if (get_type() == type::range_type)
  1024. return const_iterator(r.first, 0);
  1025. // otherwise...
  1026. if (get_type() != type::list_type)
  1027. BOOST_THROW_EXCEPTION(
  1028. bad_type_exception
  1029. ("begin() called on non-list utree type",
  1030. get_type()));
  1031. return const_iterator(l.first, 0);
  1032. }
  1033. inline utree::const_iterator utree::end() const
  1034. {
  1035. if (get_type() == type::reference_type)
  1036. return ((utree const*)p)->end();
  1037. if (get_type() == type::range_type)
  1038. return const_iterator(0, r.first);
  1039. // otherwise...
  1040. if (get_type() != type::list_type)
  1041. BOOST_THROW_EXCEPTION(
  1042. bad_type_exception
  1043. ("end() called on non-list utree type",
  1044. get_type()));
  1045. return const_iterator(0, l.last);
  1046. }
  1047. inline bool utree::empty() const
  1048. {
  1049. type::info t = get_type();
  1050. if (t == type::reference_type)
  1051. return ((utree const*)p)->empty();
  1052. if (t == type::range_type)
  1053. return r.first == 0;
  1054. if (t == type::list_type)
  1055. return l.size == 0;
  1056. return t == type::nil_type || t == type::invalid_type;
  1057. }
  1058. inline std::size_t utree::size() const
  1059. {
  1060. type::info t = get_type();
  1061. if (t == type::reference_type)
  1062. return ((utree const*)p)->size();
  1063. if (t == type::range_type)
  1064. {
  1065. // FIXME: O(n), and we have the room to store the size of a range
  1066. // in the union if we compute it when assigned/constructed.
  1067. std::size_t size = 0;
  1068. detail::list::node* n = r.first;
  1069. while (n)
  1070. {
  1071. n = n->next;
  1072. ++size;
  1073. }
  1074. return size;
  1075. }
  1076. if (t == type::list_type)
  1077. return l.size;
  1078. if (t == type::string_type)
  1079. return s.size();
  1080. if (t == type::symbol_type)
  1081. return s.size();
  1082. if (t == type::binary_type)
  1083. return s.size();
  1084. if (t == type::string_range_type)
  1085. return sr.last - sr.first;
  1086. if (t != type::nil_type)
  1087. BOOST_THROW_EXCEPTION(
  1088. bad_type_exception
  1089. ("size() called on non-list and non-string utree type",
  1090. get_type()));
  1091. return 0;
  1092. }
  1093. inline utree_type::info utree::which() const
  1094. {
  1095. return get_type();
  1096. }
  1097. inline utree& utree::front()
  1098. {
  1099. if (get_type() == type::reference_type)
  1100. return p->front();
  1101. if (get_type() == type::range_type)
  1102. {
  1103. if (!r.first)
  1104. BOOST_THROW_EXCEPTION(
  1105. empty_exception("front() called on empty utree range"));
  1106. return r.first->val;
  1107. }
  1108. // otherwise...
  1109. if (get_type() != type::list_type)
  1110. BOOST_THROW_EXCEPTION(
  1111. bad_type_exception
  1112. ("front() called on non-list utree type", get_type()));
  1113. else if (!l.first)
  1114. BOOST_THROW_EXCEPTION(
  1115. empty_exception("front() called on empty utree list"));
  1116. return l.first->val;
  1117. }
  1118. inline utree& utree::back()
  1119. {
  1120. if (get_type() == type::reference_type)
  1121. return p->back();
  1122. if (get_type() == type::range_type)
  1123. {
  1124. if (!r.last)
  1125. BOOST_THROW_EXCEPTION(
  1126. empty_exception("back() called on empty utree range"));
  1127. return r.last->val;
  1128. }
  1129. // otherwise...
  1130. if (get_type() != type::list_type)
  1131. BOOST_THROW_EXCEPTION(
  1132. bad_type_exception
  1133. ("back() called on non-list utree type", get_type()));
  1134. else if (!l.last)
  1135. BOOST_THROW_EXCEPTION(
  1136. empty_exception("back() called on empty utree list"));
  1137. return l.last->val;
  1138. }
  1139. inline utree const& utree::front() const
  1140. {
  1141. if (get_type() == type::reference_type)
  1142. return ((utree const*)p)->front();
  1143. if (get_type() == type::range_type)
  1144. {
  1145. if (!r.first)
  1146. BOOST_THROW_EXCEPTION(
  1147. empty_exception("front() called on empty utree range"));
  1148. return r.first->val;
  1149. }
  1150. // otherwise...
  1151. if (get_type() != type::list_type)
  1152. BOOST_THROW_EXCEPTION(
  1153. bad_type_exception
  1154. ("front() called on non-list utree type", get_type()));
  1155. else if (!l.first)
  1156. BOOST_THROW_EXCEPTION(
  1157. empty_exception("front() called on empty utree list"));
  1158. return l.first->val;
  1159. }
  1160. inline utree const& utree::back() const
  1161. {
  1162. if (get_type() == type::reference_type)
  1163. return ((utree const*)p)->back();
  1164. if (get_type() == type::range_type)
  1165. {
  1166. if (!r.last)
  1167. BOOST_THROW_EXCEPTION(
  1168. empty_exception("back() called on empty utree range"));
  1169. return r.last->val;
  1170. }
  1171. // otherwise...
  1172. if (get_type() != type::list_type)
  1173. BOOST_THROW_EXCEPTION(
  1174. bad_type_exception
  1175. ("back() called on non-list utree type", get_type()));
  1176. else if (!l.last)
  1177. BOOST_THROW_EXCEPTION(
  1178. empty_exception("back() called on empty utree list"));
  1179. return l.last->val;
  1180. }
  1181. inline void utree::swap(utree& other)
  1182. {
  1183. s.swap(other.s);
  1184. }
  1185. inline utree::type::info utree::get_type() const
  1186. {
  1187. // the fast string holds the type info
  1188. return static_cast<utree::type::info>(s.get_type());
  1189. }
  1190. inline void utree::set_type(type::info t)
  1191. {
  1192. // the fast string holds the type info
  1193. s.set_type(t);
  1194. }
  1195. inline void utree::ensure_list_type(char const* failed_in)
  1196. {
  1197. type::info t = get_type();
  1198. if (t == type::invalid_type)
  1199. {
  1200. set_type(type::list_type);
  1201. l.default_construct();
  1202. }
  1203. else if (get_type() != type::list_type)
  1204. {
  1205. std::string msg = failed_in;
  1206. msg += "called on non-list and non-invalid utree type";
  1207. BOOST_THROW_EXCEPTION(bad_type_exception(msg.c_str(), get_type()));
  1208. }
  1209. }
  1210. inline void utree::free()
  1211. {
  1212. switch (get_type())
  1213. {
  1214. case type::binary_type:
  1215. case type::symbol_type:
  1216. case type::string_type:
  1217. s.free();
  1218. break;
  1219. case type::list_type:
  1220. l.free();
  1221. break;
  1222. case type::function_type:
  1223. delete pf;
  1224. break;
  1225. default:
  1226. break;
  1227. };
  1228. s.initialize();
  1229. }
  1230. inline void utree::copy(utree const& other)
  1231. {
  1232. set_type(other.get_type());
  1233. switch (other.get_type())
  1234. {
  1235. default:
  1236. BOOST_THROW_EXCEPTION(
  1237. bad_type_exception("corrupt utree type", other.get_type()));
  1238. break;
  1239. case type::invalid_type:
  1240. case type::nil_type:
  1241. s.tag(other.s.tag());
  1242. break;
  1243. case type::bool_type:
  1244. b = other.b;
  1245. s.tag(other.s.tag());
  1246. break;
  1247. case type::int_type:
  1248. i = other.i;
  1249. s.tag(other.s.tag());
  1250. break;
  1251. case type::double_type:
  1252. d = other.d;
  1253. s.tag(other.s.tag());
  1254. break;
  1255. case type::reference_type:
  1256. p = other.p;
  1257. s.tag(other.s.tag());
  1258. break;
  1259. case type::any_type:
  1260. v = other.v;
  1261. s.tag(other.s.tag());
  1262. break;
  1263. case type::range_type:
  1264. r = other.r;
  1265. s.tag(other.s.tag());
  1266. break;
  1267. case type::string_range_type:
  1268. sr = other.sr;
  1269. s.tag(other.s.tag());
  1270. break;
  1271. case type::function_type:
  1272. pf = other.pf->clone();
  1273. s.tag(other.s.tag());
  1274. break;
  1275. case type::string_type:
  1276. case type::symbol_type:
  1277. case type::binary_type:
  1278. s.copy(other.s);
  1279. s.tag(other.s.tag());
  1280. break;
  1281. case type::list_type:
  1282. l.copy(other.l);
  1283. s.tag(other.s.tag());
  1284. break;
  1285. }
  1286. }
  1287. template <typename T>
  1288. struct is_iterator_range
  1289. : boost::mpl::false_
  1290. {};
  1291. template <typename Iterator>
  1292. struct is_iterator_range<boost::iterator_range<Iterator> >
  1293. : boost::mpl::true_
  1294. {};
  1295. template <typename To>
  1296. struct utree_cast
  1297. {
  1298. typedef To result_type;
  1299. template <typename From>
  1300. To dispatch(From const& val, boost::mpl::true_) const
  1301. {
  1302. return To(val); // From is convertible to To
  1303. }
  1304. template <typename From>
  1305. To dispatch(From const&, boost::mpl::false_) const
  1306. {
  1307. // From is NOT convertible to To !!!
  1308. throw std::bad_cast();
  1309. return To();
  1310. }
  1311. template <typename From>
  1312. To operator()(From const& val) const
  1313. {
  1314. // boost::iterator_range has a templated constructor, accepting
  1315. // any argument and hence any type is 'convertible' to it.
  1316. typedef typename boost::mpl::eval_if<
  1317. is_iterator_range<To>
  1318. , boost::is_same<From, To>, boost::is_convertible<From, To>
  1319. >::type is_convertible;
  1320. return dispatch(val, is_convertible());
  1321. }
  1322. };
  1323. template <typename T>
  1324. struct utree_cast<T*>
  1325. {
  1326. typedef T* result_type;
  1327. template <typename From>
  1328. T* operator()(From const&) const
  1329. {
  1330. // From is NOT convertible to T !!!
  1331. throw std::bad_cast();
  1332. return 0;
  1333. }
  1334. T* operator()(any_ptr const& p) const
  1335. {
  1336. return p.get<T*>();
  1337. }
  1338. };
  1339. template <typename T>
  1340. inline T utree::get() const
  1341. {
  1342. return utree::visit(*this, utree_cast<T>());
  1343. }
  1344. inline utree& utree::deref()
  1345. {
  1346. return (get_type() == type::reference_type) ? *p : *this;
  1347. }
  1348. inline utree const& utree::deref() const
  1349. {
  1350. return (get_type() == type::reference_type) ? *p : *this;
  1351. }
  1352. inline short utree::tag() const
  1353. {
  1354. return s.tag();
  1355. }
  1356. inline void utree::tag(short tag)
  1357. {
  1358. s.tag(tag);
  1359. }
  1360. inline utree utree::eval(utree const& env) const
  1361. {
  1362. if (get_type() == type::reference_type)
  1363. return deref().eval(env);
  1364. if (get_type() != type::function_type)
  1365. BOOST_THROW_EXCEPTION(
  1366. bad_type_exception(
  1367. "eval() called on non-function utree type", get_type()));
  1368. return (*pf)(env);
  1369. }
  1370. inline utree utree::eval(utree& env) const
  1371. {
  1372. if (get_type() == type::reference_type)
  1373. return deref().eval(env);
  1374. if (get_type() != type::function_type)
  1375. BOOST_THROW_EXCEPTION(
  1376. bad_type_exception(
  1377. "eval() called on non-function utree type", get_type()));
  1378. return (*pf)(env);
  1379. }
  1380. inline utree utree::operator() (utree const& env) const
  1381. {
  1382. return eval(env);
  1383. }
  1384. inline utree utree::operator() (utree& env) const
  1385. {
  1386. return eval(env);
  1387. }
  1388. }}
  1389. #if defined(BOOST_MSVC)
  1390. # pragma warning(pop)
  1391. #endif
  1392. #endif