2 CLAW - a C++ Library Absolutely Wonderful
4 CLAW is a free library without any particular aim but being useful to
7 Copyright (C) 2005-2011 Julien Jorge
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 contact: julien.jorge@gamned.org
26 * \file multi_type_map.tpp
27 * \brief Implementation of the claw::multi_type_map class.
28 * \author Julien Jorge
31#include <claw/assert.hpp>
32#include <claw/meta/same_type.hpp>
37 * Here is the implementation of multi_type_map_wrapper for the case where the
38 * ValueType is the first type in the type list of the map.
40 template<typename Key, typename Head, typename Tail>
41 class multi_type_map_wrapper
42 < Head, multi_type_map<Key, meta::type_list<Head, Tail> > >
45 typedef Head value_type;
46 typedef multi_type_map<Key, meta::type_list<Head, Tail> > map_type;
47 typedef typename map_type::iterator_type iterator;
48 typedef typename map_type::const_iterator_type const_iterator;
51 static void erase( map_type& self, iterator it )
53 self.m_data.erase(it);
56 static std::size_t erase( map_type& self, const key_type& k )
58 return self.m_data.erase(k);
61 static const value_type& get( const map_type& self, const key_type& k )
63 CLAW_PRECOND( exists(self, k) );
64 return self.m_data.find(k)->second;
67 static value_type& get( map_type& self, const key_type& k )
69 CLAW_PRECOND( exists(self, k) );
70 return self.m_data.find(k)->second;
73 static void set( map_type& self, const key_type& k, const value_type& v )
78 static bool exists( const map_type& self, const key_type& k )
80 return self.m_data.find(k) != self.m_data.end();
83 static iterator begin( map_type& self )
85 return self.m_data.begin();
88 static iterator end( map_type& self )
90 return self.m_data.end();
93 static const_iterator begin( const map_type& self )
95 return self.m_data.begin();
98 static const_iterator end( const map_type& self )
100 return self.m_data.end();
103 }; // class multi_type_map_wrapper
106 * Here is the implementation of multi_type_map_wrapper for the case where the
107 * ValueType is not the first type in the type list of the map.
109 template<typename ValueType, typename Key, typename Head, typename Tail>
110 class multi_type_map_wrapper
111 < ValueType, multi_type_map< Key, meta::type_list<Head, Tail> > >:
112 public multi_type_map_wrapper< ValueType, multi_type_map<Key, Tail> >
115 }; // class multi_type_map_wrapper
118 * Here is the implementation of multi_type_map_helper for the case where the
119 * ValueType is the first type in the type list of the map.
121 template<typename Key, typename Head, typename Tail>
122 class multi_type_map_helper
123 < multi_type_map<Key, meta::type_list<Head, Tail> > >
125 typedef Key key_type;
126 typedef Head value_type;
127 typedef multi_type_map<Key, meta::type_list<Head, Tail> > map_type;
128 typedef typename map_type::iterator_type iterator;
129 typedef typename map_type::const_iterator_type const_iterator;
132 static void set( map_type& self, const map_type& that )
134 for ( const_iterator it=that.template begin<value_type>();
135 it!=that.template end<value_type>(); ++it )
136 self.template set<Head>( it->first, it->second );
138 multi_type_map_helper< multi_type_map<Key, Tail> >::set( self, that );
141 static std::size_t size( const map_type& self )
143 return self.m_data.size()
144 + multi_type_map_helper< multi_type_map<Key, Tail> >::size( self );
147 }; // class multi_type_map_helper
150 * Here is the implementation of multi_type_map_helper that stops the
153 template<typename Key>
154 class multi_type_map_helper
155 < multi_type_map< Key, claw::meta::no_type > >
158 typedef multi_type_map<Key, claw::meta::no_type> map_type;
161 static void set( map_type& self, const map_type& that )
166 static std::size_t size( const map_type& self )
171 }; // class multi_type_map_helper
177/*----------------------------------------------------------------------------*/
179 * \brief Erase a value from the map.
180 * \param k The key of the value to erase.
181 * \return The number of removed elements (zero or one).
183template<typename Key, typename Head, typename Tail>
184template<typename ValueType>
186claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::erase
187( typename iterator<ValueType>::type it )
189 multi_type_map_wrapper<ValueType, self_type>::erase(*this, it);
190} // multi_type_map::erase()
192/*----------------------------------------------------------------------------*/
194 * \brief Erase a value from the map.
195 * \param k The key of the value to erase.
196 * \return The number of removed elements (zero or one).
198template<typename Key, typename Head, typename Tail>
199template<typename ValueType>
201claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::erase
204 return multi_type_map_wrapper<ValueType, self_type>::erase(*this, k);
205} // multi_type_map::erase()
207/*----------------------------------------------------------------------------*/
209 * \brief Get a value from the map.
210 * \param k The key of the value to get.
212template<typename Key, typename Head, typename Tail>
213template<typename ValueType>
215claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::get
216( const key_type& k ) const
218 return multi_type_map_wrapper<ValueType, self_type>::get(*this, k);
219} // multi_type_map::get()
221/*----------------------------------------------------------------------------*/
223 * \brief Get a value from the map.
224 * \param k The key of the value to get.
226template<typename Key, typename Head, typename Tail>
227template<typename ValueType>
228ValueType& claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::get
231 return multi_type_map_wrapper<ValueType, self_type>::get(*this, k);
232} // multi_type_map::get()
234/*----------------------------------------------------------------------------*/
236 * \brief Set a value in the map.
237 * \param k The key of the value to set.
238 * \param v The value to set.
240template<typename Key, typename Head, typename Tail>
241template<typename ValueType>
242void claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::set
243( const key_type& k, const ValueType& v )
245 return multi_type_map_wrapper<ValueType, self_type>::set(*this, k, v);
246} // multi_type_map::set()
248/*----------------------------------------------------------------------------*/
250 * \brief Set a value in the map.
251 * \param k The key of the value to set.
252 * \param v The value to set.
254template<typename Key, typename Head, typename Tail>
255void claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::set
256( const self_type& m )
258 multi_type_map_helper<self_type>::set(*this, m);
259} // multi_type_map::set()
261/*----------------------------------------------------------------------------*/
263 * \brief Tell if the map contains a value of a given type with a given key.
264 * \param k The key of the value to get.
266template<typename Key, typename Head, typename Tail>
267template<typename ValueType>
268bool claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::exists
269( const key_type& k ) const
271 return multi_type_map_wrapper<ValueType, self_type>::exists(*this, k);
272} // multi_type_map::exists()
274/*----------------------------------------------------------------------------*/
276 * \brief Return the number of elements in the map.
278template<typename Key, typename Head, typename Tail>
280claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::size() const
282 return multi_type_map_helper<self_type>::size(*this);
283} // multi_type_map::size()
285/*----------------------------------------------------------------------------*/
287 * \brief Get an iterator on the beginning of the map for a given type.
289template<typename Key, typename Head, typename Tail>
290template<typename ValueType>
291typename claw::multi_type_map
292< Key, claw::meta::type_list<Head, Tail> >::template iterator<ValueType>::type
293claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::begin()
295 return multi_type_map_wrapper<ValueType, self_type>::begin(*this);
296} // multi_type_map::begin()
298/*----------------------------------------------------------------------------*/
300 * \brief Get an iterator on the end of the map for a given type.
302template<typename Key, typename Head, typename Tail>
303template<typename ValueType>
304typename claw::multi_type_map
305< Key, claw::meta::type_list<Head, Tail> >::template iterator<ValueType>::type
306claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::end()
308 return multi_type_map_wrapper<ValueType, self_type>::end(*this);
309} // multi_type_map::end()
311/*----------------------------------------------------------------------------*/
313 * \brief Get an iterator on the beginning of the map for a given type.
315template<typename Key, typename Head, typename Tail>
316template<typename ValueType>
319< Key, claw::meta::type_list<Head, Tail> >
320::template iterator<ValueType>::const_type
321claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::begin() const
323 return multi_type_map_wrapper<ValueType, self_type>::begin(*this);
324} // multi_type_map::begin()
326/*----------------------------------------------------------------------------*/
328 * \brief Get an iterator on the end of the map for a given type.
330template<typename Key, typename Head, typename Tail>
331template<typename ValueType>
334< Key, claw::meta::type_list<Head, Tail> >
335::template iterator<ValueType>::const_type
336claw::multi_type_map< Key, claw::meta::type_list<Head, Tail> >::end() const
338 return multi_type_map_wrapper<ValueType, self_type>::end(*this);
339} // multi_type_map::end()