Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:37

0001 /*=============================================================================
0002     Copyright (c) 2001-2014 Joel de Guzman
0003 
0004     Distributed under the Boost Software License, Version 1.0. (See accompanying
0005     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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; // declared in tst.hpp
0017 
0018     template <typename Char, typename T>
0019     struct tst_map
0020     {
0021         typedef Char char_type; // the character type
0022         typedef T value_type; // the value associated with each entry
0023         typedef detail::tst_node<Char, T> node;
0024 
0025         tst_map()
0026         {
0027         }
0028 
0029         ~tst_map()
0030         {
0031             // Nothing to do here.
0032             // The pools do the right thing for us
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