tst_map.hpp 6.0 KB

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