tst_map.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM)
  7. #define BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/qi/string/tst.hpp>
  12. #include <boost/spirit/home/qi/string/detail/tst.hpp>
  13. #include <boost/unordered_map.hpp>
  14. #include <boost/pool/object_pool.hpp>
  15. namespace boost { namespace spirit { namespace qi
  16. {
  17. template <typename Char, typename T>
  18. struct tst_map
  19. {
  20. typedef Char char_type; // the character type
  21. typedef T value_type; // the value associated with each entry
  22. typedef detail::tst_node<Char, T> node;
  23. tst_map()
  24. {
  25. }
  26. ~tst_map()
  27. {
  28. // Nothing to do here.
  29. // The pools do the right thing for us
  30. }
  31. tst_map(tst_map const& rhs)
  32. {
  33. copy(rhs);
  34. }
  35. tst_map& operator=(tst_map const& rhs)
  36. {
  37. return assign(rhs);
  38. }
  39. template <typename Iterator, typename Filter>
  40. T* find(Iterator& first, Iterator last, Filter filter) const
  41. {
  42. if (first != last)
  43. {
  44. Iterator save = first;
  45. typename map_type::const_iterator
  46. i = map.find(filter(*first++));
  47. if (i != map.end())
  48. {
  49. if (T* p = node::find(i->second.root, first, last, filter))
  50. {
  51. return p;
  52. }
  53. if (i->second.data)
  54. {
  55. return i->second.data;
  56. }
  57. }
  58. first = save;
  59. }
  60. return 0;
  61. }
  62. template <typename Iterator>
  63. T* find(Iterator& first, Iterator last) const
  64. {
  65. return find(first, last, tst_pass_through());
  66. }
  67. template <typename Iterator>
  68. bool add(
  69. Iterator first
  70. , Iterator last
  71. , typename boost::call_traits<T>::param_type val)
  72. {
  73. if (first != last)
  74. {
  75. map_data x = {0, 0};
  76. std::pair<typename map_type::iterator, bool>
  77. r = map.insert(std::pair<Char, map_data>(*first++, x));
  78. if (first != last)
  79. {
  80. return node::add(r.first->second.root
  81. , first, last, val, this) ? true : false;
  82. }
  83. else
  84. {
  85. if (r.first->second.data)
  86. return false;
  87. r.first->second.data = this->new_data(val);
  88. }
  89. return true;
  90. }
  91. return false;
  92. }
  93. template <typename Iterator>
  94. void remove(Iterator first, Iterator last)
  95. {
  96. if (first != last)
  97. {
  98. typename map_type::iterator i = map.find(*first++);
  99. if (i != map.end())
  100. {
  101. if (first != last)
  102. {
  103. node::remove(i->second.root, first, last, this);
  104. }
  105. else if (i->second.data)
  106. {
  107. this->delete_data(i->second.data);
  108. i->second.data = 0;
  109. }
  110. if (i->second.data == 0 && i->second.root == 0)
  111. {
  112. map.erase(i);
  113. }
  114. }
  115. }
  116. }
  117. void clear()
  118. {
  119. typedef typename map_type::iterator iter_t;
  120. for (iter_t it = map.begin(), end = map.end(); it != end; ++it)
  121. {
  122. node::destruct_node(it->second.root, this);
  123. if (it->second.data)
  124. this->delete_data(it->second.data);
  125. }
  126. map.clear();
  127. }
  128. template <typename F>
  129. void for_each(F f) const
  130. {
  131. typedef typename map_type::const_iterator iter_t;
  132. for (iter_t it = map.begin(), end = map.end(); it != end; ++it)
  133. {
  134. std::basic_string<Char> s(1, it->first);
  135. node::for_each(it->second.root, s, f);
  136. if (it->second.data)
  137. f(s, *it->second.data);
  138. }
  139. }
  140. private:
  141. friend struct detail::tst_node<Char, T>;
  142. struct map_data
  143. {
  144. node* root;
  145. T* data;
  146. };
  147. typedef unordered_map<Char, map_data> map_type;
  148. void copy(tst_map const& rhs)
  149. {
  150. typedef typename map_type::const_iterator iter_t;
  151. for (iter_t it = rhs.map.begin(), end = rhs.map.end(); it != end; ++it)
  152. {
  153. map_data xx = {node::clone_node(it->second.root, this), 0};
  154. if (it->second.data)
  155. xx.data = data_pool.construct(*it->second.data);
  156. map[it->first] = xx;
  157. }
  158. }
  159. tst_map& assign(tst_map const& rhs)
  160. {
  161. if (this != &rhs)
  162. {
  163. typedef typename map_type::const_iterator iter_t;
  164. for (iter_t it = map.begin(), end = map.end(); it != end; ++it)
  165. {
  166. node::destruct_node(it->second.root, this);
  167. }
  168. map.clear();
  169. copy(rhs);
  170. }
  171. return *this;
  172. }
  173. node* new_node(Char id)
  174. {
  175. return node_pool.construct(id);
  176. }
  177. T* new_data(typename boost::call_traits<T>::param_type val)
  178. {
  179. return data_pool.construct(val);
  180. }
  181. void delete_node(node* p)
  182. {
  183. node_pool.destroy(p);
  184. }
  185. void delete_data(T* p)
  186. {
  187. data_pool.destroy(p);
  188. }
  189. map_type map;
  190. object_pool<node> node_pool;
  191. object_pool<T> data_pool;
  192. };
  193. }}}
  194. #endif