CMSDK 2.0.1
Cross-platform C++ base library and SDK for the Psyclone AIOS platform
Loading...
Searching...
No Matches
bimap.h
Go to the documentation of this file.
1
5/* STL-like bidirectional map.
6 *
7 * (C) 2002-2006 Joaquín M López Muñoz (joaquin@tid.es). All rights reserved.
8 *
9 * Permission is granted to use, distribute and modify this code provided that:
10 * · this copyright notice remain unchanged,
11 * · you submit all changes to the copyright holder and properly mark the
12 * changes so they can be told from the original code,
13 * · credits are given to the copyright holder in the documentation of any
14 * software using this code with the following line:
15 * "Portions copyright 2002-2006 Joaquín M López Muñoz (joaquin@tid.es)"
16 *
17 * The author welcomes any suggestions on the code or reportings of actual
18 * use of the code. Please send your comments to joaquin@tid.es.
19 *
20 * The author makes NO WARRANTY or representation, either express or implied,
21 * with respect to this code, its quality, accuracy, merchantability, or
22 * fitness for a particular purpose. This software is provided "AS IS", and
23 * you, its user, assume the entire risk as to its quality and accuracy.
24 *
25 * Changes in v1.1:
26 *
27 * · bimap::erase(to::iterator,to::iterator) incorrectly returned an
28 * iterator. Documentation was also erroneous about this point.
29 * · Incorrect use of allocator::allocate and allocator::deallocate
30 * was causing much more memory to be used than necessary.
31 * · Improved language conformance with respect to missing typename
32 * and template keywords, faulty friend declarations and broken
33 * implementation of some features of <iterator> in MSVC++.
34 * · allocator::rebind used if compiler supports it.
35 * · Fixed some non-conformances about construction of allocator
36 * and comparison objects in copy contructors.
37 * · The allocator object used to be protected for no good reason:
38 * changed to private as the rest of internal objects.
39 * · Some tweaks to make the thing compile under GNU GCC and Metrowerks
40 * CodeWarrior.
41 * · GCC didn't like a template parameter and a defined type to have
42 * the same name: I don't know if this is actually standard conformant.
43 *
44 * Changes in v1.2:
45 *
46 * · Fixed the code to make it work under MSVC 7.1. Contributed by
47 * Steve Robb.
48 *
49 * Changes in v1.3:
50 *
51 * · Fixed some incorrect (standardwise) friend declarations.
52 * · Sprinkled this-> throughout to cope with two-phase name lookup.
53 *
54 * Last modified: October 26th, 2006
55 */
56
57#ifndef BIMAP_H_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761
58#define BIMAP_H_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761
59#define VERSION_BIMAP_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761 0x00010003
60
61#ifdef _MSC_VER
62#pragma warning(disable:4786)
63#endif
64
65#include <algorithm>
66#include <functional>
67#include <iterator>
68#include <set>
69#include <stddef.h>
70#include <stdexcept>
71#include <utility>
72
73/* offsetof cannot be used on non-POD types (standard 18.1.5) altough bimap
74 * does it in a safe manner. Starting with GCC 3.1, an annoying warning is
75 * issued in this situation. Workarounded it thanks to a tip by Andrew Pollard.
76 */
77
78#if defined(__GNUC__)&&(__GNUC__>3||(__GNUC__==3&&__GNUC_MINOR__>= 1))
79#define BIMAP_OFFSETOF_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761(type,member) \
80(__extension__ \
81 ( \
82 { \
83 type* t=0; \
84 reinterpret_cast<size_t>( \
85 reinterpret_cast<const char*>( \
86 &(t->member) \
87 ) \
88 ); \
89 } \
90 ) \
91)
92#else
93#define BIMAP_OFFSETOF_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761(type,member) offsetof(type,member)
94#endif
95
96/* MSVC++ 6.0 do not support allocator::rebind; in these cases, the only
97 * option is use the original allocator_type unrebound, which VC++ 6.0
98 * accepts merrily nevertheless.
99 */
100
101#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
102#define BIMAP_REBIND_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761(type1,type2) type1
103#else
104#define BIMAP_REBIND_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761(type1,type2) \
105typename type1::template rebind<type2>::other
106#endif
107
108template<class Arg1, class Arg2, class Result>
110{
113 using result_type = Result;
114};
115
116template <typename ArgumentType, typename ResultType>
118{
119 using argument_type = ArgumentType;
120 using result_type = ResultType;
121};
122
123
124namespace codeproject{
125
126namespace bimap_detail{
127
128/* Template helper to check for type equality (save possibly constness.)
129 * Refs:
130 * · Alexandrescu, A.: Modern C++ Design: Generic Programming and Design
131 * Patterns Applied, ch. 2, Addison-Wesley, February 2001.
132 * · Boost, type_traits library, boost::is_same<T,U> template,
133 * April 2001, http://boost.org/libs/type_traits/index.htm.
134 */
135
136typedef char equal_types_yes;
137struct equal_types_no {char m[2];};
139template<typename T>
141template <typename T>
143{
144 static const T* make();
145};
146
147template<typename T,typename U> struct equal_types
148{
149 enum{
152 sizeof(equal_types_yes))};
153};
154
155/* Template stuff to select one or other type based on a compile-time
156 * condition. This can be used to simulate PTS through derivation.
157 * Refs:
158 * · Marcus, M., Jones, J.: "Simulated partial Specialization for C++",
159 * September 2000, http://opensource.adobe.com/project4/project.shtml
160 * · Czarnecki, K., Eisenecker, U.: Generative Programming - Methods, Tools,
161 * and Applications, Addison-Wesley, June 2000.
162 */
163
165{
166 template<class then,class els> struct result
167 {
168 typedef then type;
169 };
170};
171
173{
174 template<class then,class els> struct result
175 {
176 typedef els type;
177 };
178};
179
180template<bool test> struct selector_switch
181{
183};
184
185template<> struct selector_switch<false>
186{
188};
189
190template<bool test,typename then,typename els>
191struct select
192{
194 typedef typename sel::template result<then,els>::type result;
195};
196
197} /* namespace bimap_detail */
198
199/* inv_pair provides the symmetrical counterpart to std::pair necessary for
200 * the to memberspace of bimap. Its layout matches that of std::pair in the
201 * sense that an inv_pair<T,U> can be reinterpret_cast'ed to be an std::pair<U,T>.
202 * To preserve symmetry, std::pair's should provide the corresponding casting
203 * operator to inv_pair. As this is not feasible (predefined classes cannot be
204 * injected this type of operators), a derivation of std::pair called
205 * direct_pair is defined that plays the role of std::pair.
206 */
207
208#if defined(_MSC_VER)&&_MSC_VER>=1300 /* MSVC++ 7.0 */
209#pragma warning(push)
210#pragma warning(disable:4512)
211/* see http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q87638 */
212#endif
213
214template<typename first_type,typename second_type>
215struct direct_pair;
216
217template<typename first_type_,typename second_type_>
219{
220 typedef first_type_ first_type;
221 typedef second_type_ second_type;
222
225
228 inv_pair(const std::pair<first_type,second_type>& r):second(r.second),first(r.first){}
229 template<typename F,typename S>
231
233 {
234 return *reinterpret_cast<direct_pair<second_type,first_type> *>(this);
235 }
236
238 {
239 return *reinterpret_cast<const direct_pair<second_type,first_type> *>(this);
240 }
241};
242
243template<typename first_type,typename second_type>
244struct direct_pair:public std::pair<first_type,second_type>
245{
246private:
247 typedef std::pair<first_type,second_type> super;
248
249public:
250 direct_pair():super(first_type(),second_type()){}
251 direct_pair(const first_type& first,const second_type& second):super(first,second){}
252 direct_pair(const inv_pair<first_type,second_type>& r):super(r.first,r.second){}
253 template<typename F,typename S>
254 direct_pair(const std::pair<F,S>& r):super(r.first,r.second){}
255
257 {
258 return *reinterpret_cast<inv_pair<second_type,first_type> *>(this);
259 }
260
261 operator const inv_pair<second_type,first_type>&()const
262 {
263 return *reinterpret_cast<const inv_pair<second_type,first_type> *>(this);
264 }
265};
266
267#if defined(_MSC_VER)&&_MSC_VER>=1300 /* MSVC++ 7.0 */
268#pragma warning(pop)
269#endif
270
271template<typename first_type,typename second_type>
273 const first_type& first,
274 const second_type& second)
275{
276 return inv_pair<first_type,second_type>(first,second);
277}
278
279/* comparison operators for inv_pair */
280
281/* == */
282
283template<typename first_type,typename second_type>
287{
288 return x.first==y.first&&x.second==y.second;
289}
290
291template<typename first_type,typename second_type>
294 const std::pair<first_type,second_type>& y)
295{
296 return x.first==y.first&&x.second==y.second;
297}
298
299template<typename first_type,typename second_type>
301 const std::pair<first_type,second_type>& x,
303{
304 return x.first==y.first&&x.second==y.second;
305}
306
307/* != */
308
309template<typename first_type,typename second_type>
313{
314 return !(x==y);
315}
316
317template<typename first_type,typename second_type>
320 const std::pair<first_type,second_type>& y)
321{
322 return !(x==y);
323}
324
325template<typename first_type,typename second_type>
327 const std::pair<first_type,second_type>& x,
329{
330 return !(x==y);
331}
332
333/* < */
334
335template<typename first_type,typename second_type>
339{
340 return x.first<y.first||x.first==y.first&&x.second<y.second;
341}
342
343template<typename first_type,typename second_type>
346 const std::pair<first_type,second_type>& y)
347{
348 return x.first<y.first||x.first==y.first&&x.second<y.second;
349}
350
351template<typename first_type,typename second_type>
353 const std::pair<first_type,second_type>& x,
355{
356 return x.first<y.first||x.first==y.first&&x.second<y.second;
357}
358
359/* > */
360
361template<typename first_type,typename second_type>
365{
366 return y<x;
367}
368
369template<typename first_type,typename second_type>
372 const std::pair<first_type,second_type>& y)
373{
374 return y<x;
375}
376
377template<typename first_type,typename second_type>
379 const std::pair<first_type,second_type>& x,
381{
382 return y<x;
383}
384
385/* <= */
386
387template<typename first_type,typename second_type>
391{
392 return !(y<x);
393}
394
395template<typename first_type,typename second_type>
398 const std::pair<first_type,second_type>& y)
399{
400 return !(y<x);
401}
402
403template<typename first_type,typename second_type>
405 const std::pair<first_type,second_type>& x,
407{
408 return !(y<x);
409}
410
411/* >= */
412
413template<typename first_type,typename second_type>
417{
418 return !(x<y);
419}
420
421template<typename first_type,typename second_type>
424 const std::pair<first_type,second_type>& y)
425{
426 return !(x<y);
427}
428
429template<typename first_type,typename second_type>
431 const std::pair<first_type,second_type>& x,
433{
434 return !(x<y);
435}
436
437/* bimap_base is the common base for all bimaps */
438
440{
441 class value_not_found:public std::logic_error
442 {
443 public:
444 value_not_found():logic_error("value not found"){}
445 value_not_found(const std::string& str):logic_error(str){}
446 };
447
448 class duplicate_value:public std::logic_error
449 {
450 public:
451 duplicate_value():logic_error("duplicate value"){}
452 duplicate_value(const std::string& str):logic_error(str){}
453 };
454
455protected:
456 /* from_binding and company implement operator[]s. They're
457 * defined outside from and to memberspaces because
458 * otherwise VC++ chokes and produces an internal compiler
459 * error under some circumstances.
460 */
461
462 template<typename bimap_type>
464 {
465 public:
466 from_binding(bimap_type& bm,const typename bimap_type::from_type& f):bm(bm),f(f){}
467
468 const typename bimap_type::to_type& get()const
469 {
470 typename bimap_type::from_set::const_iterator it=bm.fset.find(&f);
471 if(it==bm.fset.end())throw value_not_found();
472 return bimap_type::element_by_from(*it)->second;
473 }
474
475 operator const typename bimap_type::to_type&()const
476 {
477 return get();
478 }
479
480 from_binding& operator=(const typename bimap_type::to_type& t)
481 {
482 /* MSVC++ chokes if a ctor for typename bimap_type::element
483 * is called directly.
484 */
485
486 typedef typename bimap_type::element bimap_element;
487
488 typename bimap_type::fset_iterator fit=bm.fset.find(&f);
489 typename bimap_type::tset_iterator tit=bm.tset.find(&t);
490 if(tit!=bm.tset.end()){ /* v.second shouldn't be already in */
491 /* small chance the pair (f,t) is already inserted */
492 if(fit!=bm.fset.end()&&
493 bimap_type::element_by_from(*fit)==bimap_type::element_by_to(*tit)){
494 return *this;
495 }
496 else throw duplicate_value();
497 }
498
499 bimap_element * pne=0;
500 typename bimap_type::tset_iterator tnit=bm.tset.end();
501 try{
502 pne=bm.new_element(bimap_element(f,t));
503 tnit=bm.tset.insert(&pne->second).first;
504 if(fit==bm.fset.end()){
505 bm.fset.insert(&pne->first);
506 return *this;
507 }
508 else{ // rebound fit
509 bimap_element * pe=bimap_type::element_by_from(*fit);
510 bm.tset.erase(bm.tset.find(&pe->second));
511 bm.delete_element(pe);
512 const_cast<typename bimap_type::from_type *&>(*fit)=
513 &const_cast<typename bimap_type::from_type &>(pne->first);
514 return *this;
515 }
516 }catch(...){
517 if(tnit!=bm.tset.end())bm.tset.erase(tnit);
518 if(pne)bm.delete_element(pne);
519 throw;
520 }
521 }
522
523 private:
525
526 bimap_type& bm;
527 const typename bimap_type::from_type f;
528 };
529
530 template<typename bimap_type>
532 {
533 public:
534 const_from_binding(const bimap_type& bm,const typename bimap_type::from_type& f):
535 bm(bm),f(f)
536 {}
537
538 const typename bimap_type::to_type& get()const
539 {
540 typename bimap_type::from_set::const_iterator it=bm.fset.find(&f);
541 if(it==bm.fset.end())throw value_not_found();
542 return bimap_type::element_by_from(*it)->second;
543 }
544
545 operator const typename bimap_type::to_type&()const
546 {
547 return get();
548 }
549
550 private:
551 const_from_binding& operator=(const const_from_binding&);
552
553 const bimap_type& bm;
554 const typename bimap_type::from_type f;
555 };
556
557 template<typename bimap_type>
559 {
560 public:
561 to_binding(bimap_type& bm,const typename bimap_type::to_type& t):bm(bm),t(t){}
562
563 const typename bimap_type::from_type& get()const
564 {
565 typename bimap_type::to_set::const_iterator it=bm.tset.find(&t);
566 if(it==bm.tset.end())throw value_not_found();
567 return bimap_type::element_by_to(*it)->first;
568 }
569
570 operator const typename bimap_type::from_type&()const
571 {
572 return get();
573 }
574
575 to_binding& operator=(const typename bimap_type::from_type& f)
576 {
577 /* MSVC++ chokes if a ctor for typename bimap_type::element
578 * is called directly.
579 */
580
581 typedef typename bimap_type::element bimap_element;
582
583 typename bimap_type::tset_iterator tit=bm.tset.find(&t);
584 typename bimap_type::fset_iterator fit=bm.fset.find(&f);
585 if(fit!=bm.fset.end()){ /* v.second shouldn't be already in */
586 /* small chance the pair (f,t) is already inserted */
587 if(tit!=bm.tset.end()&&
588 bimap_type::element_by_to(*tit)==bimap_type::element_by_from(*fit)){
589 return *this;
590 }
591 else throw duplicate_value();
592 }
593
594 bimap_element * pne=0;
595 typename bimap_type::fset_iterator fnit=bm.fset.end();
596 try{
597 pne=bm.new_element(bimap_element(f,t));
598 fnit=bm.fset.insert(&pne->first).first;
599 if(tit==bm.tset.end()){
600 bm.tset.insert(&pne->second);
601 return *this;
602 }
603 else{ // rebound tit
604 bimap_element * pe=bimap_type::element_by_to(*tit);
605 bm.fset.erase(bm.fset.find(&pe->first));
606 bm.delete_element(pe);
607 const_cast<typename bimap_type::to_type *&>(*tit)=
608 &const_cast<typename bimap_type::to_type &>(pne->second);
609 return *this;
610 }
611 }catch(...){
612 if(fnit!=bm.fset.end())bm.fset.erase(fnit);
613 if(pne)bm.delete_element(pne);
614 throw;
615 }
616 }
617
618 private:
620
621 bimap_type& bm;
622 const typename bimap_type::to_type t;
623 };
624
625 template<typename bimap_type>
627 {
628 public:
629 const_to_binding(const bimap_type& bm,const typename bimap_type::to_type& t):
630 bm(bm),t(t)
631 {}
632
633 const typename bimap_type::from_type& get()const
634 {
635 typename bimap_type::to_set::const_iterator it=bm.tset.find(&t);
636 if(it==bm.tset.end())throw value_not_found();
637 return bimap_type::element_by_to(*it)->first;
638 }
639
640 operator const typename bimap_type::from_type&()const
641 {
642 return get();
643 }
644
645 private:
646 const_to_binding& operator=(const const_to_binding&);
647
648 const bimap_type& bm;
649 const typename bimap_type::to_type t;
650 };
651};
652
653/* prebimap holds the entire code for bimap except for the
654 * global memberspace, which is constructed via simulated PTS
655 * in bimap (derived from prebimap).
656 */
657
658template<
659 typename from_type_,typename to_type_,
660 typename from_compare,typename to_compare,
661 typename allocator_type_>
663{
664private:
665 /* Data structure. The bidirectional map is implemented with two sets
666 * fset and tset indexing the corresponding members of elements of type
667 * direct_pair<from_type,to_type>.
668 */
669
670 typedef from_type_ from_type;
671 typedef to_type_ to_type;
672
673 template<typename type,typename compare>
674 struct p_compare /* pointer compare based on value compare */
675 {
676 p_compare(const compare& c=compare()):c(c){}
677 bool operator()(const type* p1,const type* p2)const{return c(*p1,*p2);}
678 compare get_compare()const{return c;}
679 private:
680 compare c;
681 };
682
683 typedef std::set<
684 const from_type*,
685 p_compare<
686 from_type,
687 from_compare>,
688 BIMAP_REBIND_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761(allocator_type_,const from_type*)>
689 from_set;
690 typedef std::set<
691 const to_type*,
692 p_compare<
693 to_type,
694 to_compare>,
695 BIMAP_REBIND_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761(allocator_type_,const to_type*)>
696 to_set;
697 typedef typename from_set::allocator_type fset_allocator_type;
698 typedef typename to_set::allocator_type tset_allocator_type;
699 typedef typename from_set::iterator fset_iterator;
700 typedef typename from_set::const_iterator const_fset_iterator;
701 typedef typename to_set::iterator tset_iterator;
702 typedef typename to_set::const_iterator const_tset_iterator;
703 typedef direct_pair<
704 const from_type,
705 const to_type> element;
706 allocator_type_ allocator;
707 from_set fset;
708 to_set tset;
709
710 /* Basic data management */
711
712 /* new_element and delete_element deal only with allocation/
713 * deallocation of elements, i.e. they do not update fset and tset.
714 */
715
716 element * new_element(const element& e)
717 {
718 element * pe=allocator.allocate(1,0);
719 try{
720 allocator.construct(pe,e);
721 }catch(...){
722 allocator.destroy(pe);
723 throw;
724 }
725 return pe;
726 }
727
728 void delete_element(element *pe)
729 {
730 allocator.destroy(pe);
731 allocator.deallocate(pe,1);
732 }
733
734 static element * element_by_from(const from_type* pf)
735 {
736 return
737 reinterpret_cast<element*>(
738 reinterpret_cast<char*>(
739 const_cast<from_type *>(pf))-
741 }
742
743 static element * element_by_to(const to_type* pt)
744 {
745 return
746 reinterpret_cast<element *>(
747 reinterpret_cast<char*>(
748 const_cast<to_type *>(pt))-
750 }
751
752public:
753 /* memberspace from */
754
756 {
757 public:
758
759 /* assigning a from_impl object is the same as assigning its owner */
760
762 {
763 prebimap tmp(r.owner());
764 swap(tmp.from);
765 return *this;
766 }
767
768 /* Comparison */
769
770 bool operator==(const from_impl& r)const
771 {
772 return size()==r.size()&&std::equal(begin(),end(),r.begin());
773 }
774
775 bool operator!=(const from_impl& r)const
776 {
777 return !(*this==r);
778 }
779
780 bool operator<(const from_impl& r)const
781 {
782 return
783 std::lexicographical_compare(
784 begin(),end(),r.begin(),r.end());
785 }
786
787 bool operator>(const from_impl& r)const
788 {
789 return r<*this;
790 }
791
792 bool operator<=(const from_impl& r)const
793 {
794 return !(r<*this);
795 }
796
797 bool operator>=(const from_impl& r)const
798 {
799 return !(*this<r);
800 }
801
802 /* Standard member types */
803
804 typedef from_type_ key_type;
805 typedef to_type_ mapped_type;
806 typedef to_type_ referent_type; /* prestandard synonim */
807 typedef to_type_ data_type; /* prestandard synonim */
808 typedef from_compare key_compare;
809 typedef allocator_type_ allocator_type;
810 typedef
812 const from_type_,
813 const to_type_> value_type;
814
815 /* value_compare lexicographically orders value_type's. This is
816 * compatible with the weaker value_compare implemented by maps.
817 */
818
819 class value_compare:public std_binary_function<value_type,value_type,bool>
820 {
821 public:
822 bool operator()(const value_type& x,const value_type& y)
823 {
824 if(kcomp(x.first,y.first))return true;
825 if(kcomp(y.first,x.first))return false;
826 return tcomp(x.second,y.second);
827 }
828 protected:
831 to_compare tcomp;
832 };
833
834 typedef typename allocator_type_::size_type size_type;
835 typedef typename allocator_type_::difference_type difference_type;
837 typedef const value_type * const_pointer;
840
841 /* Iterators */
842
843 class const_iterator;
844 class iterator:public std::iterator<std::bidirectional_iterator_tag,const value_type>
845 {
846 friend class from_impl;
847 friend class const_iterator;
848 friend class prebimap<from_type,to_type,from_compare,to_compare,allocator_type>;
849
850#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
851 /* MSVC++ 6.0 fails to define reference in std::iterator */
852
853 typedef const value_type& reference;
854#endif
855
856 public:
858
859#ifdef __MWERKS__
860 /* strange bug */
861
862 typename reference operator*()const{return *element_by_from(*fit);}
863 typename value_type * operator->()const{return &operator*();}
864#else
865 typename iterator::reference operator*()const{return *element_by_from(*fit);}
866 typename iterator::value_type * operator->()const{return &operator*();}
867#endif
868
869 iterator& operator++(){++fit;return *this;}
870 const iterator operator++(int){const iterator tmp=*this;++*this;return tmp;}
871 iterator& operator--(){--fit;return *this;}
872 const iterator operator--(int){const iterator tmp=*this;--*this;return tmp;}
873 bool operator==(const iterator& it)const{return fit==it.fit;}
874 bool operator!=(const iterator& it)const{return !(*this==it);}
875 private:
876 iterator(const fset_iterator& fit):fit(fit){}
877 fset_iterator fit;
878 };
879
880 class const_iterator:public std::iterator<std::bidirectional_iterator_tag,const value_type>
881 {
882 friend class from_impl;
883 friend class prebimap<from_type,to_type,from_compare,to_compare,allocator_type>;
884
885#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
886 /* MSVC++ 6.0 fails to define reference in std::iterator */
887
888 typedef const value_type& reference;
889#endif
890
891 public:
893 const_iterator(const iterator& it):fit(it.fit){}
894
895#ifdef __MWERKS__
896 /* strange bug */
897
898 typename reference operator*()const{return *element_by_from(*fit);}
899 const typename value_type * operator->()const{return &operator*();}
900#else
901 typename const_iterator::reference operator*()const{return *element_by_from(*fit);}
902 const typename const_iterator::value_type * operator->()const{return &operator*();}
903#endif
904
905 const_iterator& operator++(){++fit;return *this;}
906 const const_iterator operator++(int){const const_iterator tmp=*this;++*this;return tmp;}
907 const_iterator& operator--(){--fit;return *this;}
908 const const_iterator operator--(int){const const_iterator tmp=*this;--*this;return tmp;}
909 bool operator==(const const_iterator& it)const{return fit==it.fit;}
910 bool operator!=(const const_iterator& it)const{return !(*this==it);}
911 private:
912 const_iterator(const const_fset_iterator& fit):fit(fit){}
913 const_fset_iterator fit;
914 };
915
916#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
917 typedef
918 std::reverse_bidirectional_iterator<
919 const_iterator,
920 const value_type,
922 const value_type *,
924#else
925 typedef std::reverse_iterator<const_iterator> reverse_iterator;
926#endif
927
929
930 /* Iterator retrieval methods */
931
932 iterator begin(){return iterator(owner().fset.begin());}
933 const_iterator begin()const{return const_iterator(owner().fset.begin());}
934 iterator end(){return iterator(owner().fset.end());}
935 const_iterator end()const{return const_iterator(owner().fset.end());}
936
941
942 /* Utility standard methods */
943
944 size_type size()const{return owner().fset.size();}
945 size_type max_size()const{return owner().fset.max_size();}
946 bool empty()const{return owner().fset.empty();}
947 allocator_type get_allocator()const{return owner().allocator;}
948
949 /* operator []. Uses wrapper classes from_binding and const_from_binding. */
950
958
966
967 /* Insertion and erasing */
968
969 std::pair<iterator,bool> insert(const value_type& x)
970 {
971 fset_iterator fit=owner().fset.find(&x.first);
972 if(fit!=owner().fset.end()){
973 return std::make_pair(iterator(fit),false);
974 }
975 tset_iterator tit=owner().tset.find(&x.second);
976 if(tit!=owner().tset.end())throw duplicate_value();
977
978 element * pe=0;
979 tset_iterator tnit=owner().tset.end();
980 fset_iterator fnit=owner().fset.end();
981 try{
982 pe=owner().new_element(x);
983 tnit=owner().tset.insert(&pe->second).first;
984 fnit=owner().fset.insert(&pe->first).first;
985 }catch(...){
986 if(tnit!=owner().tset.end())owner().tset.erase(tnit);
987 if(pe)owner().delete_element(pe);
988 throw;
989 }
990 return std::make_pair(iterator(fnit),true);
991 }
992
994 {
995 if(!adjacent(it.fit,x.first))return insert(x).first;
996
997 tset_iterator tit=owner().tset.find(&x.second);
998 if(tit!=owner().tset.end())throw duplicate_value();
999
1000 element * pe=0;
1001 tset_iterator tnit=owner().tset.end();
1002 fset_iterator fnit=owner().fset.end();
1003 try{
1004 pe=owner().new_element(x);
1005 tnit=owner().tset.insert(&pe->second).first;
1006 fnit=owner().fset.insert(it.fit,&pe->first);
1007 }catch(...){
1008 if(tnit!=owner().tset.end())owner().tset.erase(tnit);
1009 if(pe)owner().delete_element(pe);
1010 throw;
1011 }
1012 return iterator(fnit);
1013 }
1014
1015 template<typename it_type>
1016 void insert(it_type first,it_type last)
1017 {
1018 while(first!=last){
1019 insert(*first);
1020 ++first;
1021 }
1022 }
1023
1024
1025#ifdef _MSC_VER
1026 /* The standard says the return type for iterator-based erases
1027 * in associative containers is void. Strangely enough, VC++
1028 * implementation returns an iterator. We keep the iterator return
1029 * for the first version of erase.
1030 */
1031
1032 iterator erase(iterator it)
1033 {
1034 fset_iterator& fit=it.fit;
1035 element * pe=element_by_from(*fit);
1036 tset_iterator tit=owner().tset.find(&pe->second);
1037 owner().delete_element(pe);
1038 owner().tset.erase(tit);
1039 return(iterator(owner().fset.erase(fit)));
1040 }
1041#else
1043 {
1044 fset_iterator& fit=it.fit;
1045 element * pe=element_by_from(*fit);
1046 tset_iterator tit=owner().tset.find(&pe->second);
1047 owner().delete_element(pe);
1048 owner().tset.erase(tit);
1049 owner().fset.erase(fit);
1050 }
1051#endif
1052
1053 void erase(iterator first,iterator last)
1054 {
1055 while(first!=last)erase(first++);
1056 }
1057
1059 {
1060 fset_iterator fit=owner().fset.find(&key);
1061 if(fit==owner().fset.end())return 0;
1062 element * pe=element_by_from(*fit);
1063 owner().tset.erase(owner().tset.find(&pe->second));
1064 owner().fset.erase(fit);
1065 owner().delete_element(pe);
1066 return 1;
1067 }
1068
1069 void clear()
1070 {
1071 erase(begin(),end());
1072 }
1073
1075 {
1076 /* assumes allocator equivalence */
1077
1078 owner().fset.swap(x.owner().fset);
1079 owner().tset.swap(x.owner().tset);
1080 }
1081
1082 /* Search methods */
1083
1085 {
1086 return owner().fset.key_comp().get_compare();
1087 }
1088
1090 {
1091 return
1093 owner().fset.key_comp().get_compare(),
1094 owner().tset.key_comp().get_compare());
1095 }
1096
1098 {
1099 return iterator(owner().fset.find(&key));
1100 }
1101
1103 {
1104 return const_iterator(owner().fset.find(&key));
1105 }
1106
1107 size_type count(const key_type& key)const
1108 {
1109 return owner().fset.count(&key);
1110 }
1111
1113 {
1114 return iterator(owner().fset.lower_bound(&key));
1115 }
1116
1118 {
1119 return const_iterator(owner().fset.lower_bound(&key));
1120 }
1121
1123 {
1124 return iterator(owner().fset.upper_bound(&key));
1125 }
1126
1128 {
1129 return const_iterator(owner().fset.upper_bound(&key));
1130 }
1131
1132 std::pair<iterator,iterator> equal_range(const key_type& key)
1133 {
1134 return std::make_pair(lower_bound(key),upper_bound(key));
1135 }
1136
1137 std::pair<const_iterator,const_iterator> equal_range(const key_type& key)const
1138 {
1139 return std::make_pair(lower_bound(key),upper_bound(key));
1140 }
1141
1142 protected:
1145
1147 {
1148 return *reinterpret_cast<prebimap*>(
1149 reinterpret_cast<char*>(this)-
1151 };
1152 const prebimap& owner()const
1153 {
1154 return *reinterpret_cast<const prebimap*>(
1155 reinterpret_cast<const char*>(this)-
1157 };
1158
1159 bool adjacent(const_fset_iterator fit,const from_type_& f)const
1160 {
1161 if(fit==owner().fset.end()){
1162 if(owner().fset.size()==0)return true;
1163 const_fset_iterator fit2=fit;
1164 --fit2;
1165 return owner().fset.key_comp()(*fit2,&f);
1166 }
1167 else if(owner().fset.key_comp()(&f,*fit)){
1168 if(fit==owner().fset.begin())return true;
1169 const_fset_iterator fit2=fit;
1170 --fit2;
1171 return owner().fset.key_comp()(*fit2,&f);
1172
1173 }
1174 else if(owner().fset.key_comp()(*fit,&f)){
1175 const_fset_iterator fit2=fit;
1176 ++fit2;
1177 if(fit2==owner().fset.end())return true;
1178 return owner().fset.key_comp()(&f,*fit2);
1179 }
1180 else return false;
1181 }
1182 };
1183
1184 friend class from_impl;
1185
1186 class from:public from_impl
1187 {
1188 friend class prebimap<from_type_,to_type_,from_compare,to_compare,allocator_type_>;
1189
1190 public:
1191 friend void swap(from& x,from& y)
1192 {
1193 x.swap(y);
1194 }
1195 }from; /* from memberspace */
1196
1197#ifdef __MWERKS__
1198 /* strange bug */
1199
1200 friend class from_impl::iterator;
1201 friend class from_impl::const_iterator;
1202#elif defined(_MSC_VER)
1203 friend typename from::iterator;
1204 friend typename from::const_iterator;
1205#endif
1206
1207 friend class from_binding<prebimap>;
1208 friend class const_from_binding<prebimap>;
1209
1210 /* memberspace to, symetrical to from */
1211
1213 {
1214 public:
1215
1217 {
1218 prebimap tmp(r.owner());
1219 swap(tmp.to);
1220 return *this;
1221 }
1222
1223 /* Comparison */
1224
1225 bool operator==(const to_impl& r)const
1226 {
1227 return size()==r.size()&&std::equal(begin(),end(),r.begin());
1228 }
1229
1230 bool operator!=(const to_impl& r)const
1231 {
1232 return !(*this==r);
1233 }
1234
1235 bool operator<(const to_impl& r)const
1236 {
1237 return
1238 std::lexicographical_compare(
1239 begin(),end(),r.begin(),r.end());
1240 }
1241
1242 bool operator>(const to_impl& r)const
1243 {
1244 return r<*this;
1245 }
1246
1247 bool operator<=(const to_impl& r)const
1248 {
1249 return !(r<*this);
1250 }
1251
1252 bool operator>=(const to_impl& r)const
1253 {
1254 return !(*this<r);
1255 }
1256
1257 /* Standard member types */
1258
1259 typedef to_type_ key_type;
1260 typedef from_type_ mapped_type;
1261 typedef from_type_ referent_type; /* prestandard synonim */
1262 typedef from_type_ data_type; /* prestandard synonim */
1263 typedef to_compare key_compare;
1264 typedef allocator_type_ allocator_type;
1265 typedef
1266 inv_pair<
1267 const to_type_,
1268 const from_type_> value_type;
1269
1270 class value_compare:public std_binary_function<value_type,value_type,bool>
1271 {
1272 public:
1273 bool operator()(const value_type& x,const value_type& y)
1274 {
1275 if(kcomp(x.first,y.first))return true;
1276 if(kcomp(y.first,x.first))return false;
1277 return fcomp(x.second,y.second);
1278 }
1279 protected:
1282 from_compare fcomp;
1283 };
1284
1285 typedef typename allocator_type_::size_type size_type;
1286 typedef typename allocator_type_::difference_type difference_type;
1288 typedef const value_type * const_pointer;
1291
1292 /* Iterators */
1293
1294 class const_iterator;
1295 class iterator:public std::iterator<std::bidirectional_iterator_tag,const value_type>
1296 {
1297 friend class to_impl;
1298 friend class const_iterator;
1299 friend class prebimap<from_type,to_type,from_compare,to_compare,allocator_type>;
1300
1301#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
1302 /* MSVC++ 6.0 fails to define reference in std::iterator */
1303
1304 typedef const value_type& reference;
1305#endif
1306 public:
1308
1309#ifdef __MWERKS__
1310 /* strange bug */
1311
1312 typename reference operator*()const{return *element_by_to(*tit);}
1313 typename value_type * operator->()const{return &operator*();}
1314#else
1315 typename iterator::reference operator*()const{return *element_by_to(*tit);}
1316 typename iterator::value_type * operator->()const{return &operator*();}
1317#endif
1318
1319 iterator& operator++(){++tit;return *this;}
1320 const iterator operator++(int){const iterator tmp=*this;++*this;return tmp;}
1321 iterator& operator--(){--tit;return *this;}
1322 const iterator operator--(int){const iterator tmp=*this;--*this;return tmp;}
1323 bool operator==(const iterator& it)const{return tit==it.tit;}
1324 bool operator!=(const iterator& it)const{return !(*this==it);}
1325 private:
1326 iterator(const tset_iterator& tit):tit(tit){}
1327 tset_iterator tit;
1328 };
1329
1330 class const_iterator:public std::iterator<std::bidirectional_iterator_tag,const value_type>
1331 {
1332 friend class to_impl;
1333 friend class prebimap<from_type,to_type,from_compare,to_compare,allocator_type>;
1334
1335#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
1336 /* MSVC++ 6.0 fails to define reference in std::iterator */
1337
1338 typedef const value_type& reference;
1339#endif
1340
1341 public:
1343 const_iterator(const iterator& it):tit(it.tit){}
1344
1345#ifdef __MWERKS__
1346 /* strange bug */
1347
1348 typename reference operator*()const{return *element_by_to(*tit);}
1349 const typename value_type * operator->()const{return &operator*();}
1350#else
1351 typename const_iterator::reference operator*()const{return *element_by_to(*tit);}
1352 const typename const_iterator::value_type * operator->()const{return &operator*();}
1353#endif
1354
1355 const_iterator& operator++(){++tit;return *this;}
1356 const const_iterator operator++(int){const const_iterator tmp=*this;++*this;return tmp;}
1357 const_iterator& operator--(){--tit;return *this;}
1358 const const_iterator operator--(int){const const_iterator tmp=*this;--*this;return tmp;}
1359 bool operator==(const const_iterator& it)const{return tit==it.tit;}
1360 bool operator!=(const const_iterator& it)const{return !(*this==it);}
1361 private:
1362 const_iterator(const const_tset_iterator& tit):tit(tit){}
1363 const_tset_iterator tit;
1364 };
1365
1366#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
1367 typedef
1368 std::reverse_bidirectional_iterator<
1369 const_iterator,
1370 const value_type,
1372 const value_type *,
1374#else
1375 typedef std::reverse_iterator<const_iterator> reverse_iterator;
1376#endif
1377
1379
1380 /* Iterator retrieval methods */
1381
1382 iterator begin(){return iterator(owner().tset.begin());}
1383 const_iterator begin()const{return const_iterator(owner().tset.begin());}
1384 iterator end(){return iterator(owner().tset.end());}
1385 const_iterator end()const{return const_iterator(owner().tset.end());}
1386
1391
1392 /* Utility standard methods */
1393
1394 size_type size()const{return owner().tset.size();}
1395 size_type max_size()const{return owner().tset.max_size();}
1396 bool empty()const{return owner().tset.empty();}
1397 allocator_type get_allocator()const{return owner().allocator;}
1398
1399 /* operator []. Uses wrapper classes to_binding and const_to_binding. */
1400
1402 operator[](const to_type_& t)
1403 {
1404 return
1406 (owner(),t);
1407 }
1408
1410 operator[](const to_type_& t)const
1411 {
1412 return
1414 (owner(),t);
1415 }
1416
1417 /* Insertion and erasing */
1418
1419 std::pair<iterator,bool> insert(const value_type& x)
1420 {
1421 tset_iterator tit=owner().tset.find(&x.first);
1422 if(tit!=owner().tset.end()){
1423 return std::make_pair(iterator(tit),false);
1424 }
1425 fset_iterator fit=owner().fset.find(&x.second);
1426 if(fit!=owner().fset.end())throw duplicate_value();
1427
1428 element * pe=0;
1429 fset_iterator fnit=owner().fset.end();
1430 tset_iterator tnit=owner().tset.end();
1431 try{
1432 pe=owner().new_element(x);
1433 fnit=owner().fset.insert(&pe->first).first;
1434 tnit=owner().tset.insert(&pe->second).first;
1435 }catch(...){
1436 if(fnit!=owner().fset.end())owner().fset.erase(fnit);
1437 if(pe)owner().delete_element(pe);
1438 throw;
1439 }
1440 return std::make_pair(iterator(tnit),true);
1441 }
1442
1444 {
1445 if(!adjacent(it.tit,x.first))return insert(x).first;
1446
1447 fset_iterator fit=owner().fset.find(&x.second);
1448 if(fit!=owner().fset.end())throw duplicate_value();
1449
1450 element * pe=0;
1451 fset_iterator fnit=owner().fset.end();
1452 tset_iterator tnit=owner().tset.end();
1453 try{
1454 pe=owner().new_element(x);
1455 fnit=owner().fset.insert(&pe->first).first;
1456 tnit=owner().tset.insert(it.tit,&pe->second);
1457 }catch(...){
1458 if(fnit!=owner().fset.end())owner().fset.erase(fnit);
1459 if(pe)owner().delete_element(pe);
1460 throw;
1461 }
1462 return iterator(tnit);
1463 }
1464
1465 template<typename it_type>
1466 void insert(it_type first,it_type last)
1467 {
1468 while(first!=last){
1469 insert(*first);
1470 ++first;
1471 }
1472 }
1473
1474
1475#ifdef _MSC_VER
1476 /* see note in from::erase */
1477
1478 iterator erase(iterator it)
1479 {
1480 tset_iterator& tit=it.tit;
1481 element * pe=element_by_to(*tit);
1482 fset_iterator fit=owner().fset.find(&pe->first);
1483 owner().delete_element(pe);
1484 owner().fset.erase(fit);
1485 return(iterator(owner().tset.erase(tit)));
1486 }
1487#else
1489 {
1490 tset_iterator& tit=it.tit;
1491 element * pe=element_by_to(*tit);
1492 fset_iterator fit=owner().fset.find(&pe->first);
1493 owner().delete_element(pe);
1494 owner().fset.erase(fit);
1495 owner().tset.erase(tit);
1496 }
1497#endif
1498
1499 void erase(iterator first,iterator last)
1500 {
1501 while(first!=last)erase(first++);
1502 }
1503
1505 {
1506 tset_iterator tit=owner().tset.find(&key);
1507 if(tit==owner().tset.end())return 0;
1508 element * pe=element_by_to(*tit);
1509 owner().fset.erase(owner().fset.find(&pe->first));
1510 owner().tset.erase(tit);
1511 owner().delete_element(pe);
1512 return 1;
1513 }
1514
1515 void clear()
1516 {
1517 erase(begin(),end());
1518 }
1519
1520 void swap(to_impl& x)
1521 {
1522 /* assumes allocator equivalence */
1523
1524 owner().tset.swap(x.owner().tset);
1525 owner().fset.swap(x.owner().fset);
1526 }
1527
1528 /* Search methods */
1529
1531 {
1532 return owner().tset.key_comp().get_compare();
1533 }
1534
1536 {
1537 return
1539 owner().tset.key_comp().get_compare(),
1540 owner().fset.key_comp().get_compare());
1541 }
1542
1544 {
1545 return iterator(owner().tset.find(&key));
1546 }
1547
1549 {
1550 return const_iterator(owner().tset.find(&key));
1551 }
1552
1553 size_type count(const key_type& key)const
1554 {
1555 return owner().tset.count(&key);
1556 }
1557
1559 {
1560 return iterator(owner().tset.lower_bound(&key));
1561 }
1562
1564 {
1565 return const_iterator(owner().tset.lower_bound(&key));
1566 }
1567
1569 {
1570 return iterator(owner().tset.upper_bound(&key));
1571 }
1572
1574 {
1575 return const_iterator(owner().tset.upper_bound(&key));
1576 }
1577
1578 std::pair<iterator,iterator> equal_range(const key_type& key)
1579 {
1580 return std::make_pair(lower_bound(key),upper_bound(key));
1581 }
1582
1583 std::pair<const_iterator,const_iterator> equal_range(const key_type& key)const
1584 {
1585 return std::make_pair(lower_bound(key),upper_bound(key));
1586 }
1587
1588 protected:
1591
1593 {
1594 return *reinterpret_cast<prebimap*>(
1595 reinterpret_cast<char*>(this)-
1597 };
1598 const prebimap& owner()const
1599 {
1600 return *reinterpret_cast<const prebimap*>(
1601 reinterpret_cast<const char*>(this)-
1603 };
1604
1605 bool adjacent(const_tset_iterator tit,const to_type_& t)const
1606 {
1607 if(tit==owner().tset.end()){
1608 if(owner().tset.size()==0)return true;
1609 const_tset_iterator tit2=tit;
1610 --tit2;
1611 return owner().tset.key_comp()(*tit2,&t);
1612 }
1613 else if(owner().tset.key_comp()(&t,*tit)){
1614 if(tit==owner().tset.begin())return true;
1615 const_tset_iterator tit2=tit;
1616 --tit2;
1617 return owner().tset.key_comp()(*tit2,&t);
1618
1619 }
1620 else if(owner().tset.key_comp()(*tit,&t)){
1621 const_tset_iterator tit2=tit;
1622 ++tit2;
1623 if(tit2==owner().tset.end())return true;
1624 return owner().tset.key_comp()(&t,*tit2);
1625 }
1626 else return false;
1627 }
1628 };
1629
1630 friend class to_impl;
1631
1632 class to:public to_impl
1633 {
1634 friend class prebimap<from_type_,to_type_,from_compare,to_compare,allocator_type_>;
1635
1636 public:
1637 friend void swap(to& x,to& y)
1638 {
1639 x.swap(y);
1640 }
1641 }to; /* to memberspace */
1642
1643#ifdef __MWERKS__
1644 /* strange bug */
1645
1646 friend class to_impl::iterator;
1647 friend class to_impl::const_iterator;
1648#elif defined(_MSC_VER)
1649 friend typename to::iterator;
1650 friend typename to::const_iterator;
1651#endif
1652
1653 friend class to_binding<prebimap>;
1654 friend class const_to_binding<prebimap>;
1655
1656 /* Double-hint insertion. This does not naturally belong into any
1657 * memberspace.
1658 */
1659
1660 std::pair<typename from_impl::iterator,typename to_impl::iterator>
1662 typename from_impl::iterator fit,typename to_impl::iterator tit,
1663 const typename from_impl::value_type& x)
1664 {
1665 typedef typename from_impl::iterator from_iterator;
1666 typedef typename to_impl::iterator to_iterator;
1667
1668 if(!from.adjacent(fit.fit,x.first)){
1669 fit=fset.find(&x.first);
1670 if(fit!=fset.end()){ /* small chance x is already inserted */
1671 tset_iterator tnit=tset.find(&x.second);
1672 if(tnit!=tset.end()&&element_by_from(*(fit.fit))==element_by_to(*tnit)){
1673 return std::make_pair(fit,to_iterator(tnit));
1674 }
1675 else throw duplicate_value();
1676 }
1677 }
1678
1679 if(!to.adjacent(tit.tit,x.second)){
1680 tit=tset.find(&x.second);
1681 if(tit!=tset.end()) throw duplicate_value();
1682 /* no need to check for x being inserted (already done above) */
1683 }
1684
1685 element * pe=0;
1686 tset_iterator tnit=tset.begin();
1687 fset_iterator fnit=fset.begin();
1688 try{
1689 pe=new_element(x);
1690 tnit=tset.insert(tit.tit,&pe->second);
1691 fnit=fset.insert(fit.fit,&pe->first);
1692 }catch(...){
1693 if(tnit!=tset.end())tset.erase(tnit);
1694 if(pe)delete_element(pe);
1695 throw;
1696 }
1697 return std::make_pair(from_iterator(fnit),to_iterator(tnit));
1698 }
1699
1700protected:
1702 const from_compare& from_comp,
1703 const to_compare& to_comp,
1704 const allocator_type_& al):
1705 allocator(al),
1706 fset(p_compare<from_type,from_compare>(from_comp),fset_allocator_type(allocator)),
1707 tset(p_compare<to_type,to_compare>(to_comp),tset_allocator_type(allocator))
1708 {}
1709
1711 allocator(r.allocator),
1712 fset(r.fset.key_comp(),fset_allocator_type(allocator)),
1713 tset(r.tset.key_comp(),tset_allocator_type(allocator))
1714 {
1715 try{
1716
1717#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
1718/* Amortized constant insertion in VC++ 6.0 happens if hint iterator is
1719 * right *after* the insertion point, in disagreement with the standard.
1720 */
1721
1722 typename from::iterator fhint=from.end();
1723 typename to::iterator thint=to.end();
1724 for(typename from::const_iterator it=r.from.begin();it!=r.from.end();++it){
1725 insert(fhint,thint,*it);
1726 }
1727#else
1728 typename from_impl::iterator fhint=from.end();
1729 typename to_impl::iterator thint=to.end();
1730 for(typename from_impl::const_iterator it=r.from.begin();it!=r.from.end();++it){
1731 std::pair<typename from_impl::iterator,typename to_impl::iterator>
1732 p=insert(fhint,thint,*it);
1733 fhint=p.first;
1734 thint=p.second;
1735 }
1736#endif
1737
1738 }catch(...){
1739 from.clear();
1740 throw;
1741 }
1742 }
1743
1745 {
1746 for(fset_iterator it=fset.begin();it!=fset.end();++it){
1747 delete_element(element_by_from(*it));
1748 }
1749 }
1750};
1751
1752#ifdef __GNUC__
1753/* GCC chokes when trying to derive from a template class with memberspaces.
1754 * See http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9159
1755 * for details. prebimap_identity is nothing but compiler sugar to workaround
1756 * the problem.
1757 */
1758
1759template<
1760 typename from_type,typename to_type,
1761 typename from_compare,typename to_compare,
1762 typename allocator_type>
1763struct prebimap_identity
1764{
1765 typedef prebimap<from_type,to_type,from_compare,to_compare,allocator_type> type;
1766};
1767#endif
1768
1769/* When from_type and to_type are equal, we promote only the from memberspace
1770 * to the global memberspace ans members of the to space posing no ambiguity.
1771 */
1772template<
1773 typename from_type_,typename to_type_,
1774 typename from_compare,typename to_compare,
1775 typename allocator_type_>
1777
1778#ifdef __GNUC__
1779 public prebimap_identity<from_type_,to_type_,from_compare,to_compare,allocator_type_>::type
1780#else
1781 public prebimap<from_type_,to_type_,from_compare,to_compare,allocator_type_>
1782#endif
1783
1784{
1785 typedef
1787 typedef typename super::template from_binding<super> from_binding_t;
1788 typedef typename super::template const_from_binding<super> const_from_binding_t;
1789 typedef typename super::to::value_type to_value_type;
1790 typedef typename super::to::iterator to_iterator;
1791
1792public:
1793 typedef typename super::from::key_type key_type;
1794 typedef typename super::from::mapped_type mapped_type;
1795 typedef typename super::from::referent_type referent_type;
1796 typedef typename super::from::data_type data_type;
1797 typedef typename super::from::key_compare key_compare;
1798 typedef typename super::from::allocator_type allocator_type;
1799 typedef typename super::from::value_type value_type;
1800 typedef typename super::from::value_compare value_compare;
1801 typedef typename super::from::size_type size_type;
1802 typedef typename super::from::difference_type difference_type;
1803 typedef typename super::from::pointer pointer;
1804 typedef typename super::from::const_pointer const_pointer;
1805 typedef typename super::from::reference reference;
1806 typedef typename super::from::const_reference const_reference;
1807 typedef typename super::from::iterator iterator;
1808 typedef typename super::from::const_iterator const_iterator;
1809 typedef typename super::from::reverse_iterator reverse_iterator;
1810 typedef typename super::from::const_reverse_iterator const_reverse_iterator;
1811
1812 iterator begin(){return this->from.begin();}
1813 const_iterator begin()const{return this->from.begin();}
1814 iterator end(){return this->from.end();}
1815 const_iterator end()const{return this->from.end();}
1818 reverse_iterator rend(){return this->from.rend();}
1819 const_reverse_iterator rend()const{return this->from.rend();}
1820 size_type size()const{return this->from.size();}
1821 size_type max_size()const{return this->from.max_size();}
1822 bool empty()const{return this->from.empty();}
1824 from_binding_t operator[](const key_type& key){return this->from[key];}
1825 const_from_binding_t operator[](const key_type& key)const{return this->from[key];}
1826 using super::insert;
1827 std::pair<iterator,bool> insert(const value_type& x){return this->from.insert(x);}
1828 iterator insert(iterator it,const value_type& x){return this->from.insert(it,x);}
1829 template<
1830 typename it_type>
1831 void insert(it_type first,it_type last){this->from.insert(first,last);}
1832
1833#ifdef _MSC_VER /* see note in from::erase */
1834 iterator erase(iterator it){return this->from.erase(it);}
1835#else
1836 void erase(iterator it){this->from.erase(it);}
1837#endif
1838
1839 void erase(iterator first,iterator last){this->from.erase(first,last);}
1840 size_type erase(const key_type& key){return this->from.erase(key);}
1841 void clear(){this->from.clear();}
1844 key_compare key_comp()const{return this->from.key_comp();}
1845 value_compare value_comp()const{return this->from.value_comp();}
1846 iterator find(const key_type& key){return this->from.find(key);}
1847 const_iterator find(const key_type& key)const{return this->from.find(key);}
1848 size_type count(const key_type& key)const{return this->from.count(key);}
1849 iterator lower_bound(const key_type& key){return this->from.lower_bound(key);}
1850 const_iterator lower_bound(const key_type& key)const{return this->from.lower_bound(key);}
1851 iterator upper_bound(const key_type& key){return this->from.upper_bound(key);}
1852 const_iterator upper_bound(const key_type& key)const{return this->from.upper_bound(key);}
1853 std::pair<
1854 iterator,
1855 iterator> equal_range(const key_type& key){return this->from.equal_range(key);}
1856 std::pair<
1858 const_iterator> equal_range(const key_type& key)const{return this->from.equal_range(key);}
1859
1860 /* Promotion of unambiguous parts of the to memberspace */
1861
1862 std::pair<
1863 to_iterator,
1864 bool> insert(const to_value_type& x){return this->to.insert(x);}
1865 to_iterator insert(to_iterator it,const to_value_type& x){return this->to.insert(it,x);}
1866 void insert(const to_value_type *first,const to_value_type *last)
1867 {this->to.insert(first,last);}
1868
1869#ifdef _MSC_VER /* see note in from::erase */
1870 to_iterator erase(to_iterator it){return this->to.erase(it);}
1871#else
1872 void erase(to_iterator it){this->to.erase(it);}
1873#endif
1874
1875 void erase(to_iterator first,to_iterator last){this->to.erase(first,last);}
1876
1877protected:
1879 const from_compare& from_comp,
1880 const to_compare& to_comp,
1881 const allocator_type_& al):
1882 super(from_comp,to_comp,al)
1883 {
1884 }
1885
1886 /* default copy ctor serves well */
1887};
1888
1889/* If from_type and to_type are distinct, some more members of the to
1890 * memberspace can be promoted to the global memberspace without
1891 * ambiguity (notably operator[]).
1892 */
1893template<
1894 typename from_type_,typename to_type_,
1895 typename from_compare,typename to_compare,
1896 typename allocator_type_>
1898
1899#ifdef __GNUC__
1900 public prebimap_identity<from_type_,to_type_,from_compare,to_compare,allocator_type_>::type
1901#else
1902 public prebimap<from_type_,to_type_,from_compare,to_compare,allocator_type_>
1903#endif
1904
1905{
1906 typedef
1908 typedef typename super::template from_binding<super> from_binding_t;
1909 typedef typename super::template const_from_binding<super> const_from_binding_t;
1910 typedef typename super::template to_binding<super> to_binding_t;
1911 typedef typename super::template const_to_binding<super> const_to_binding_t;
1912 typedef typename super::to::key_type to_key_type;
1913 typedef typename super::to::value_type to_value_type;
1914 typedef typename super::to::iterator to_iterator;
1915 typedef typename super::to::const_iterator const_to_iterator;
1916
1917public:
1918 typedef typename super::from::key_type key_type;
1919 typedef typename super::from::mapped_type mapped_type;
1920 typedef typename super::from::referent_type referent_type;
1921 typedef typename super::from::data_type data_type;
1922 typedef typename super::from::key_compare key_compare;
1923 typedef typename super::from::allocator_type allocator_type;
1924 typedef typename super::from::value_type value_type;
1925 typedef typename super::from::value_compare value_compare;
1926 typedef typename super::from::size_type size_type;
1927 typedef typename super::from::difference_type difference_type;
1928 typedef typename super::from::pointer pointer;
1929 typedef typename super::from::const_pointer const_pointer;
1930 typedef typename super::from::reference reference;
1931 typedef typename super::from::const_reference const_reference;
1932 typedef typename super::from::iterator iterator;
1933 typedef typename super::from::const_iterator const_iterator;
1934 typedef typename super::from::reverse_iterator reverse_iterator;
1935 typedef typename super::from::const_reverse_iterator const_reverse_iterator;
1936
1937 iterator begin(){return this->from.begin();}
1938 const_iterator begin()const{return this->from.begin();}
1939 iterator end(){return this->from.end();}
1940 const_iterator end()const{return this->from.end();}
1943 reverse_iterator rend(){return this->from.rend();}
1944 const_reverse_iterator rend()const{return this->from.rend();}
1945 size_type size()const{return this->from.size();}
1946 size_type max_size()const{return this->from.max_size();}
1947 bool empty()const{return this->from.empty();}
1949 from_binding_t operator[](const key_type& key){return this->from[key];}
1950 const_from_binding_t operator[](const key_type& key)const{return this->from[key];}
1951 using super::insert;
1952 std::pair<iterator,bool> insert(const value_type& x){return this->from.insert(x);}
1953 iterator insert(iterator it,const value_type& x){return this->from.insert(it,x);}
1954 template<
1955 typename it_type>
1956 void insert(it_type first,it_type last){this->from.insert(first,last);}
1957
1958#ifdef _MSC_VER /* see note in from::erase */
1959 iterator erase(iterator it){return this->from.erase(it);}
1960#else
1961 void erase(iterator it){this->from.erase(it);}
1962#endif
1963
1964 void erase(iterator first,iterator last){this->from.erase(first,last);}
1965 size_type erase(const key_type& key){return this->from.erase(key);}
1966 void clear(){this->from.clear();}
1969 {x.swap(y);}
1970 key_compare key_comp()const{return this->from.key_comp();}
1971 value_compare value_comp()const{return this->from.value_comp();}
1972 iterator find(const key_type& key){return this->from.find(key);}
1973 const_iterator find(const key_type& key)const{return this->from.find(key);}
1974 size_type count(const key_type& key)const{return this->from.count(key);}
1975 iterator lower_bound(const key_type& key){return this->from.lower_bound(key);}
1976 const_iterator lower_bound(const key_type& key)const{return this->from.lower_bound(key);}
1977 iterator upper_bound(const key_type& key){return this->from.upper_bound(key);}
1978 const_iterator upper_bound(const key_type& key)const{return this->from.upper_bound(key);}
1979 std::pair<
1980 iterator,
1981 iterator> equal_range(const key_type& key){return this->from.equal_range(key);}
1982 std::pair<
1984 const_iterator> equal_range(const key_type& key)const{return this->from.equal_range(key);}
1985
1986 /* Promotion of unambiguous parts of the to memberspace */
1987
1988 to_binding_t operator[](const to_key_type& key){return this->to[key];}
1989 const_to_binding_t operator[](const to_key_type& key)const{return this->to[key];}
1990 std::pair<
1991 to_iterator,
1992 bool> insert(const to_value_type& x){return this->to.insert(x);}
1993 to_iterator insert(to_iterator it,const to_value_type& x){return this->to.insert(it,x);}
1994 void insert(const to_value_type *first,const to_value_type *last)
1995 {this->to.insert(first,last);}
1996
1997#ifdef _MSC_VER /* see note in this->from.erase */
1998 to_iterator erase(to_iterator it){return this->to.erase(it);}
1999#else
2000 void erase(to_iterator it){this->to.erase(it);}
2001#endif
2002
2003 void erase(to_iterator first,to_iterator last){this->to.erase(first,last);}
2004 size_type erase(const to_key_type& key){return this->to.erase(key);}
2005 to_iterator find(const to_key_type& key){return this->to.find(key);}
2006 const_to_iterator find(const to_key_type& key)const{return this->to.find(key);}
2007 size_type count(const to_key_type& key)const{return this->to.count(key);}
2008 to_iterator lower_bound(const to_key_type& key){return this->to.lower_bound(key);}
2009 const_to_iterator lower_bound(const to_key_type& key)const{return this->to.lower_bound(key);}
2010 to_iterator upper_bound(const to_key_type& key){return this->to.upper_bound(key);}
2011 const_to_iterator upper_bound(const to_key_type& key)const{return this->to.upper_bound(key);}
2012 std::pair<
2013 to_iterator,
2014 to_iterator> equal_range(const to_key_type& key){return this->to.equal_range(key);}
2015 std::pair<
2016 const_to_iterator,
2017 const_to_iterator> equal_range(const to_key_type& key)const{return this->to.equal_range(key);}
2018
2019protected:
2021 const from_compare& from_comp,
2022 const to_compare& to_comp,
2023 const allocator_type_& al):
2024 super(from_comp,to_comp,al)
2025 {
2026 }
2027
2028 /* default copy ctor serves well */
2029};
2030
2031/* bimap finally inherits from bimap_equal_types or bimap_different_types
2032 * depending on the equality of from_type and to_type, as a way to
2033 * simulate PTS.
2034 */
2035template<
2036 typename from_type_,typename to_type_,
2037 typename from_compare=std::less<from_type_>,
2038 typename to_compare=std::less<to_type_>,
2039 typename allocator_type=std::allocator<direct_pair<const from_type_,const to_type_> > >
2040class bimap:
2041 public
2043 bimap_detail::equal_types<from_type_,to_type_>::value,
2044 bimap_equal_types<
2045 from_type_,to_type_,
2046 from_compare,to_compare,allocator_type>,
2047 bimap_different_types<
2048 from_type_,to_type_,
2049 from_compare,to_compare,allocator_type>
2050 >::result
2051{
2052protected:
2053 typedef typename
2057 from_type_,to_type_,
2058 from_compare,to_compare,allocator_type>,
2060 from_type_,to_type_,
2061 from_compare,to_compare,allocator_type>
2062 >::result
2064
2065public:
2066 explicit bimap(
2067 const from_compare& from_comp=from_compare(),
2068 const to_compare& to_comp=to_compare(),
2069 const allocator_type& al=allocator_type()):
2070 super(from_comp,to_comp,al)
2071 {
2072 }
2073
2074 /* default copy ctor serves well */
2075
2077 {
2078 bimap tmp(r);
2079 this->swap(tmp);
2080 return *this;
2081 }
2082
2083 /* inverse copy ctor (from a bimap<to_type,from_type>) */
2084
2085#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
2086 /* no allocator::rebind, assume allocator_type==std::allocator */
2087
2088 typedef
2089 bimap<
2090 to_type_,from_type_,
2091 to_compare,from_compare,
2092 std::allocator<direct_pair<const to_type_,const from_type_> > >
2093 inv_bimap;
2094
2095 explicit bimap(const inv_bimap& r):
2096 super(r.to.key_comp(),r.from.key_comp(),allocator_type())
2097#else
2098 typedef
2099 bimap<
2100 to_type_,from_type_,
2101 to_compare,from_compare,
2102 typename allocator_type::template rebind<
2103 direct_pair<const to_type_,const from_type_> >::other>
2105
2106 explicit bimap(const inv_bimap& r):
2107 super(r.to.key_comp(),r.from.key_comp(),r.get_allocator())
2108#endif
2109
2110/* body of bimap(const inv_bimap& r) follows */
2111
2112 {
2113 try{
2114
2115#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
2116/* Amortized constant insertion in VC++ 6.0 happens if hint iterator is
2117 * right *after* the insertion point, in disagreement with the standard.
2118 */
2119 typename super::from::iterator fhint=from.end();
2120 typename super::to::iterator thint=to.end();
2121 for(typename inv_bimap::to::const_iterator it=r.to.begin();it!=r.to.end();++it){
2122 insert(fhint,thint,*it);
2123 }
2124#else
2125 typename super::from::iterator fhint=this->from.end();
2126 typename super::to::iterator thint=this->to.end();
2127 for(typename inv_bimap::to::const_iterator it=r.to.begin();it!=r.to.end();++it){
2128 std::pair<typename super::from::iterator,typename super::to::iterator>
2129 p=this->insert(fhint,thint,*it);
2130 fhint=p.first;
2131 thint=p.second;
2132 }
2133#endif
2134
2135 }catch(...){
2136 this->clear();
2137 throw;
2138 }
2139 }
2140
2141 template<typename it_type>
2143 it_type first,it_type last,
2144 const from_compare& from_comp=from_compare(),
2145 const to_compare& to_comp=to_compare(),
2146 const allocator_type& al=allocator_type()):
2147 super(from_comp,to_comp,al)
2148 {
2149 try{
2150
2151#if defined(_MSC_VER)&&_MSC_VER==1200 /* MSVC++ 6.0 */
2152/* Amortized constant insertion in VC++ 6.0 happens if hint iterator is
2153 * right *after* the insertion point, in disagreement with the standard.
2154 */
2155
2156 typename super::from::iterator fhint=from.end();
2157 typename super::to::iterator thint=to.end();
2158 while(first!=last){
2159 insert(fhint,thint,first++);
2160 }
2161#else
2162 typename super::from::iterator fhint=this->from.end();
2163 typename super::to::iterator thint=this->to.end();
2164 while(first!=last){
2165 std::pair<typename super::from::iterator,typename super::to::iterator>
2166 p=this->insert(fhint,thint,first++);
2167 fhint=p.first;
2168 thint=p.second;
2169 }
2170#endif
2171
2172 }catch(...){
2173 this->clear();
2174 throw;
2175 }
2176 }
2177
2178 /* Comparison: we simply forward to from */
2179
2180 bool operator==(const bimap& r)const{return this->from==r.from;}
2181 bool operator!=(const bimap& r)const{return this->from!=r.from;}
2182 bool operator< (const bimap& r)const{return this->from<r.from;}
2183 bool operator> (const bimap& r)const{return this->from>r.from;}
2184 bool operator<=(const bimap& r)const{return this->from<=r.from;}
2185 bool operator>=(const bimap& r)const{return this->from>=r.from;}
2186};
2187
2188} /* namespace codeproject */
2189
2190#elif VERSION_BIMAP_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761!=0x00010003
2191#error You have included two BIMAP.H with different version numbers
2192#endif
#define BIMAP_OFFSETOF_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761(type, member)
Definition bimap.h:93
#define BIMAP_REBIND_9B698EF9_C6E9_4BC4_A7D2_5B4D71155761(type1, type2)
Definition bimap.h:104
const bimap_type::to_type & get() const
Definition bimap.h:538
const_from_binding(const bimap_type &bm, const typename bimap_type::from_type &f)
Definition bimap.h:534
const bimap_type::from_type & get() const
Definition bimap.h:633
const_to_binding(const bimap_type &bm, const typename bimap_type::to_type &t)
Definition bimap.h:629
duplicate_value(const std::string &str)
Definition bimap.h:452
from_binding & operator=(const typename bimap_type::to_type &t)
Definition bimap.h:480
from_binding(bimap_type &bm, const typename bimap_type::from_type &f)
Definition bimap.h:466
const bimap_type::to_type & get() const
Definition bimap.h:468
to_binding(bimap_type &bm, const typename bimap_type::to_type &t)
Definition bimap.h:561
to_binding & operator=(const typename bimap_type::from_type &f)
Definition bimap.h:575
const bimap_type::from_type & get() const
Definition bimap.h:563
value_not_found(const std::string &str)
Definition bimap.h:445
super::from::const_reference const_reference
Definition bimap.h:1931
super::from::key_compare key_compare
Definition bimap.h:1922
super::from::value_type value_type
Definition bimap.h:1924
super::from::allocator_type allocator_type
Definition bimap.h:1923
super::from::const_pointer const_pointer
Definition bimap.h:1929
to_iterator lower_bound(const to_key_type &key)
Definition bimap.h:2008
void erase(iterator first, iterator last)
Definition bimap.h:1964
super::from::difference_type difference_type
Definition bimap.h:1927
std::pair< iterator, bool > insert(const value_type &x)
Definition bimap.h:1952
std::pair< iterator, iterator > equal_range(const key_type &key)
Definition bimap.h:1981
std::pair< to_iterator, bool > insert(const to_value_type &x)
Definition bimap.h:1992
super::from::const_iterator const_iterator
Definition bimap.h:1933
size_type count(const key_type &key) const
Definition bimap.h:1974
const_iterator lower_bound(const key_type &key) const
Definition bimap.h:1976
size_type erase(const key_type &key)
Definition bimap.h:1965
iterator insert(iterator it, const value_type &x)
Definition bimap.h:1953
std::pair< const_iterator, const_iterator > equal_range(const key_type &key) const
Definition bimap.h:1984
std::pair< to_iterator, to_iterator > equal_range(const to_key_type &key)
Definition bimap.h:2014
allocator_type get_allocator() const
Definition bimap.h:1948
value_compare value_comp() const
Definition bimap.h:1971
super::from::mapped_type mapped_type
Definition bimap.h:1919
reverse_iterator rbegin()
Definition bimap.h:1941
size_type erase(const to_key_type &key)
Definition bimap.h:2004
super::from::value_compare value_compare
Definition bimap.h:1925
super::from::iterator iterator
Definition bimap.h:1932
super::from::referent_type referent_type
Definition bimap.h:1920
const_to_iterator upper_bound(const to_key_type &key) const
Definition bimap.h:2011
const_to_binding_t operator[](const to_key_type &key) const
Definition bimap.h:1989
super::from::data_type data_type
Definition bimap.h:1921
super::from::reverse_iterator reverse_iterator
Definition bimap.h:1934
super::from::reference reference
Definition bimap.h:1930
const_iterator find(const key_type &key) const
Definition bimap.h:1973
const_iterator end() const
Definition bimap.h:1940
bimap_different_types(const from_compare &from_comp, const to_compare &to_comp, const allocator_type_ &al)
Definition bimap.h:2020
const_reverse_iterator rend() const
Definition bimap.h:1944
void swap(bimap_different_types &x)
Definition bimap.h:1967
super::from::const_reverse_iterator const_reverse_iterator
Definition bimap.h:1935
void erase(to_iterator it)
Definition bimap.h:2000
iterator lower_bound(const key_type &key)
Definition bimap.h:1975
const_to_iterator lower_bound(const to_key_type &key) const
Definition bimap.h:2009
super::from::pointer pointer
Definition bimap.h:1928
void erase(to_iterator first, to_iterator last)
Definition bimap.h:2003
const_iterator upper_bound(const key_type &key) const
Definition bimap.h:1978
const_iterator begin() const
Definition bimap.h:1938
iterator upper_bound(const key_type &key)
Definition bimap.h:1977
super::from::key_type key_type
Definition bimap.h:1918
void insert(const to_value_type *first, const to_value_type *last)
Definition bimap.h:1994
std::pair< const_to_iterator, const_to_iterator > equal_range(const to_key_type &key) const
Definition bimap.h:2017
to_iterator insert(to_iterator it, const to_value_type &x)
Definition bimap.h:1993
iterator find(const key_type &key)
Definition bimap.h:1972
to_iterator upper_bound(const to_key_type &key)
Definition bimap.h:2010
void insert(it_type first, it_type last)
Definition bimap.h:1956
to_iterator find(const to_key_type &key)
Definition bimap.h:2005
key_compare key_comp() const
Definition bimap.h:1970
const_to_iterator find(const to_key_type &key) const
Definition bimap.h:2006
const_from_binding_t operator[](const key_type &key) const
Definition bimap.h:1950
size_type count(const to_key_type &key) const
Definition bimap.h:2007
to_binding_t operator[](const to_key_type &key)
Definition bimap.h:1988
from_binding_t operator[](const key_type &key)
Definition bimap.h:1949
super::from::size_type size_type
Definition bimap.h:1926
const_reverse_iterator rbegin() const
Definition bimap.h:1942
friend void swap(bimap_different_types &x, bimap_different_types &y)
Definition bimap.h:1968
iterator find(const key_type &key)
Definition bimap.h:1846
iterator upper_bound(const key_type &key)
Definition bimap.h:1851
void erase(to_iterator first, to_iterator last)
Definition bimap.h:1875
super::from::reverse_iterator reverse_iterator
Definition bimap.h:1809
super::from::size_type size_type
Definition bimap.h:1801
bimap_equal_types(const from_compare &from_comp, const to_compare &to_comp, const allocator_type_ &al)
Definition bimap.h:1878
void erase(to_iterator it)
Definition bimap.h:1872
super::from::referent_type referent_type
Definition bimap.h:1795
const_iterator upper_bound(const key_type &key) const
Definition bimap.h:1852
void erase(iterator first, iterator last)
Definition bimap.h:1839
super::from::mapped_type mapped_type
Definition bimap.h:1794
const_iterator begin() const
Definition bimap.h:1813
super::from::reference reference
Definition bimap.h:1805
friend void swap(bimap_equal_types &x, bimap_equal_types &y)
Definition bimap.h:1843
reverse_iterator rend()
Definition bimap.h:1818
size_type erase(const key_type &key)
Definition bimap.h:1840
const_from_binding_t operator[](const key_type &key) const
Definition bimap.h:1825
value_compare value_comp() const
Definition bimap.h:1845
super::from::data_type data_type
Definition bimap.h:1796
super::from::const_reverse_iterator const_reverse_iterator
Definition bimap.h:1810
reverse_iterator rbegin()
Definition bimap.h:1816
std::pair< iterator, bool > insert(const value_type &x)
Definition bimap.h:1827
super::from::const_iterator const_iterator
Definition bimap.h:1808
std::pair< iterator, iterator > equal_range(const key_type &key)
Definition bimap.h:1855
super::from::const_reference const_reference
Definition bimap.h:1806
iterator lower_bound(const key_type &key)
Definition bimap.h:1849
super::from::iterator iterator
Definition bimap.h:1807
void erase(iterator it)
Definition bimap.h:1836
to_iterator insert(to_iterator it, const to_value_type &x)
Definition bimap.h:1865
const_reverse_iterator rbegin() const
Definition bimap.h:1817
std::pair< const_iterator, const_iterator > equal_range(const key_type &key) const
Definition bimap.h:1858
const_reverse_iterator rend() const
Definition bimap.h:1819
super::from::const_pointer const_pointer
Definition bimap.h:1804
void insert(const to_value_type *first, const to_value_type *last)
Definition bimap.h:1866
super::from::allocator_type allocator_type
Definition bimap.h:1798
super::from::pointer pointer
Definition bimap.h:1803
key_compare key_comp() const
Definition bimap.h:1844
super::from::difference_type difference_type
Definition bimap.h:1802
size_type count(const key_type &key) const
Definition bimap.h:1848
super::from::key_compare key_compare
Definition bimap.h:1797
from_binding_t operator[](const key_type &key)
Definition bimap.h:1824
allocator_type get_allocator() const
Definition bimap.h:1823
const_iterator find(const key_type &key) const
Definition bimap.h:1847
super::from::key_type key_type
Definition bimap.h:1793
std::pair< to_iterator, bool > insert(const to_value_type &x)
Definition bimap.h:1864
super::from::value_compare value_compare
Definition bimap.h:1800
size_type size() const
Definition bimap.h:1820
void swap(bimap_equal_types &x)
Definition bimap.h:1842
const_iterator end() const
Definition bimap.h:1815
size_type max_size() const
Definition bimap.h:1821
iterator insert(iterator it, const value_type &x)
Definition bimap.h:1828
const_iterator lower_bound(const key_type &key) const
Definition bimap.h:1850
void insert(it_type first, it_type last)
Definition bimap.h:1831
super::from::value_type value_type
Definition bimap.h:1799
bimap_detail::select< bimap_detail::equal_types< from_type_, to_type_ >::value, bimap_equal_types< from_type_, to_type_, from_compare, to_compare, allocator_type >, bimap_different_types< from_type_, to_type_, from_compare, to_compare, allocator_type > >::result super
Definition bimap.h:2063
bool operator==(const bimap &r) const
Definition bimap.h:2180
bool operator!=(const bimap &r) const
Definition bimap.h:2181
bool operator<=(const bimap &r) const
Definition bimap.h:2184
bimap & operator=(const bimap &r)
Definition bimap.h:2076
bimap(it_type first, it_type last, const from_compare &from_comp=from_compare(), const to_compare &to_comp=to_compare(), const allocator_type &al=allocator_type())
Definition bimap.h:2142
bimap(const from_compare &from_comp=from_compare(), const to_compare &to_comp=to_compare(), const allocator_type &al=allocator_type())
Definition bimap.h:2066
bool operator<(const bimap &r) const
Definition bimap.h:2182
bimap(const inv_bimap &r)
Definition bimap.h:2106
bimap< to_type_, from_type_, to_compare, from_compare, typename allocator_type::template rebind< direct_pair< const to_type_, const from_type_ > >::other > inv_bimap
Definition bimap.h:2104
bool operator>(const bimap &r) const
Definition bimap.h:2183
bool operator>=(const bimap &r) const
Definition bimap.h:2185
const const_iterator::value_type * operator->() const
Definition bimap.h:902
bool operator!=(const const_iterator &it) const
Definition bimap.h:910
bool operator==(const const_iterator &it) const
Definition bimap.h:909
const_iterator::reference operator*() const
Definition bimap.h:901
bool operator!=(const iterator &it) const
Definition bimap.h:874
iterator::value_type * operator->() const
Definition bimap.h:866
iterator::reference operator*() const
Definition bimap.h:865
bool operator==(const iterator &it) const
Definition bimap.h:873
value_compare(key_compare kcomp, to_compare tcomp)
Definition bimap.h:829
bool operator()(const value_type &x, const value_type &y)
Definition bimap.h:822
reverse_iterator rbegin()
Definition bimap.h:937
bool operator==(const from_impl &r) const
Definition bimap.h:770
size_type count(const key_type &key) const
Definition bimap.h:1107
const_reverse_iterator rbegin() const
Definition bimap.h:938
const_reverse_iterator rend() const
Definition bimap.h:940
allocator_type get_allocator() const
Definition bimap.h:947
bool operator<=(const from_impl &r) const
Definition bimap.h:792
const prebimap & owner() const
Definition bimap.h:1152
iterator find(const key_type &key)
Definition bimap.h:1097
from_impl & operator=(const from_impl &r)
Definition bimap.h:761
std::pair< iterator, iterator > equal_range(const key_type &key)
Definition bimap.h:1132
iterator insert(iterator it, const value_type &x)
Definition bimap.h:993
const_iterator end() const
Definition bimap.h:935
from_binding< prebimap< from_type_, to_type_, from_compare, to_compare, allocator_type_ > > operator[](const from_type_ &f)
Definition bimap.h:952
value_compare value_comp() const
Definition bimap.h:1089
size_type erase(const key_type &key)
Definition bimap.h:1058
bool adjacent(const_fset_iterator fit, const from_type_ &f) const
Definition bimap.h:1159
bool operator<(const from_impl &r) const
Definition bimap.h:780
key_compare key_comp() const
Definition bimap.h:1084
direct_pair< const from_type_, const to_type_ > value_type
Definition bimap.h:813
std::reverse_iterator< const_iterator > reverse_iterator
Definition bimap.h:925
iterator upper_bound(const key_type &key)
Definition bimap.h:1122
allocator_type_ allocator_type
Definition bimap.h:809
std::pair< const_iterator, const_iterator > equal_range(const key_type &key) const
Definition bimap.h:1137
void erase(iterator it)
Definition bimap.h:1042
reverse_iterator const_reverse_iterator
Definition bimap.h:928
const_iterator begin() const
Definition bimap.h:933
const_iterator find(const key_type &key) const
Definition bimap.h:1102
bool operator>=(const from_impl &r) const
Definition bimap.h:797
iterator lower_bound(const key_type &key)
Definition bimap.h:1112
reverse_iterator rend()
Definition bimap.h:939
const_iterator upper_bound(const key_type &key) const
Definition bimap.h:1127
const value_type & const_reference
Definition bimap.h:839
bool operator!=(const from_impl &r) const
Definition bimap.h:775
bool operator>(const from_impl &r) const
Definition bimap.h:787
void erase(iterator first, iterator last)
Definition bimap.h:1053
const_iterator lower_bound(const key_type &key) const
Definition bimap.h:1117
void insert(it_type first, it_type last)
Definition bimap.h:1016
const_from_binding< prebimap< from_type_, to_type_, from_compare, to_compare, allocator_type_ > > operator[](const from_type_ &f) const
Definition bimap.h:960
std::pair< iterator, bool > insert(const value_type &x)
Definition bimap.h:969
size_type size() const
Definition bimap.h:944
allocator_type_::difference_type difference_type
Definition bimap.h:835
size_type max_size() const
Definition bimap.h:945
void swap(from_impl &x)
Definition bimap.h:1074
const value_type * const_pointer
Definition bimap.h:837
allocator_type_::size_type size_type
Definition bimap.h:834
friend void swap(from &x, from &y)
Definition bimap.h:1191
bool operator==(const const_iterator &it) const
Definition bimap.h:1359
bool operator!=(const const_iterator &it) const
Definition bimap.h:1360
const const_iterator operator++(int)
Definition bimap.h:1356
const_iterator::reference operator*() const
Definition bimap.h:1351
const const_iterator::value_type * operator->() const
Definition bimap.h:1352
const const_iterator operator--(int)
Definition bimap.h:1358
bool operator!=(const iterator &it) const
Definition bimap.h:1324
iterator::reference operator*() const
Definition bimap.h:1315
iterator::value_type * operator->() const
Definition bimap.h:1316
bool operator==(const iterator &it) const
Definition bimap.h:1323
bool operator()(const value_type &x, const value_type &y)
Definition bimap.h:1273
value_compare(key_compare kcomp, from_compare fcomp)
Definition bimap.h:1280
allocator_type_::difference_type difference_type
Definition bimap.h:1286
const value_type * const_pointer
Definition bimap.h:1288
bool operator<(const to_impl &r) const
Definition bimap.h:1235
reverse_iterator const_reverse_iterator
Definition bimap.h:1378
value_compare value_comp() const
Definition bimap.h:1535
std::pair< const_iterator, const_iterator > equal_range(const key_type &key) const
Definition bimap.h:1583
const_to_binding< prebimap< from_type_, to_type_, from_compare, to_compare, allocator_type_ > > operator[](const to_type_ &t) const
Definition bimap.h:1410
allocator_type_::size_type size_type
Definition bimap.h:1285
const_iterator begin() const
Definition bimap.h:1383
bool operator>(const to_impl &r) const
Definition bimap.h:1242
std::pair< iterator, iterator > equal_range(const key_type &key)
Definition bimap.h:1578
void erase(iterator first, iterator last)
Definition bimap.h:1499
const_iterator end() const
Definition bimap.h:1385
reverse_iterator rbegin()
Definition bimap.h:1387
to_impl & operator=(const to_impl &r)
Definition bimap.h:1216
std::pair< iterator, bool > insert(const value_type &x)
Definition bimap.h:1419
size_type count(const key_type &key) const
Definition bimap.h:1553
iterator find(const key_type &key)
Definition bimap.h:1543
bool adjacent(const_tset_iterator tit, const to_type_ &t) const
Definition bimap.h:1605
const_iterator upper_bound(const key_type &key) const
Definition bimap.h:1573
std::reverse_iterator< const_iterator > reverse_iterator
Definition bimap.h:1375
bool operator!=(const to_impl &r) const
Definition bimap.h:1230
reverse_iterator rend()
Definition bimap.h:1389
bool operator==(const to_impl &r) const
Definition bimap.h:1225
void erase(iterator it)
Definition bimap.h:1488
void swap(to_impl &x)
Definition bimap.h:1520
allocator_type get_allocator() const
Definition bimap.h:1397
key_compare key_comp() const
Definition bimap.h:1530
size_type size() const
Definition bimap.h:1394
allocator_type_ allocator_type
Definition bimap.h:1264
void insert(it_type first, it_type last)
Definition bimap.h:1466
const_iterator lower_bound(const key_type &key) const
Definition bimap.h:1563
bool operator<=(const to_impl &r) const
Definition bimap.h:1247
iterator upper_bound(const key_type &key)
Definition bimap.h:1568
size_type max_size() const
Definition bimap.h:1395
inv_pair< const to_type_, const from_type_ > value_type
Definition bimap.h:1268
bool operator>=(const to_impl &r) const
Definition bimap.h:1252
size_type erase(const key_type &key)
Definition bimap.h:1504
iterator insert(iterator it, const value_type &x)
Definition bimap.h:1443
const value_type & const_reference
Definition bimap.h:1290
to_binding< prebimap< from_type_, to_type_, from_compare, to_compare, allocator_type_ > > operator[](const to_type_ &t)
Definition bimap.h:1402
iterator lower_bound(const key_type &key)
Definition bimap.h:1558
const_reverse_iterator rbegin() const
Definition bimap.h:1388
const_iterator find(const key_type &key) const
Definition bimap.h:1548
const prebimap & owner() const
Definition bimap.h:1598
const_reverse_iterator rend() const
Definition bimap.h:1390
friend void swap(to &x, to &y)
Definition bimap.h:1637
codeproject::prebimap::from from
codeproject::prebimap::to to
prebimap(const prebimap &r)
Definition bimap.h:1710
std::pair< typename from_impl::iterator, typename to_impl::iterator > insert(typename from_impl::iterator fit, typename to_impl::iterator tit, const typename from_impl::value_type &x)
Definition bimap.h:1661
prebimap(const from_compare &from_comp, const to_compare &to_comp, const allocator_type_ &al)
Definition bimap.h:1701
equal_types_no equal_types_helper(...)
bool operator>=(const inv_pair< first_type, second_type > &x, const inv_pair< first_type, second_type > &y)
Definition bimap.h:414
inv_pair< first_type, second_type > make_inv_pair(const first_type &first, const second_type &second)
Definition bimap.h:272
bool operator==(const inv_pair< first_type, second_type > &x, const inv_pair< first_type, second_type > &y)
Definition bimap.h:284
bool operator!=(const inv_pair< first_type, second_type > &x, const inv_pair< first_type, second_type > &y)
Definition bimap.h:310
bool operator>(const inv_pair< first_type, second_type > &x, const inv_pair< first_type, second_type > &y)
Definition bimap.h:362
bool operator<(const inv_pair< first_type, second_type > &x, const inv_pair< first_type, second_type > &y)
Definition bimap.h:336
bool operator<=(const inv_pair< first_type, second_type > &x, const inv_pair< first_type, second_type > &y)
Definition bimap.h:388
sel::template result< then, els >::type result
Definition bimap.h:194
selector_switch< test >::result sel
Definition bimap.h:193
direct_pair(const inv_pair< first_type, second_type > &r)
Definition bimap.h:252
direct_pair(const std::pair< F, S > &r)
Definition bimap.h:254
direct_pair(const first_type &first, const second_type &second)
Definition bimap.h:251
second_type_ second_type
Definition bimap.h:221
inv_pair(const inv_pair< F, S > &r)
Definition bimap.h:230
inv_pair(const first_type &first, const second_type &second)
Definition bimap.h:227
inv_pair(const std::pair< first_type, second_type > &r)
Definition bimap.h:228
first_type_ first_type
Definition bimap.h:220
Arg2 second_argument_type
Definition bimap.h:112
Arg1 first_argument_type
Definition bimap.h:111
Result result_type
Definition bimap.h:113
ArgumentType argument_type
Definition bimap.h:119
ResultType result_type
Definition bimap.h:120