jle_cpp_tk  0.0 2015-04-03 sh1:"d699093732dd5f321606d0ff7a6b63b229f1922c"
A small, safe, selft contained, soft-realtime C++ toolkit
map.hpp
1 #ifndef JLE_CONTAINERS_MAP_GUARD
2 #define JLE_CONTAINERS_MAP_GUARD
3 
4 
5 
6 
7 #include <map>
8 
9 #include "container_support.h"
10 #include "core/alarm.h"
11 
12 
13 
14 namespace jle {
15 //---------------------------------------------------------------------------
16 
17 
18 
19 template<typename key_type, typename T>
20 class map
21 {
22 public:
23 
24  class iterator {
25  public:
26  iterator(const iterator&) = default;
27  iterator(iterator&&) = default;
28  iterator& operator=(const iterator&) = default;
29  iterator& operator=(iterator&&) = default;
30 
31  friend class jle::map<key_type, T>;
32  friend class jle::map<key_type, T>::const_iterator;
33  iterator() : registered_owner(0), last_updated_container(0) {};
34  iterator& operator++();
35  iterator operator++(int);
36  bool operator==(const iterator& it) const;
37  bool operator!=(const iterator& it) const;
38 
39  std::pair<const key_type, T>* operator->(void);
40  std::pair<const key_type, T>& operator*(void);
41 
42  private:
43  typename std::map<key_type, T>::iterator iiterator;
44  typename std::map<key_type, T>::iterator i_end_iterator;
45  int registered_owner;
46  int last_updated_container;
47 
48  bool is_valid (void) const;
49  };
50 
51 
53  public:
54  const_iterator(const const_iterator&) = default;
55  const_iterator(const_iterator&&) = default;
56  const_iterator& operator=(const const_iterator&) = default;
57  const_iterator& operator=(const_iterator&&) = default;
58 
59  friend class jle::map<key_type, T>;
60  const_iterator() : registered_owner(0), last_updated_container(0) {};
61  const_iterator(const iterator& it) :
62  iiterator (it.iiterator),
63  i_end_iterator (it.i_end_iterator),
64  registered_owner(it.registered_owner),
65  last_updated_container(it.last_updated_container)
66  {
67  };
68  const_iterator& operator=(const iterator& it)
69  {
70  registered_owner = it.registered_owner;
71  last_updated_container = it.last_updated_container;
72  iiterator = it.iiterator;
73  i_end_iterator = it.i_end_iterator;
74  return *this;
75  }
76 
77  const_iterator& operator++();
78  const_iterator operator++(int);
79  bool operator==(const const_iterator& it) const;
80  bool operator!=(const const_iterator& it) const;
81 
82  const std::pair<const key_type, T>* operator->(void);
83  const std::pair<const key_type, T>& operator*(void);
84 
85  private:
86  typename std::map<key_type, T>::const_iterator iiterator;
87  typename std::map<key_type, T>::const_iterator i_end_iterator;
88  int registered_owner;
89  int last_updated_container;
90 
91  bool is_valid (void) const;
92  };
93 
94 
95 
96 
97 
98  map() : registered_as(internal_for_containers::register_container(true)) {};
99  ~map()
100  {
101  try{
102  internal_for_containers::unregister_container(registered_as);
103  } JLE_CATCH_CALLFUNCION(jle::alarm_msg, "exception on destructor", "catched exception on destructor")
104  };
105 
106  map(std::initializer_list<T> il) : imap(il), registered_as(internal_for_containers::register_container(true)) {};
107  map(const map<key_type, T>& m);
108  map(map<key_type, T>&& m);
109  map<key_type, T>& operator=(const map<key_type, T>& m);
110  map<key_type, T>& operator=(map<key_type, T>&& m);
111 
112  // comparison operators
113  bool operator==( const map<key_type, T>& rhs ) { return imap == rhs.imap; }
114  bool operator!=( const map<key_type, T>& rhs ) { return imap != rhs.imap; }
115  bool operator< ( const map<key_type, T>& rhs ) { return imap < rhs.imap; }
116  bool operator<=( const map<key_type, T>& rhs ) { return imap <= rhs.imap; }
117  bool operator> ( const map<key_type, T>& rhs ) { return imap > rhs.imap; }
118  bool operator>=( const map<key_type, T>& rhs ) { return imap >= rhs.imap; }
119 
120 
121 
122 
123 
124  // capacity
125  bool empty () const;
126  unsigned size () const;
127 
128 
129  // access
130  T& operator[] (const key_type& x);
131 
132 
133  // operations
134  void clear ();
135  unsigned count (const key_type& x) const;
136  iterator find (const key_type& x);
137  const_iterator find (const key_type& x) const;
138  iterator lower_bound (const key_type& x);
139  const_iterator lower_bound (const key_type& x) const;
140  iterator upper_bound (const key_type& x);
141  const_iterator upper_bound (const key_type& x) const;
142 
143 
144  // iterators
145  iterator begin ();
146  const_iterator cbegin () const;
147  iterator end ();
148  const_iterator cend () const;
149 
150 
151  // modifiers
152  unsigned erase (const key_type& x);
153  iterator erase (iterator position);
154  void erase (const iterator& first, const iterator& last);
155  std::pair<iterator, bool> insert (const std::pair<key_type, T>& x );
156 
157 private:
158  std::map<key_type, T> imap;
159  int registered_as; // can't be constant. assign operator
160 };
161 
162 
163 
164 
165 
166 //--------------------------------------------------------------------------------
167 // IMPLEMENTATION
168 //--------------------------------------------------------------------------------
169 
170 
171 template <typename key_type, typename T>
173  : registered_as (internal_for_containers::register_container( imap.empty() ? true : false))
174 {
175  imap = m.imap;
176  if(imap.empty() == false)
177  internal_for_containers::register_container_size_change(registered_as);
178 }
179 
180 template <typename key_type, typename T>
182  : registered_as (internal_for_containers::register_container( imap.empty() ? true : false))
183 {
184  imap = std::move(l.imap);
185 
186  if (imap.empty() == false)
187  internal_for_containers::register_container_size_change(registered_as);
188 }
189 
190 
191 template <typename key_type, typename T>
193 {
194  imap = m.imap;
195  registered_as = internal_for_containers::register_container( imap.empty() ? true : false);
196  if(imap.empty() == false)
197  internal_for_containers::register_container_size_change(registered_as);
198  return *this;
199 }
200 
201 template <typename key_type, typename T>
203 {
204  imap = std::move(v.imap);
205  registered_as = internal_for_containers::register_container( imap.empty() ? true : false);
206  if (imap.empty() == false)
207  internal_for_containers::register_container_size_change(registered_as);
208  return *this;
209 }
210 
211 
212 // iterators ---------------------------------------------------
213 
214 template <typename key_type, typename T>
215 bool map<key_type, T>::iterator::is_valid (void) const
216 {
217  if (last_updated_container==0 || internal_for_containers::get_registered_container_last_size_change(registered_owner) != last_updated_container)
218  return false;
219  else
220  return true;
221 }
222 
223 template <typename key_type, typename T>
225 {
226  typename map<key_type, T>::iterator it;
227  it.iiterator = imap.begin();
228 
229  it.registered_owner = registered_as;
230  it.i_end_iterator = imap.end();
231 
232  if (imap.empty()==false)
233  it.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
234  else
235  it.last_updated_container = 0; // no valid value
236 
237  return it;
238 }
239 
240 
241 template <typename key_type, typename T>
243 {
244  typename map<key_type, T>::iterator it;
245  it.iiterator = imap.end();
246  it.registered_owner = registered_as;
247  it.i_end_iterator = imap.end();
248  it.last_updated_container = 0; // no value
249  return it;
250 }
251 
252 
253 
254 
255 template <typename key_type, typename T>
257 {
258  if (is_valid() == false)
259  throw jle::alarm(JLE_HERE, "map", "iterator not valid", jle::al::priority::error);
260 
261  if (i_end_iterator == iiterator)
262  throw jle::alarm(JLE_HERE, "map", "++ on end iterator", jle::al::priority::error);
263 
264  ++iiterator;
265  return *this;
266 }
267 
268 template <typename key_type, typename T>
270 {
271  typename map<key_type, T>::iterator result = *this;
272 
273  if (is_valid() == false)
274  throw jle::alarm(JLE_HERE, "map", "iterator not valid", jle::al::priority::error);
275 
276  if (i_end_iterator == iiterator)
277  throw jle::alarm(JLE_HERE, "map", "++ on end iterator", jle::al::priority::error);
278 
279  ++iiterator;
280  return result;
281 }
282 
283 template <typename key_type, typename T>
285 {
286  if(registered_owner!=0 && it.registered_owner != 0 && registered_owner != it.registered_owner)
287  throw jle::alarm(JLE_HERE, "map", "on different owners", jle::al::priority::error);
288 
289  return it.iiterator == iiterator;
290 }
291 
292 template <typename key_type, typename T>
294 {
295  return !operator==(it);
296 }
297 
298 
299 template <typename key_type, typename T>
300 std::pair<const key_type, T>* map<key_type, T>::iterator::operator->(void)
301 {
302  if (last_updated_container==0
303  || internal_for_containers::get_registered_container_last_size_change(registered_owner) != last_updated_container
304  || internal_for_containers::get_registered_container_last_size_change(registered_owner) == 0)
305  throw jle::alarm(JLE_HERE, "map", "iterator not valid", jle::al::priority::error);
306 
307  if (i_end_iterator == iiterator)
308  throw jle::alarm(JLE_HERE, "map", "-> on end iterator", jle::al::priority::error);
309 
310  return iiterator.operator->();
311 }
312 
313 template <typename key_type, typename T>
314 std::pair<const key_type, T>& map<key_type, T>::iterator::operator*(void)
315 {
316  if (last_updated_container==0
317  || internal_for_containers::get_registered_container_last_size_change(registered_owner) != last_updated_container
318  || internal_for_containers::get_registered_container_last_size_change(registered_owner) == 0)
319  throw jle::alarm(JLE_HERE, "map", "iterator not valid", jle::al::priority::error);
320 
321  if (i_end_iterator == iiterator)
322  throw jle::alarm(JLE_HERE, "map", "* on end iterator", jle::al::priority::error);
323 
324  return *iiterator;
325 }
326 
327 
328 
329 
330 
331 
332 
333 
334 
335 
336 
337 // const_iterators ---------------------------------------------------
338 
339 template <typename key_type, typename T>
341 {
342  if (last_updated_container==0 || internal_for_containers::get_registered_container_last_size_change(registered_owner) != last_updated_container)
343  return false;
344  else
345  return true;
346 }
347 
348 
349 template <typename key_type, typename T>
351 {
353  it.iiterator = imap.begin();
354 
355  it.registered_owner = registered_as;
356  it.i_end_iterator = imap.end();
357 
358  if (imap.empty()==false)
359  it.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
360  else
361  it.last_updated_container = 0; // no valid value
362 
363  return it;
364 }
365 
366 
367 template <typename key_type, typename T>
369 {
371  it.registered_owner = registered_as;
372  it.i_end_iterator = imap.end();
373  it.iiterator = imap.end();
374  it.last_updated_container = 0; // no value
375  return it;
376 }
377 
378 
379 
380 
381 template <typename key_type, typename T>
383 {
384  if (is_valid() == false)
385  throw jle::alarm(JLE_HERE, "map", "iterator not valid", jle::al::priority::error);
386 
387  if (i_end_iterator == iiterator)
388  throw jle::alarm(JLE_HERE, "map", "++ on end iterator", jle::al::priority::error);
389 
390  ++iiterator;
391  return *this;
392 }
393 
394 template <typename key_type, typename T>
396 {
397  typename map<key_type, T>::const_iterator result = *this;
398 
399  if (is_valid() == false)
400  throw jle::alarm(JLE_HERE, "map", "iterator not valid", jle::al::priority::error);
401 
402  if (i_end_iterator == iiterator)
403  throw jle::alarm(JLE_HERE, "map", "++ on end iterator", jle::al::priority::error);
404 
405  ++iiterator;
406  return result;
407 }
408 
409 template <typename key_type, typename T>
411 {
412  if(registered_owner!=0 && it.registered_owner != 0 && registered_owner != it.registered_owner)
413  throw jle::alarm(JLE_HERE, "map", "on different owners", jle::al::priority::error);
414 
415  return it.iiterator == iiterator;
416 }
417 
418 template <typename key_type, typename T>
420 {
421  return !operator==(it);
422 }
423 
424 
425 template <typename key_type, typename T>
426 const std::pair<const key_type, T>* map<key_type, T>::const_iterator::operator->(void)
427 {
428  if (is_valid() == false)
429  throw jle::alarm(JLE_HERE, "map", "iterator not valid", jle::al::priority::error);
430 
431  if (i_end_iterator == iiterator)
432  throw jle::alarm(JLE_HERE, "map", "-> on end iterator", jle::al::priority::error);
433 
434  return iiterator.operator->();
435 }
436 
437 template <typename key_type, typename T>
438 const std::pair<const key_type, T>& map<key_type, T>::const_iterator::operator*(void)
439 {
440  if (is_valid() == false)
441  throw jle::alarm(JLE_HERE, "map", "iterator not valid", jle::al::priority::error);
442 
443  if (i_end_iterator == iiterator)
444  throw jle::alarm(JLE_HERE, "map", "* on end iterator", jle::al::priority::error);
445 
446  return *iiterator;
447 }
448 
449 
450 
451 template <typename key_type, typename T>
452 bool map<key_type, T>::empty () const
453 {
454  return imap.empty();
455 }
456 
457 template <typename key_type, typename T>
458 unsigned map<key_type, T>::size () const
459 {
460  return unsigned(imap.size());
461 }
462 
463 
464 template <typename key_type, typename T>
465 T& map<key_type, T>::operator[] (const key_type& x)
466 {
467  if (find(x) == end())
468  internal_for_containers::register_container_size_change(registered_as);
469  return imap[x];
470 }
471 
472 
473 template <typename key_type, typename T>
475 {
476  internal_for_containers::register_container_size_change(registered_as);
477  imap.clear();
478 }
479 
480 template <typename key_type, typename T>
481 unsigned map<key_type, T>::count (const key_type& x) const
482 {
483  return imap.count(x);
484 }
485 
486 
487 
488 
489 
490 
491 
492 
493 
494 template <typename key_type, typename T>
496 map<key_type, T>::find (const key_type& x)
497 {
498  typename map<key_type, T>::iterator it;
499  it.iiterator = imap.find(x);
500  if (it.iiterator != imap.end())
501  {
502  it.registered_owner = registered_as;
503  it.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
504  it.i_end_iterator = imap.end();
505  }
506  else
507  {
508  it.registered_owner = 0;
509  it.last_updated_container = 0;
510  }
511 
512  return it;
513 }
514 
515 template <typename key_type, typename T>
517 map<key_type, T>::find (const key_type& x) const
518 {
520  it.iiterator = imap.find(x);
521  if (it.iiterator != imap.end())
522  {
523  it.registered_owner = registered_as;
524  it.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
525  it.i_end_iterator = imap.end();
526  }
527  else
528  {
529  it.registered_owner = 0;
530  it.last_updated_container = 0;
531  }
532 
533  return it;
534 }
535 
536 
537 template <typename key_type, typename T>
539 map<key_type, T>::lower_bound (const key_type& x)
540 {
541  typename map<key_type, T>::iterator it;
542  it.iiterator = imap.lower_bound(x);
543  if (it.iiterator != imap.end())
544  {
545  it.registered_owner = registered_as;
546  it.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
547  it.i_end_iterator = imap.end();
548  }
549  else
550  {
551  it.registered_owner = 0;
552  it.last_updated_container = 0;
553  }
554 
555  return it;
556 }
557 
558 template <typename key_type, typename T>
560 map<key_type, T>::lower_bound (const key_type& x) const
561 {
563  it.iiterator = imap.lower_bound(x);
564  if (it.iiterator != imap.end())
565  {
566  it.registered_owner = registered_as;
567  it.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
568  it.i_end_iterator = imap.end();
569  }
570  else
571  {
572  it.registered_owner = 0;
573  it.last_updated_container = 0;
574  }
575 
576  return it;
577 }
578 
579 template <typename key_type, typename T>
581 map<key_type, T>::upper_bound (const key_type& x)
582 {
583  typename map<key_type, T>::iterator it;
584  it.iiterator = imap.upper_bound(x);
585  if (it.iiterator != imap.end())
586  {
587  it.registered_owner = registered_as;
588  it.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
589  it.i_end_iterator = imap.end();
590  }
591  else
592  {
593  it.registered_owner = 0;
594  it.last_updated_container = 0;
595  }
596 
597  return it;
598 }
599 
600 
601 template <typename key_type, typename T>
603 map<key_type, T>::upper_bound (const key_type& x) const
604 {
606  it.iiterator = imap.upper_bound(x);
607  if (it.iiterator != imap.end())
608  {
609  it.registered_owner = registered_as;
610  it.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
611  it.i_end_iterator = imap.end();
612  }
613  else
614  {
615  it.registered_owner = 0;
616  it.last_updated_container = 0;
617  }
618 
619  return it;
620 }
621 
622 
623 
624 
625 // modifiers
626 template <typename key_type, typename T>
627 unsigned map<key_type, T>::erase (const key_type& x)
628 {
629  internal_for_containers::register_container_size_change(registered_as);
630  return unsigned(imap.erase(x));
631 }
632 
633 
634 template <typename key_type, typename T>
636 {
637  if (position.registered_owner != registered_as)
638  throw jle::alarm(JLE_HERE, "map", "erase with extrange iterator", jle::al::priority::error);
639  if (position.iiterator == imap.end())
640  throw jle::alarm(JLE_HERE, "map", "erase over end iterator", jle::al::priority::error);
641  if (position.is_valid() == false)
642  throw jle::alarm(JLE_HERE, "map", "erase over iterator invalid", jle::al::priority::error);
643 
644 
645 
646  internal_for_containers::register_container_size_change(registered_as);
647 
648  typename map<key_type, T>::iterator result;
649  result.iiterator = ++(position.iiterator);
650  --(position.iiterator);
651  imap.erase(position.iiterator);
652 
653  result.registered_owner = registered_as;
654  result.i_end_iterator = imap.end();
655  if (imap.empty()==false)
656  result.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
657  else
658  result.last_updated_container = 0; // no valid value
659 
660  return result;
661 }
662 
663 template <typename key_type, typename T>
664 void map<key_type, T>::erase (const iterator& first, const iterator& last)
665 {
666  if (first.registered_owner != registered_as || last.registered_owner != registered_as)
667  throw jle::alarm(JLE_HERE, "map", "erase with extrange iterator (first or second)", jle::al::priority::error);
668  if (first.iiterator == imap.end())
669  throw jle::alarm(JLE_HERE, "map", "erase over end iterator (first)", jle::al::priority::error);
670  if (first.is_valid() == false)
671  throw jle::alarm(JLE_HERE, "map", "erase over iterator invalid (first)", jle::al::priority::error);
672 
673  typename map<key_type, T>::iterator result;
674 
675  internal_for_containers::register_container_size_change(registered_as);
676 
677  if (first == last)
678  {
679  imap.erase(first.iiterator);
680  }
681  else
682  {
683  //std::pair <int,int> pair_last;
684  //pair_last = *imap.lower_bound(last.iiterator->second);
685  //if ((imap.value_comp() (*first.iiterator, pair_last)) == true )
686 
687  if ((imap.value_comp() (*first.iiterator, *last.iiterator)) == true )
688  {
689  // True (sorted first ... last)
690  imap.erase(first.iiterator, last.iiterator);
691  }
692  else
693  {
694  // False (NO sorted last ... first)
695  throw jle::alarm(JLE_HERE, "map", "erase over iterators with invalid order (first > last)", jle::al::priority::error);
696  }
697  }
698 }
699 
700 template <typename key_type, typename T>
701 std::pair<typename map<key_type, T>::iterator, bool> map<key_type, T>::insert (const std::pair<key_type, T>& x )
702 {
703  internal_for_containers::register_container_size_change(registered_as);
704  std::pair<typename std::map<key_type, T>::iterator, bool> presult = imap.insert(x);
705 
706  typename map<key_type, T>::iterator it;
707  it.registered_owner = registered_as;
708  it.iiterator = presult.first;
709  it.last_updated_container = internal_for_containers::get_registered_container_last_size_change(registered_as);
710  it.i_end_iterator = imap.end();
711 
712  return std::make_pair(it, presult.second);
713 }
714 
715 
716 
717 
718 
719 
720 
721 
722 //---------------------------------------------------------------------------
723 } // namespace jle {
724 
725 
726 #endif
Definition: map.hpp:52
Definition: alarm.h:95
Definition: map.hpp:20
Definition: map.hpp:24
generic namespace
Definition: alarm.cpp:12