9af5cbfbc2ee45de2490f5cbc0db62bf739b209b
[senf.git] / boost / bimap / bimap.hpp
1 // Boost.Bimap
2 //
3 // Copyright (c) 2006-2007 Matias Capeletto
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8
9 /// \file bimap.hpp
10 /// \brief Includes the basic bimap container
11
12 /** \mainpage notitle
13 \n
14 \image html http://matias.capeletto.googlepages.com/boost.bimap.reference.logo.png
15
16 \section Introduction
17
18 This is the complete reference of Boost.Bimap.
19
20 After getting a good understanding of the library from a user perspective
21 the next step will be:
22
23     - Understand the tagged idiom. (boost::bimaps::tags)
24     - Understand the internals of the relation class (boost::bimaps::relation)
25     - Read the container_adaptor toolbox docs (boost::bimaps::container_adaptor)
26     - Understand the internals of the bimap class. (boost::bimaps, boost::bimaps::views
27       and boost::bimaps::detail)
28
29
30                                                                         **/
31
32 /** \defgroup mutant_group mutant idiom
33 \brief A safe wrapper around reinterpret_cast
34                                                                         **/
35
36 /** \defgroup relation_group relation
37 \brief The relation
38                                                                         **/
39
40 /** \defgroup tags_group tagged idiom
41 \brief The tagged idiom
42                                                                         **/
43
44
45 #ifndef BOOST_BIMAP_BIMAP_HPP
46 #define BOOST_BIMAP_BIMAP_HPP
47
48 #if defined(_MSC_VER) && (_MSC_VER>=1200)
49 #pragma once
50 #endif
51
52 #include <boost/config.hpp>
53 #include <boost/bimap/detail/user_interface_config.hpp>
54 #include <boost/mpl/aux_/na.hpp>
55
56 #define BOOST_BIMAP_DISABLE_SERIALIZATION
57 #define BOOST_MULTI_INDEX_DISABLE_SERIALIZATION
58
59 #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
60     #include <boost/serialization/nvp.hpp>
61 #endif // BOOST_BIMAP_DISABLE_SERIALIZATION
62
63 // Boost.Bimap
64 #include <boost/bimap/detail/bimap_core.hpp>
65 #include <boost/bimap/detail/map_view_base.hpp>
66 #include <boost/bimap/detail/modifier_adaptor.hpp>
67 #include <boost/bimap/relation/support/data_extractor.hpp>
68 #include <boost/bimap/relation/support/member_with_tag.hpp>
69
70 #include <boost/bimap/support/map_type_by.hpp>
71 #include <boost/bimap/support/map_by.hpp>
72 #include <boost/bimap/support/iterator_type_by.hpp>
73
74 /// \brief The namespace where all the boost libraries lives.
75
76 namespace boost {
77
78 /// \brief Boost.Bimap library namespace
79 /**
80 All the entities in the library are defined in this namespace.
81                                                                     **/
82 namespace bimaps {
83
84 /// \brief The bimap class is the entry point to the library.
85 /**
86 This class manages the instantiation of the desired bimap type.
87 As there are several types of bidirectional maps that can be
88 created using it. the main job of it is to find the desired
89 type. This is done using metaprogramming to obtain the relation
90 type that will be stored, the map_view type of each side and
91 the set_view type of the general relationship. The instantiation
92 is kept simple using an extended standard set theory, where a
93 bidirectional map type is defined by the set types it relates.
94 For example, a bidirectional map that has multimap semantics
95 viewed from both sides is defined by specifying that the two
96 keys sets are of \c multiset_of<Key> type.
97 This allows the bimap class to support seamingless N-N, 1-N,
98 ordered/unordered and even vector-list types of mapping.
99 The three last parameters are used to specify the set type of
100 the relation, an inplace hooked data class and the allocator
101 type. As a help to the bimap user, these parameters support
102 default types but use a special idiom that allow them to be
103 specified without interleaving the usual use_default keyword.
104 The possible bimap instantiation are enumerated here:
105 \c {Side}KeyType can be directly a type, this is default to
106 \c set_of<{Side}KeyType>, or can be a \c {SetType}_of<Type>
107 specification. Additionally this two parameters can be tagged
108 to specify others tags instead of the usual \c member_at::{Side}
109 ones.
110
111
112 \code
113
114     typedef bimap
115     <
116         LeftCollectionType, RightCollectionType
117
118         [ , SetTypeOfRelation  ]  // Default to left_based
119         [ , info_hook< Info >  ]  // Default to no info
120         [ , Allocator          ]  // Default to std::allocator<>
121
122     > bm;
123
124 \endcode
125
126                                                                        **/
127
128
129 template
130 <
131     class KeyTypeA, class KeyTypeB,
132     class AP1 = ::boost::mpl::na,
133     class AP2 = ::boost::mpl::na,
134     class AP3 = ::boost::mpl::na
135 >
136 class bimap
137 :
138     // Bimap Core, use mpl magic to find the desired bimap type
139
140     public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>,
141
142     // You can use bimap as a collection of relations
143
144     public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>
145                 ::relation_set,
146
147     // Include extra typedefs (i.e. left_local_iterator for unordered_map)
148
149     public ::boost::bimaps::detail:: left_map_view_extra_typedefs<
150         BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::left_map_view_type<
151             ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>
152         >::type
153     >,
154     public ::boost::bimaps::detail::right_map_view_extra_typedefs< 
155         BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::right_map_view_type<
156             ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>
157         >::type
158     >
159 {
160     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::
161         bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3> base_;
162
163     BOOST_DEDUCED_TYPENAME base_::core_type core;
164
165     public:
166
167     // metadata --------------------------------------------------------
168
169     /*
170     // The rest is computed in the core, because it is quite difficult to
171     // expose a nice interface with so many metaprogramming stuff.
172     // Here it is the complete metadat list.
173
174     // Map by {side} metadata
175
176     typedef -unspecified- {side}_tag;
177     typedef -unspecified- {side}_data_type;
178     typedef -unspecified- {side}_value_type;
179     typedef -unspecified- {side}_key_type;
180     typedef -unspecified- {side}_iterator;
181     typedef -unspecified- {side}_const_iterator;
182
183     ------------------------------------------------------------------*/
184
185     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::
186           left_map_view_type<base_>::type  left_map;
187     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::
188          right_map_view_type<base_>::type right_map;
189
190     typedef BOOST_DEDUCED_TYPENAME
191          left_map::reference        left_reference;
192     typedef BOOST_DEDUCED_TYPENAME
193          left_map::const_reference  left_const_reference;
194
195     typedef BOOST_DEDUCED_TYPENAME
196         right_map::reference       right_reference;
197     typedef BOOST_DEDUCED_TYPENAME
198         right_map::const_reference right_const_reference;
199
200     typedef BOOST_DEDUCED_TYPENAME base_::relation::info_type info_type;
201
202     /// Left map view
203     left_map  left;
204
205     /// Right map view
206     right_map right;
207
208     bimap() :
209
210         base_::relation_set(
211             ::boost::multi_index::get<
212                 BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag 
213             >(core) 
214         ),
215         left (
216             ::boost::multi_index::get<
217                 BOOST_DEDUCED_TYPENAME base_::logic_left_tag
218             >(core)
219         ),
220         right (
221             ::boost::multi_index::get<
222                 BOOST_DEDUCED_TYPENAME base_::logic_right_tag 
223             >(core)
224         )
225
226     {}
227
228     template< class InputIterator >
229     bimap(InputIterator first,InputIterator last) :
230
231         base_::relation_set(
232             ::boost::multi_index::get<
233                 BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag
234             >(core) 
235         ),
236
237         core(first,last),
238
239         left (
240             ::boost::multi_index::get<
241                 BOOST_DEDUCED_TYPENAME base_::logic_left_tag
242             >(core)
243         ),
244         right (
245             ::boost::multi_index::get<
246                 BOOST_DEDUCED_TYPENAME base_::logic_right_tag
247             >(core)
248         )
249
250     {}
251
252     bimap(const bimap& x) :
253
254         base_::relation_set(
255             ::boost::multi_index::get<
256                 BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag
257             >(core) 
258         ),
259
260         core(x.core),
261
262         left (
263             ::boost::multi_index::get<
264                 BOOST_DEDUCED_TYPENAME base_::logic_left_tag
265             >(core)
266         ),
267         right (
268             ::boost::multi_index::get<
269                 BOOST_DEDUCED_TYPENAME base_::logic_right_tag
270             >(core)
271         )
272
273     {}
274
275     bimap& operator=(const bimap& x)
276     {
277         core = x.core;
278         return *this;
279     }
280
281     // Projection of iterators
282
283     template< class IteratorType >
284     BOOST_DEDUCED_TYPENAME base_::left_iterator
285         project_left(IteratorType iter)
286     {
287         return core.template project<
288             BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base());
289     }
290
291     template< class IteratorType >
292     BOOST_DEDUCED_TYPENAME base_::left_const_iterator
293         project_left(IteratorType iter) const
294     {
295         return core.template project<
296             BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base());
297     }
298
299     template< class IteratorType >
300     BOOST_DEDUCED_TYPENAME base_::right_iterator
301         project_right(IteratorType iter)
302     {
303         return core.template project<
304             BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base());
305     }
306
307     template< class IteratorType >
308     BOOST_DEDUCED_TYPENAME base_::right_const_iterator
309         project_right(IteratorType iter) const
310     {
311         return core.template project<
312             BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base());
313     }
314
315     template< class IteratorType >
316     BOOST_DEDUCED_TYPENAME base_::relation_set::iterator
317         project_up(IteratorType iter)
318     {
319         return core.template project<
320             BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base());
321     }
322
323     template< class IteratorType >
324     BOOST_DEDUCED_TYPENAME base_::relation_set::const_iterator
325         project_up(IteratorType iter) const
326     {
327         return core.template project<
328             BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base());
329     }
330
331     // Support for tags
332
333     template< class Tag, class IteratorType >
334     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
335     iterator_type_by<Tag,bimap>::type
336         project(IteratorType iter
337                 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
338     {
339         return core.template project<Tag>(iter.base());
340     }
341
342     template< class Tag, class IteratorType >
343     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
344     const_iterator_type_by<Tag,bimap>::type
345         project(IteratorType iter
346                 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) const
347     {
348         return core.template project<Tag>(iter.base());
349     }
350
351     template< class Tag >
352     struct map_by :
353         public ::boost::bimaps::support::map_type_by<Tag,bimap>::type
354     {
355         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
356             map_type_by<Tag,bimap>::type type;
357
358         private: map_by() {}
359     };
360
361     template< class Tag >
362     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
363     map_type_by<Tag,bimap>::type &
364         by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))
365     {
366         return ::boost::bimaps::support::map_by<Tag>(*this);
367     }
368
369     template< class Tag >
370     const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
371     map_type_by<Tag,bimap>::type &
372         by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) const
373     {
374         return ::boost::bimaps::support::map_by<Tag>(*this);
375     }
376
377
378     #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
379
380     // Serialization support
381
382     private:
383
384     friend class boost::serialization::access;
385
386     template<class Archive>
387     void serialize(Archive & ar, const unsigned int version)
388     {
389         ar & serialization::make_nvp("mi_core",core);
390     }
391
392     #endif // BOOST_BIMAP_DISABLE_SERIALIZATION
393 };
394
395 } // namespace bimaps
396 } // namespace boost
397
398
399 /** \namespace boost::bimaps::support
400 \brief Metafunctions to help working with bimaps.
401                                                             **/
402
403 /** \namespace boost::bimaps::views
404 \brief Bimap views.
405                                                             **/
406
407 /** \namespace boost::bimaps::views::detail
408 \brief Bimap views details.
409                                                             **/
410
411
412
413 // Include basic tools for user commodity
414
415 #include <boost/bimap/tags/tagged.hpp>
416 #include <boost/bimap/relation/member_at.hpp>
417 #include <boost/multi_index/detail/unbounded.hpp>
418
419 // Bring the most used namespaces directly to the user main namespace
420 namespace boost {
421 namespace bimaps {
422
423 using ::boost::bimaps::tags::tagged;
424
425 namespace member_at = ::boost::bimaps::relation::member_at;
426
427 using ::boost::multi_index::unbounded;
428
429 } // namespace bimaps
430 } // namespace boost
431
432
433 #endif // BOOST_BIMAP_BIMAP_HPP