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