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