acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
integer_biunique.h
1#pragma once
2
3
4//#include "acme/prototype/prototype/matter.h"
5#include "acme/prototype/collection/map.h"
6#include "acme/prototype/collection/integer_map.h"
7
8
9template < class T, class T_to_T = map_base < T, T > >
10class biunique :
11 virtual public ::matter
12{
13public:
14
15
16 biunique();
17 virtual ~biunique()
18 {
19 }
20
21 bool has_a(T a) const;
22 bool has_b(T b) const;
23
24
25 T calc_max_a();
26 T calc_max_b();
27
28
29 T erase_a(T a);
30 T erase_b(T b);
31
32 T array_translate_a(T aNew, T aOld);
33
34 T translate_a(T a1, T a2);
35 T translate_b(T b1, T b2);
36
37
38 T get_a(T b) const;
39 T get_b(T a) const;
40 void set(T a, T b);
41
42 void __swap(T a1, T a2);
43
44 T operator [](T a) const
45 {
46 return get_b(a);
47 }
48
49 T get_max_a() const;
50 T get_max_b() const;
51
52 void erase_all();
53
54 void set_empty_a(T iEmpty);
55 void set_empty_b(T iEmpty);
56
57 T get_free_a() const;
58 T get_free_b() const;
59
60 T add(T b);
61 T add_b_in_first_free_a(T b);
62 T add_b_in_first_free_a_mod_w(T b, T w, T mod);
63 T add_unique(T b);
64 T get_size() const;
65
66 void copy_data(const biunique & ia);
67
68 //virtual ::stream & write(::stream & stream) const override;
69//virtual ::stream & read(::stream & stream) override;
70
71 biunique & operator = (const biunique & ia);
72
73 void biunivoca(bool b = true);
74
75 bool m_bBiunivoca;
76 T m_iMaxA;
77 T m_iMaxB;
78 T m_iEmptyA;
79 T m_iEmptyB;
80 T_to_T m_ab;
81 T_to_T m_ba;
82};
83
84
85
86template < class T, class T_to_T >
87biunique < T, T_to_T > ::biunique()
88{
89 m_bBiunivoca = true;
90 m_iEmptyA = -1;
91 m_iEmptyB = -1;
92 m_iMaxA = -1;
93 m_iMaxB = -1;
94}
95
96
97template < class T, class T_to_T >
98void biunique < T, T_to_T > ::biunivoca(bool b)
99{
100 m_bBiunivoca = b;
101}
102
103template < class T, class T_to_T >
104T biunique < T, T_to_T > ::get_a (T b) const
105{
106
107 return m_ba.defer_get(b, m_iEmptyA);
108
109}
110
111
112template < class T, class T_to_T >
113T biunique < T, T_to_T > ::get_b (T a) const
114{
115
116 return m_ab.defer_get(a, m_iEmptyB);
117
118}
119
120template < class T, class T_to_T >
121T biunique < T, T_to_T > ::erase_a(T a)
122{
123
124 if(has_a(a))
125 {
126
127 T b = get_b(a);
128
129 m_ba.erase(b);
130
131 m_ab.erase(a);
132
133 m_iMaxA = calc_max_a();
134
135 m_iMaxB = calc_max_b();
136
137 return b;
138
139 }
140
141 return m_iEmptyB;
142
143}
144
145
146template < class T, class T_to_T >
147T biunique < T, T_to_T > ::array_translate_a(T aNew, T aOld)
148{
149
150 if (aOld < 0 || aNew < 0)
151 {
152
153 return m_iEmptyB;
154
155 }
156
157 T bParam = get_b(aOld);
158
159 if (bParam == m_iEmptyB)
160 {
161
162 return m_iEmptyB;
163
164 }
165
166 if (aNew == aOld)
167 {
168
169 return bParam;
170
171 }
172
173 m_ba.erase(bParam);
174
175 m_ab.erase(aOld);
176
177 m_iMaxA = calc_max_a();
178
179 m_iMaxB = calc_max_b();
180
181 //if (aNew > aOld)
182 //{
183 // T a = aOld;
184 // while (a + 1 <= m_iMaxA)
185 // {
186 // T b = get_b(a + 1);
187 // if (b == m_iEmptyB)
188 // {
189 // break;
190 // }
191 // m_ba.erase_key(b);
192 // m_ab.erase_key(a + 1);
193 // m_ba.set_at(b, a);
194 // m_ab.set_at(a, b);
195 // m_iMaxA = calc_max_a();
196 // m_iMaxB = calc_max_b();
197 // a++;
198 // }
199 //}
200
201 // making room
202 if (has_a(aNew))
203 {
204
205 T a = aNew;
206
207 T b;
208
209 while (true)
210 {
211
212 a++;
213
214 if (a > m_iMaxA)
215 {
216
217 break;
218
219 }
220
221 b = get_b(a);
222
223 if (b == m_iEmptyB)
224 {
225
226 break;
227
228 }
229
230 }
231
232 a--;
233
234 while (a >= aNew)
235 {
236
237 b = get_b(a);
238
239 if (b != m_iEmptyB)
240 {
241
242 m_ba.erase(b);
243
244 m_ab.erase(a);
245
246 m_ba.set_at(b, a + 1);
247
248 m_ab.set_at(a + 1, b);
249
250 }
251
252 a--;
253
254 }
255
256 }
257
258 // actually (in)se(r)tting
259 m_ba.set_at(bParam, aNew);
260
261 m_ab.set_at(aNew, bParam);
262
263 m_iMaxA = calc_max_a();
264
265 m_iMaxB = calc_max_b();
266
267 return bParam;
268
269}
270
271
272template < class T, class T_to_T >
273T biunique < T, T_to_T > ::erase_b(T b)
274{
275
276 if(has_b(b))
277 {
278
279 T a = get_a(b);
280
281 m_ab.erase(a);
282
283 m_ba.erase(b);
284
285 m_iMaxA = calc_max_a();
286
287 m_iMaxB = calc_max_b();
288
289 return a;
290
291 }
292
293 return m_iEmptyA;
294
295}
296
297
298template < class T, class T_to_T >
299T biunique < T, T_to_T > ::translate_a(T a1, T a2)
300{
301
302 T b = erase_a(a2);
303
304 set(a1, b);
305
306 return b;
307
308}
309
310
311template < class T, class T_to_T >
312T biunique < T, T_to_T > ::translate_b(T b1, T b2)
313{
314
315 T a = erase_b(b2);
316
317 set(a, b1);
318
319 return a;
320
321}
322
323
324template < class T, class T_to_T >
325void biunique < T, T_to_T > ::set(T a, T b)
326{
327
328 if(m_bBiunivoca)
329 {
330
331 if (has_a(a))
332 {
333
334 erase_a(a);
335
336 }
337
338 if (has_b(b))
339 {
340
341 erase_b(b);
342
343 }
344
345 }
346
347 m_ab.set_at(a, b);
348
349 m_ba.set_at(b, a);
350
351 m_iMaxA = calc_max_a();
352
353 m_iMaxB = calc_max_b();
354
355}
356
357
358template < class T, class T_to_T >
359T biunique < T, T_to_T > ::get_max_a() const
360{
361
362 return m_iMaxA;
363
364}
365
366
367template < class T, class T_to_T >
368T biunique < T, T_to_T > ::get_max_b() const
369{
370
371 return m_iMaxB;
372
373}
374
375
376template < class T, class T_to_T >
377void biunique < T, T_to_T > ::erase_all()
378{
379
380 m_ab.erase_all();
381
382 m_ba.erase_all();
383
384 m_iMaxA = -1;
385
386 m_iMaxB = -1;
387
388}
389
390
391template < class T, class T_to_T >
392void biunique < T, T_to_T > ::set_empty_a(T iEmpty)
393{
394
395 m_iEmptyA = iEmpty;
396
397}
398
399
400template < class T, class T_to_T >
401void biunique < T, T_to_T > ::set_empty_b(T iEmpty)
402{
403
404 m_iEmptyB = iEmpty;
405
406}
407
408
409template < class T, class T_to_T >
410void biunique < T, T_to_T > ::copy_data(const biunique & function)
411{
412
413 if(&function != this)
414 {
415
416 m_ab = function.m_ab;
417
418 m_ba = function.m_ba;
419
420 }
421
422}
423
424
425template < class T, class T_to_T >
426T biunique < T, T_to_T > ::add(T b)
427{
428
429 T a = get_max_a() + 1;
430
431 set(a, b);
432
433 return a;
434
435}
436
437
438template < class T, class T_to_T >
439T biunique < T, T_to_T > ::add_b_in_first_free_a(T b)
440{
441
442 T a = get_free_a();
443
444 set(a, b);
445
446 return a;
447
448}
449
450
451template < class T, class T_to_T >
452T biunique < T, T_to_T > ::add_b_in_first_free_a_mod_w(T b, T w, T mod)
453{
454
455 if (mod <= 1)
456 {
457
458 return add_b_in_first_free_a(b);
459
460 }
461
462 if (w <= 0)
463 {
464
465 return add_b_in_first_free_a(b);
466
467 }
468
469 T ca = get_max_a() + 1;
470
471 T a;
472
473 for(a = 0; a < ca ; a++)
474 {
475
476 if((a % mod) >= w)
477 {
478
479 a = ((a / mod) + 1) * mod;
480
481 }
482
483 if(get_b(a) == m_iEmptyB)
484 {
485
486 set(a, b);
487
488 return a;
489
490 }
491
492 }
493
494 set(a, b);
495
496 return a;
497
498}
499
500
501template < class T, class T_to_T >
502T biunique < T, T_to_T > ::add_unique(T b)
503{
504
505 if (auto iterator = m_ba.find(b))
506 {
507
508 return iterator->element2();
509
510 }
511
512 auto a = get_max_a() + 1;
513
514 set(a, b);
515
516 return a;
517
518}
519
520
521template < class T, class T_to_T >
522T biunique < T, T_to_T > ::get_size() const
523{
524
525 return get_max_a() + 1;
526
527}
528
529
530template < class T, class T_to_T >
531void biunique < T, T_to_T > ::__swap(T a1, T a2)
532{
533
534 // because of Biunivoca
535
536 T b1 = get_b(a1);
537
538 T b2 = get_b(a2);
539
540 set(a1, b2);
541
542 set(a2, b1);
543
544}
545
546
547template < class T, class T_to_T >
548bool biunique < T, T_to_T > ::has_a(T a) const
549{
550
551 return m_ab.has(a);
552
553}
554
555
556template < class T, class T_to_T >
557bool biunique < T, T_to_T > ::has_b(T b) const
558{
559
560 return m_ba.has(b);
561
562}
563
564
565template < class T, class T_to_T >
566T biunique < T, T_to_T > ::get_free_a() const
567{
568
569 for(T a = 0; a <= m_iMaxA; a++)
570 {
571
572 if (!has_a(a))
573 {
574
575 return a;
576
577 }
578
579 }
580
581 return m_iMaxA + 1;
582
583}
584
585
586template < class T, class T_to_T >
587T biunique < T, T_to_T > ::get_free_b() const
588{
589
590 for(T b = 0; b <= m_iMaxB; b++)
591 {
592
593 if (!has_b(b))
594 {
595
596 return b;
597
598 }
599
600 }
601
602 return m_iMaxB + 1;
603
604}
605
606
607template < class T, class T_to_T >
608biunique < T, T_to_T > & biunique < T, T_to_T > ::operator = (const biunique & ia)
609{
610
611 if(this != &ia)
612 {
613
614 m_bBiunivoca = ia.m_bBiunivoca;
615
616 m_iMaxA = ia.m_iMaxA;
617
618 m_iMaxB = ia.m_iMaxB;
619
620 m_iEmptyA = ia.m_iEmptyA;
621
622 m_iEmptyB = ia.m_iEmptyB;
623
624 m_ab = ia.m_ab;
625
626 m_ba = ia.m_ba;
627
628 }
629
630 return *this;
631
632}
633
634
635//template < class t1, class t2, class t3, class t4 >
636//void serialize_write(stream & ostream, map_base < t1, t2, t3, t4 > & m)
637//{
638// ::collection::count count = m.get_count();
639// typename map_base < t1, t2, t3, t4 >::assoc * passoc = m.get_start();
640// ostream << count;
641// while(passoc != nullptr)
642// {
643// ostream << passoc->element1();
644// ostream << passoc->element2();
645// passoc = m.get_next(passoc);
646// }
647//}
648//
649//template < class t1, class t2, class t3, class t4 >
650//void serialize_read(stream & istream, map_base < t1, t2, t3, t4 > & m)
651//{
652// try
653// {
654// t1 iCount;
656// // m.get_start();
657// istream >> iCount;
658// t1 key;
659// t3 value;
660// m.erase_all();
661// for(::i32 i = 0; i < iCount; i++)
662// {
663// istream >> key;
664// istream >> value;
665// m.set_at(key, value);
666// }
667// }
668// catch(const ::scoped_string & scopedstr)
669// {
670// m.erase_all();
671// throw ::exception(scopedstr);
672// }
673//}
674//
675//
676//template < class T, class T_to_T >
677//inline stream & operator << (stream & stream, const biunique < T, T_to_T > &biunique)
678//{
679//
680// stream << biunique.m_bBiunivoca;
681// stream << biunique.m_iMaxA;
682// stream << biunique.m_iMaxB;
683// stream << biunique.m_iEmptyA;
684// stream << biunique.m_iEmptyB;
685//
686// if (biunique.m_bBiunivoca)
687// {
688// stream << biunique.m_ab;
689// }
690// else
691// {
692// stream << biunique.m_ab;
693// stream << biunique.m_ba;
694// }
695//
696// return stream;
697//
698//}
699//
700//
701//template < class T, class T_to_T >
702//inline stream & operator >> (stream & stream, biunique < T, T_to_T > & biunique)
703//{
704//
705// stream >> biunique.m_bBiunivoca;
706// stream >> biunique.m_iMaxA;
707// stream >> biunique.m_iMaxB;
708// stream >> biunique.m_iEmptyA;
709// stream >> biunique.m_iEmptyB;
710//
711// try
712// {
713// if (biunique.m_bBiunivoca)
714// {
715// T_to_T ab;
716// stream >> ab;
717// typename T_to_T::assoc * passoc = ab.get_start();
718// while (passoc != nullptr)
719// {
720// biunique.set(passoc->element1(), passoc->element2());
721// passoc = ab.get_next(passoc);
722// }
723// }
724// else
725// {
726// stream >> biunique.m_ab;
727// stream >> biunique.m_ba;
728// }
729// }
730// catch (const ::scoped_string & scopedstr)
731// {
732// biunique.m_ab.erase_all();
733// biunique.m_ba.erase_all();
734// biunique.m_bBiunivoca = true;
735// biunique.m_iEmptyA = -1;
736// biunique.m_iEmptyB = -1;
737// biunique.m_iMaxA = -1;
738// biunique.m_iMaxB = -1;
739// throw ::exception(scopedstr);
740// }
741//
742// return stream;
743//
744//}
745
746
747template < class T, class T_to_T >
748T biunique < T, T_to_T > ::calc_max_a()
749{
750
751 auto passoc = m_ab.begin();
752
753 T iMaxA = -1;
754
755 while(passoc.is_set())
756 {
757
758 if (passoc->element1() > iMaxA)
759 {
760
761 iMaxA = passoc->element1();
762
763 }
764
765 passoc++;
766
767 }
768
769 return iMaxA;
770
771}
772
773
774template < class T, class T_to_T >
775T biunique < T, T_to_T > ::calc_max_b()
776{
777
778 auto passoc = m_ba.begin();
779
780 T iMaxB = -1;
781
782 while(passoc.is_set())
783 {
784
785 if (passoc->element1() > iMaxB)
786 {
787
788 iMaxB = passoc->element1();
789
790 }
791
792 passoc++;
793
794 }
795
796 return iMaxB;
797
798}
799
800
801class CLASS_DECL_ACME index_biunique :
802 public biunique < ::collection::index >
803{
804public:
805
806
807 index_biunique();
808 ~index_biunique() override {}
809
810
811};
812
813
814class CLASS_DECL_ACME i32_biunique :
815 public biunique < ::i32, i32_to_int >
816{
817public:
818
819
820 i32_biunique();
821 virtual ~i32_biunique() {}
822
823
824};
825
826
827CLASS_DECL_ACME ::collection::index array_translate_a(index_biunique & ia, ::collection::index aNew, ::collection::index aOld);
828
829
830
Definition integer_biunique.h:12
Definition _template_forward_declaration.h:297
Definition integer_biunique.h:803
Definition std_iterator.h:49