123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- ==============================================================================*/
- #if !defined(BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM)
- #define BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #include <boost/spirit/home/qi/string/tst.hpp>
- #include <boost/spirit/home/qi/string/detail/tst.hpp>
- #include <boost/unordered_map.hpp>
- #include <boost/pool/object_pool.hpp>
- namespace boost { namespace spirit { namespace qi
- {
- template <typename Char, typename T>
- struct tst_map
- {
- typedef Char char_type; // the character type
- typedef T value_type; // the value associated with each entry
- typedef detail::tst_node<Char, T> node;
- tst_map()
- {
- }
- ~tst_map()
- {
- // Nothing to do here.
- // The pools do the right thing for us
- }
- tst_map(tst_map const& rhs)
- {
- copy(rhs);
- }
- tst_map& operator=(tst_map const& rhs)
- {
- return assign(rhs);
- }
- template <typename Iterator, typename Filter>
- T* find(Iterator& first, Iterator last, Filter filter) const
- {
- if (first != last)
- {
- Iterator save = first;
- typename map_type::const_iterator
- i = map.find(filter(*first++));
- if (i != map.end())
- {
- if (T* p = node::find(i->second.root, first, last, filter))
- {
- return p;
- }
-
- if (i->second.data)
- {
- return i->second.data;
- }
- }
- first = save;
- }
- return 0;
- }
- template <typename Iterator>
- T* find(Iterator& first, Iterator last) const
- {
- return find(first, last, tst_pass_through());
- }
- template <typename Iterator>
- bool add(
- Iterator first
- , Iterator last
- , typename boost::call_traits<T>::param_type val)
- {
- if (first != last)
- {
- map_data x = {0, 0};
- std::pair<typename map_type::iterator, bool>
- r = map.insert(std::pair<Char, map_data>(*first++, x));
- if (first != last)
- {
- return node::add(r.first->second.root
- , first, last, val, this) ? true : false;
- }
- else
- {
- if (r.first->second.data)
- return false;
- r.first->second.data = this->new_data(val);
- }
- return true;
- }
- return false;
- }
- template <typename Iterator>
- void remove(Iterator first, Iterator last)
- {
- if (first != last)
- {
- typename map_type::iterator i = map.find(*first++);
- if (i != map.end())
- {
- if (first != last)
- {
- node::remove(i->second.root, first, last, this);
- }
- else if (i->second.data)
- {
- this->delete_data(i->second.data);
- i->second.data = 0;
- }
- if (i->second.data == 0 && i->second.root == 0)
- {
- map.erase(i);
- }
- }
- }
- }
- void clear()
- {
- typedef typename map_type::iterator iter_t;
- for (iter_t it = map.begin(), end = map.end(); it != end; ++it)
- {
- node::destruct_node(it->second.root, this);
- if (it->second.data)
- this->delete_data(it->second.data);
- }
- map.clear();
- }
- template <typename F>
- void for_each(F f) const
- {
- typedef typename map_type::const_iterator iter_t;
- for (iter_t it = map.begin(), end = map.end(); it != end; ++it)
- {
- std::basic_string<Char> s(1, it->first);
- node::for_each(it->second.root, s, f);
- if (it->second.data)
- f(s, *it->second.data);
- }
- }
- private:
- friend struct detail::tst_node<Char, T>;
- struct map_data
- {
- node* root;
- T* data;
- };
- typedef unordered_map<Char, map_data> map_type;
- void copy(tst_map const& rhs)
- {
- typedef typename map_type::const_iterator iter_t;
- for (iter_t it = rhs.map.begin(), end = rhs.map.end(); it != end; ++it)
- {
- map_data xx = {node::clone_node(it->second.root, this), 0};
- if (it->second.data)
- xx.data = data_pool.construct(*it->second.data);
- map[it->first] = xx;
- }
- }
- tst_map& assign(tst_map const& rhs)
- {
- if (this != &rhs)
- {
- typedef typename map_type::const_iterator iter_t;
- for (iter_t it = map.begin(), end = map.end(); it != end; ++it)
- {
- node::destruct_node(it->second.root, this);
- }
- map.clear();
- copy(rhs);
- }
- return *this;
- }
- node* new_node(Char id)
- {
- return node_pool.construct(id);
- }
- T* new_data(typename boost::call_traits<T>::param_type val)
- {
- return data_pool.construct(val);
- }
- void delete_node(node* p)
- {
- node_pool.destroy(p);
- }
- void delete_data(T* p)
- {
- data_pool.destroy(p);
- }
- map_type map;
- object_pool<node> node_pool;
- object_pool<T> data_pool;
- };
- }}}
- #endif
|