File indexing completed on 2025-01-31 10:02:37
0001
0002
0003
0004
0005
0006
0007 #if !defined(BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM)
0008 #define BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM
0009
0010 #include <boost/spirit/home/x3/string/detail/tst.hpp>
0011 #include <unordered_map>
0012 #include <boost/pool/object_pool.hpp>
0013
0014 namespace boost { namespace spirit { namespace x3
0015 {
0016 struct tst_pass_through;
0017
0018 template <typename Char, typename T>
0019 struct tst_map
0020 {
0021 typedef Char char_type;
0022 typedef T value_type;
0023 typedef detail::tst_node<Char, T> node;
0024
0025 tst_map()
0026 {
0027 }
0028
0029 ~tst_map()
0030 {
0031
0032
0033 }
0034
0035 tst_map(tst_map const& rhs)
0036 {
0037 copy(rhs);
0038 }
0039
0040 tst_map& operator=(tst_map const& rhs)
0041 {
0042 return assign(rhs);
0043 }
0044
0045 template <typename Iterator, typename Filter>
0046 T* find(Iterator& first, Iterator last, Filter filter) const
0047 {
0048 if (first != last)
0049 {
0050 Iterator save = first;
0051 typename map_type::const_iterator
0052 i = map.find(filter(*first++));
0053 if (i == map.end())
0054 {
0055 first = save;
0056 return 0;
0057 }
0058 if (T* p = node::find(i->second.root, first, last, filter))
0059 {
0060 return p;
0061 }
0062 return i->second.data;
0063 }
0064 return 0;
0065 }
0066
0067 template <typename Iterator>
0068 T* find(Iterator& first, Iterator last) const
0069 {
0070 return find(first, last, tst_pass_through());
0071 }
0072
0073 template <typename Iterator>
0074 bool add(
0075 Iterator first
0076 , Iterator last
0077 , typename boost::call_traits<T>::param_type val)
0078 {
0079 if (first != last)
0080 {
0081 map_data x = {0, 0};
0082 std::pair<typename map_type::iterator, bool>
0083 r = map.insert(std::pair<Char, map_data>(*first++, x));
0084
0085 if (first != last)
0086 {
0087 return node::add(r.first->second.root
0088 , first, last, val, this) ? true : false;
0089 }
0090 else
0091 {
0092 if (r.first->second.data)
0093 return false;
0094 r.first->second.data = this->new_data(val);
0095 }
0096 return true;
0097 }
0098 return false;
0099 }
0100
0101 template <typename Iterator>
0102 void remove(Iterator first, Iterator last)
0103 {
0104 if (first != last)
0105 {
0106 typename map_type::iterator i = map.find(*first++);
0107 if (i != map.end())
0108 {
0109 if (first != last)
0110 {
0111 node::remove(i->second.root, first, last, this);
0112 }
0113 else if (i->second.data)
0114 {
0115 this->delete_data(i->second.data);
0116 i->second.data = 0;
0117 }
0118 if (i->second.data == 0 && i->second.root == 0)
0119 {
0120 map.erase(i);
0121 }
0122 }
0123 }
0124 }
0125
0126 void clear()
0127 {
0128 for (typename map_type::value_type& x : map)
0129 {
0130 node::destruct_node(x.second.root, this);
0131 if (x.second.data)
0132 this->delete_data(x.second.data);
0133 }
0134 map.clear();
0135 }
0136
0137 template <typename F>
0138 void for_each(F f) const
0139 {
0140 for (typename map_type::value_type const& x : map)
0141 {
0142 std::basic_string<Char> s(1, x.first);
0143 node::for_each(x.second.root, s, f);
0144 if (x.second.data)
0145 f(s, *x.second.data);
0146 }
0147 }
0148
0149 private:
0150
0151 friend struct detail::tst_node<Char, T>;
0152
0153 struct map_data
0154 {
0155 node* root;
0156 T* data;
0157 };
0158
0159 typedef std::unordered_map<Char, map_data> map_type;
0160
0161 void copy(tst_map const& rhs)
0162 {
0163 for (typename map_type::value_type const& x : rhs.map)
0164 {
0165 map_data xx = {node::clone_node(x.second.root, this), 0};
0166 if (x.second.data)
0167 xx.data = data_pool.construct(*x.second.data);
0168 map[x.first] = xx;
0169 }
0170 }
0171
0172 tst_map& assign(tst_map const& rhs)
0173 {
0174 if (this != &rhs)
0175 {
0176 for (typename map_type::value_type& x : map)
0177 {
0178 node::destruct_node(x.second.root, this);
0179 }
0180 map.clear();
0181 copy(rhs);
0182 }
0183 return *this;
0184 }
0185
0186 node* new_node(Char id)
0187 {
0188 return node_pool.construct(id);
0189 }
0190
0191 T* new_data(typename boost::call_traits<T>::param_type val)
0192 {
0193 return data_pool.construct(val);
0194 }
0195
0196 void delete_node(node* p)
0197 {
0198 node_pool.destroy(p);
0199 }
0200
0201 void delete_data(T* p)
0202 {
0203 data_pool.destroy(p);
0204 }
0205
0206 map_type map;
0207 object_pool<node> node_pool;
0208 object_pool<T> data_pool;
0209 };
0210 }}}
0211
0212 #endif