utree_detail2.hpp 42 KB

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