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