acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
numeric_array.h
1#pragma once
2
3
4#include "raw_array.h"
5#include "comparable_eq_array.h"
6#include "comparable_array.h"
7#include "comparable_raw_array.h"
8#include "acme/prototype/prototype/compare_predicate.h"
9#include "acme/prototype/prototype/make_particle.h"
10#include "acme/prototype/mathematics/numeric.h"
11
12
13template < typename ARG_TYPE >
14::collection::index numeric_compare(ARG_TYPE t1, ARG_TYPE t2)
15{
16 typename ::non_reference < ARG_TYPE >::TYPE t = t1 - t2;
17 if(t > ::numeric_info< typename ::non_reference < ARG_TYPE >::TYPE >::null())
18 return 1;
19 else if(t < ::numeric_info < typename ::non_reference < ARG_TYPE >::TYPE >::null())
20 return -1;
21 else
22 return 0;
23}
24
25//template < >
26//inline ::i64 from_string(const ::scoped_string & scopedstr)
27//{
28// return to_i64(string(scopedstr));
29//}
30
31
32
33
34template < typename TYPE, enum_type t_etypeContainer >
36 public comparable_raw_array_base < TYPE, TYPE, ::typed::nodef < TYPE >, ::heap::typed_memory < TYPE, ::heap::e_memory_array >, t_etypeContainer >
37{
38public:
39
40
41 using BASE_ARRAY = comparable_raw_array_base < TYPE, TYPE, ::typed::nodef < TYPE >, ::heap::typed_memory < TYPE, ::heap::e_memory_array >, t_etypeContainer >;
42 using BASE_TYPE = TYPE;
43 using BASE_ARG_TYPE = const TYPE &;
44
45
46 using BASE_ARRAY::BASE_ARRAY;
47 using BASE_ARRAY::operator =;
48
49 //numeric_array_base() = default;
50
51
52 //numeric_array_base(const std::initializer_list < TYPE > & initializerlist):
53 // BASE_ARRAY(initializerlist)
54 //{
55
56 //}
57
58 //numeric_array_base(const TYPE * pa, ::collection::count c) :
59 // numeric_array_base(pa, c)
60 //{
61
62
63 //}
64
65
66 //numeric_array_base(const numeric_array_base & array) :
67 //BASE_ARRAY(array)
68 //{
69
70 //}
71
72 //numeric_array_base(numeric_array_base && array) noexcept :
73 //BASE_ARRAY(::transfer(array))
74 //{
75 //}
76
77
78 //DECLARE_AND_IMPLEMENT_DEFAULT_CONSTRUCTION_AND_ASSIGNMENT(numeric_array_base, comparable_raw_array < TYPE >)
79
80 //using BASE_ARRAY = comparable_raw_array < TYPE, TYPE, ::typed::nodef < TYPE >, ::heap::typed_memory < TYPE, ::heap::e_memory_array >, t_etypeContainer >;
81
82
83 ::collection::index find_first_maximum_value() const;
84 const TYPE & get_maximum_value() const;
85 ::collection::index find_first_minimum_value() const;
86 const TYPE & get_minimum_value() const;
87
88
89 template < prototype_integral INTEGRAL >
90 INTEGRAL & mask(INTEGRAL & i)
91 {
92
93 i = 0;
94
95 for(auto number : *this)
96 {
97
98 i |= number;
99
100 }
101
102 return i;
103
104 }
105
106 void push_last();
107
108
109 TYPE pop_max();
110 TYPE pop_max_last_add_up(TYPE tLastAddUp);
111
112 TYPE get_sum(::collection::index first = 0, ::collection::count in_count_out_last = -1) const
113 {
114
115 this->prepare_first_in_count_last_out(first, in_count_out_last);
116
117 TYPE t = ::numeric_info < TYPE >:: null();
118
119 for(::collection::index i = first; i <= in_count_out_last; i++)
120 {
121
122 // TODO: numeric calculus
123
124 t += this->element_at(i);
125
126 }
127
128 return t;
129
130 }
131
132
133 TYPE pop_to();
134
135
136 void CopySorted(const numeric_array_base & array, const TYPE & tOffset, const TYPE & tMin);
137
138 void Diff(
139 const numeric_array_base & array1,
140 const numeric_array_base & array2);
141
142 void divide(TYPE i);
143
144 void ElementDiff(
145 const numeric_array_base & array1,
146 const TYPE & tMax);
147
148 TYPE simple_total_mean();
149
150 void set(const TYPE & t, ::collection::index iStart = 0, ::collection::index iEnd = -1);
151
152 ::collection::index Cmp(const numeric_array_base & array1);
153
154
155 numeric_array_base unique() const;
156 void unique();
157
158
159
160
161 numeric_array_base operator - (const numeric_array_base & a) const;
162 numeric_array_base operator + (const numeric_array_base & a) const;
163
164 numeric_array_base & operator -= (const numeric_array_base & a);
165 numeric_array_base & operator += (const numeric_array_base & a);
166
167
168
169 ::i32 compare(const numeric_array_base & a) const
170 {
171
172 ::collection::count iCompare = this->get_size() - a.get_size();
173
174 if (iCompare != 0)
175 {
176
177 return ::numeric::sign(iCompare);
178
179 }
180
181 TYPE t;
182 for(::collection::index i = 0; i < this->get_size(); i++)
183 {
184
185 t = this->element_at(i) - a[i];
186
187 if (t != 0)
188 {
189
190 return ::numeric::sign(t);
191
192 }
193
194 }
195
196 return 0;
197
198 }
199
200
201 /*using comparable_raw_array_base < TYPE, TYPE, ::typed::nodef < TYPE >, ::heap::typed_memory < TYPE, ::heap::e_memory_array >, t_etypeContainer >::operator =;
202 numeric_array_base & operator = (const numeric_array_base & a)
203 {
204
205 BASE_ARRAY::operator = (a);
206
207 return *this;
208
209 }
210
211
212 numeric_array_base & operator = (numeric_array_base && a)
213 {
214 transfer(::transfer(a));
215 return *this;
216 }*/
217
218
219 //numeric_array_base & transfer (numeric_array_base && a)
220 //{
221 // BASE_ARRAY::transfer(::transfer(a));
222 // return *this;
223 //}
224
225
226 //void sort(bool bAsc = true);
227
228 bool is_any_set() const
229 {
230
231 return this->predicate_contains([](auto number) {return number != (TYPE)0; });
232
233 }
234
235
236};
237
238
239
240template < typename TYPE, ::enum_type t_etypeContainer >
241class unique_number_sort_array :
242 public numeric_array_base < TYPE, t_etypeContainer >
243{
244public:
245 unique_number_sort_array();
246 unique_number_sort_array(const unique_number_sort_array & array);
247
248 ::collection::index add(const TYPE & newElement)
249 {
250 ::collection::index iFind = 0;
251 if(find(newElement, iFind))
252 {
253 return -1;
254 }
255 else
256 {
257 this->insert_at(iFind, newElement);
258 return iFind;
259 }
260 }
261
262 bool find(const TYPE &t, ::collection::index & find) const
263 {
264 ::collection::index iL = find;
265 ::collection::index iU = this->get_upper_bound();
266 while(iU - iL > 5)
267 {
268 find = (iL + iU) / 2;
269 TYPE tCmp = t - this->element_at(find);
270 if(tCmp == numeric_info < TYPE > :: null ())
271 {
272 return true;
273 }
274 else if(tCmp > numeric_info < TYPE >::null())
275 {
276 iL = find + 1;
277 }
278 else
279 {
280 iU = find - 1;
281 }
282 }
283 for(; find < this->get_size(); find++)
284 {
285 TYPE tCmp = t - this->element_at(find);
286 if(tCmp == numeric_info < TYPE >::null())
287 {
288 return true;
289 }
290 else if(tCmp < numeric_info < TYPE >::null())
291 {
292 return false;
293 }
294 }
295 return false;
296 }
297
298 /*::collection::index find_first_maximum_value();
299 TYPE & get_maximum_value();
300
301 void CopySorted(
302 const numeric_array_base < TYPE > & array, // this array is sorted
303 TYPE & tOffset,
304 TYPE & tMin);
305
306 void Diff(
307 const numeric_array_base < TYPE > & array1,
308 const numeric_array_base < TYPE > & array2);*/
309
310 //void divide(::i32 i);
311
312 //void ElementDiff(
313 // const numeric_array_base < TYPE > & array1,
314 //TYPE & tMax);
315
316 //TYPE GetMean();
317
318 //void set(const TYPE & t, ::i32 iStart = 0, ::i32 iEnd = -1);
319
320 //::i32 Cmp(const numeric_array_base < TYPE > & array1);
321
322
323 /*virtual void quick_sort(bool bAsc = true)
324 {
325 if(bAsc)
326 {
327 sort::QuickSortAsc(*this);
328 }
329 else
330 {
331 sort::QuickSortDesc(*this);
332 }
333 }*/
334
335
336};
337
338
339
340//template < typename T >
341//string & to_network_payload(string & str, const T & t, bool bNewLine);
342
343
344//template < typename TYPE, ::enum_type t_etypeContainer >
345//string & numeric_array_base < TYPE, t_etypeContainer >::get_network_payload(string & str, bool bNewLine) const
346//{
347//
348//
349// str += "[";
350//
351// if(this->get_count() > 0)
352// {
353//
354// to_network_payload(str, this->element_at(0), bNewLine);
355//
356// }
357//
358// for (::collection::index i = 1; i < this->get_count(); i++)
359// {
360//
361// if (bNewLine)
362// {
363//
364// str += ", \r\n";
365//
366// }
367// else
368// {
369//
370// str += ", ";
371//
372// }
373//
374// to_network_payload(str, this->element_at(i), bNewLine);
375//
376// }
377//
378// if (bNewLine)
379// {
380//
381// str += "\r\n";
382//
383// }
384//
385// str += "]";
386//
387// return str;
388//
389//}
390
391
392//template < typename TYPE, ::enum_type t_etypeContainer >
393//void numeric_array_base < TYPE, t_etypeContainer >::implode(string & str, const ::scoped_string & scopedstrSeparator, ::collection::index start, ::collection::count count) const
394//
395//{
396// if(start < 0)
397// {
398// start += this->get_size();
399// }
400// ::collection::index last;
401// if(count < 0)
402// {
403// last = this->get_size() + count;
404// }
405// else
406// {
407// last = start + count - 1;
408// }
409// if(start <= last)
410// {
411//
412// ::collection::index i = start;
413//
414// ::copy(str, this->element_at(i));
415//
416// i++;
417// for(; i <= last; i++)
418// {
419// str += scopedstrSeparator + as_string(this->element_at(i));
420// }
421// }
422// else
423// {
424//
425// str.empty();
426//
427// }
428//
429//}
430
431
432//template < typename TYPE, ::enum_type t_etypeContainer >
433//string numeric_array_base < TYPE, t_etypeContainer >::implode(const ::scoped_string & scopedstrSeparator, ::collection::index iStart, ::collection::index iEnd) const
434//{
435//
436// string str;
437//
438// implode(str, scopedstrSeparator, iStart, iEnd);
439//
440// return str;
441//
442//}
443
444
445
446//template < typename TYPE, ::enum_type t_etypeContainer >
447//void numeric_array_base < TYPE, t_etypeContainer >::each_add(const TYPE & t,::collection::index i, ::collection::count iEnd)
448//{
449//
450// if(iEnd == 0)
451// return ;
452//
453// if(iEnd < 0)
454// {
455//
456// iEnd += get_size();
457//
458// }
459// else
460// {
461//
462// iEnd--;
463//
464// }
465//
466// if(i < 0)
467// {
468//
469// i += get_size();
470//
471// }
472//
473// if(i < 0)
474// {
475//
476// iEnd += i;
477//
478// i = 0;
479//
480// }
481//
482// while(i <= iEnd)
483// {
484//
485// element_at(i) += t;
486//
487// i++;
488//
489// }
490//
491//
492//}
493//
494//template < typename TYPE, ::enum_type t_etypeContainer >
495//void numeric_array_base < TYPE, t_etypeContainer >::each_subtract(const TYPE & t,::collection::index i,::collection::count iEnd)
496//{
497//
498// if(iEnd == 0)
499// return;
500//
501// if(iEnd < 0)
502// {
503//
504// iEnd += get_size();
505//
506// }
507// else
508// {
509//
510// iEnd--;
511//
512// }
513//
514// if(i < 0)
515// {
516//
517// i += get_size();
518//
519// }
520
521// if(i < 0)
522// {
523//
524// iEnd += i;
525//
526// i = 0;
527//
528// }
529//
530// while(i <= iEnd)
531// {
532//
533// element_at(i) -= t;
534//
535// i++;
536//
537// }
538//
539//}
540
541
542
543template < typename TYPE, ::enum_type t_etypeContainer >
544numeric_array_base < TYPE, t_etypeContainer > numeric_array_base < TYPE, t_etypeContainer >::unique() const
545{
546
547 numeric_array_base < TYPE, t_etypeContainer > a;
548
549 for(::i32 i = 0; i < this->get_count(); i++)
550 {
551 a.add_unique(this->element_at(i));
552 }
553
554 return a;
555
556}
557
558template < typename TYPE, ::enum_type t_etypeContainer >
559void numeric_array_base < TYPE, t_etypeContainer >::unique()
560{
561
562 numeric_array_base < TYPE, t_etypeContainer > a;
563
564 for(::i32 i = 0; i < this->get_count(); i++)
565 {
566 a.add_unique(this->element_at(i));
567 }
568
569 *this = a;
570
571}
572
573
574
575
576
577template < typename TYPE, ::enum_type t_etypeContainer >
578::collection::index numeric_array_base < TYPE, t_etypeContainer >::
579Cmp(const numeric_array_base & array1)
580{
581 ::collection::count iMinSize = minimum(array1.get_size(), this->get_size());
582 ::collection::index i = 0;
583 while(true)
584 {
585 if(i >= iMinSize)
586 {
587 return this->get_size() - array1.get_size();
588 }
589 if(this->element_at(i) > array1.element_at(i))
590 return 1;
591 else if(this->element_at(i) < array1.element_at(i))
592 return -1;
593 i++;
594 }
595}
596
597template < typename TYPE, ::enum_type t_etypeContainer >
598void numeric_array_base < TYPE, t_etypeContainer >::CopySorted(
600const TYPE & tOffset,
601const TYPE & tMin)
602{
603
604
605 ::collection::index i;
606 TYPE tStart = tMin - tOffset;
607 this->set_size(a.get_size());
608 TYPE t;
609 for(i = 0; i < a.get_size()
610 && a.get_at(i) <= tStart; i++)
611 {
612 this->set_at(i, tMin);
613 }
614 for(; i < a.get_size(); i++)
615 {
616 t = a.get_at(i) + tOffset;
617 this->set_at(i, t);
618 }
619}
620
621
622template < typename TYPE, ::enum_type t_etypeContainer >
623void numeric_array_base < TYPE, t_etypeContainer >::Diff(
624const numeric_array_base < TYPE, t_etypeContainer > & array1,
625const numeric_array_base < TYPE, t_etypeContainer > & array2)
626{
627 ASSERT(array1.get_size() == array2.get_size());
628 ::collection::index i;
629 this->set_size(array1.get_size());
630 TYPE t;
631 for(i = 0; i < array1.get_size(); i++)
632 {
633 t = array1.get_at(i) - array2.get_at(i);
634 this->set_at(i, t);
635 }
636}
637
638template < typename TYPE, ::enum_type t_etypeContainer >
639void numeric_array_base < TYPE, t_etypeContainer >::ElementDiff(
640const numeric_array_base & a,
641const TYPE & tMax)
642{
643 ::collection::index i;
644 TYPE t;
645 TYPE it;
646 this->set_size(a.get_size());
647 if(a.get_size() > 0)
648 {
649 TYPE tLast = a[0];
650 for(i = 1; i < a.get_size(); i++)
651 {
652 t = a[i];
653 it = t - tLast;
654 this->set_at(i - 1, it);
655 tLast = t;
656 }
657 it = tMax - tLast;
658 this->set_at(i - 1, it);
659 }
660}
661
662
663template < typename TYPE, ::enum_type t_etypeContainer >
664::collection::index numeric_array_base < TYPE, t_etypeContainer >::find_first_maximum_value() const
665{
666
667 TYPE tMax = this->element_at(0);
668
669 ::collection::index iFind = 0;
670
671 for(::collection::index i = 1; i < this->get_size(); i++)
672 {
673
674 if (this->element_at(i) > tMax)
675 {
676
677 iFind = i;
678
679 tMax = this->element_at(i);
680
681 }
682
683 }
684
685 return iFind;
686
687}
688
689
690template < typename TYPE, ::enum_type t_etypeContainer >
691const TYPE & numeric_array_base < TYPE, t_etypeContainer >::
692get_maximum_value() const
693{
694 ASSERT(this->get_size() > 0);
695 return this->element_at(find_first_maximum_value());
696}
697
698template < typename TYPE, ::enum_type t_etypeContainer >
699::collection::index numeric_array_base < TYPE, t_etypeContainer >::find_first_minimum_value() const
700{
701
702 TYPE tMin = this->element_at(0);
703
704 ::collection::index iFind = 0;
705
706 for (::collection::index i = 1; i < this->get_size(); i++)
707 {
708
709 if (this->element_at(i) < tMin)
710 {
711
712 iFind = i;
713
714 tMin = this->element_at(i);
715
716 }
717
718 }
719
720 return iFind;
721
722}
723
724
725template < typename TYPE, ::enum_type t_etypeContainer >
726const TYPE & numeric_array_base < TYPE, t_etypeContainer >::
727get_minimum_value() const
728{
729 ASSERT(this->get_size() > 0);
730 return this->element_at(find_first_minimum_value());
731}
732
733template < typename INTEGER >
734inline INTEGER get_integer_mean(const INTEGER * p, ::collection::count N)
735{
736 ::i64 x = 0;
737 ::i64 y = 0;
738 ::collection::count c = N;
739 while (c > 0)
740 {
741 ::i64 a = *p;
742 x += a / N;
743 if (a >= 0)
744 {
745 ::i32 b = (::i32) (a % N);
746 if (y >= N - b)
747 {
748 x++;
749 y -= N - b;
750 }
751 else
752 {
753 y += b;
754 }
755 }
756 else
757 {
758 ::i32 b = (::i32) ((-a) % N);
759 if (y <= -N + b)
760 {
761 x--;
762 y -= -N + b;
763 }
764 else
765 {
766 y -= b;
767 }
768 }
769 c--;
770 p++;
771 }
772 return (::i32) (x + y / N);
773
774}
775
776
777template < prototype_integral INTEGRAL >
778inline INTEGRAL simple_total_mean(const INTEGRAL * p, ::collection::count N)
779{
780
781 ::i64 i = 0;
782
783 ::collection::count c = N;
784
785 while(c > 0)
786 {
787
788 i += *p;
789
790 p++;
791
792 c--;
793
794 }
795
796 return (INTEGRAL) (i / N);
797
798}
799
800template < prototype_floating FLOATING >
801inline FLOATING simple_total_mean(const FLOATING * p, ::collection::count N)
802{
803
804 ::f64 d = 0.;
805
806 ::collection::count c = N;
807
808 while (c > 0)
809 {
810
811 d += *p;
812
813 p++;
814
815 c--;
816
817 }
818
819 return (FLOATING)(d / (::f64) N);
820
821}
822
823inline ::i32 get_mean(const ::i32 * A, ::collection::count N)
824{
825 return get_integer_mean(A, N);
826}
827
828
829template < typename TYPE, ::enum_type t_etypeContainer >
830TYPE numeric_array_base < TYPE, t_etypeContainer >::simple_total_mean()
831{
832
833 return ::simple_total_mean(this->get_data(), this->get_count());
834
835}
836
837
838template < typename TYPE, ::enum_type t_etypeContainer >
839void numeric_array_base < TYPE, t_etypeContainer >::set(const TYPE & t, ::collection::index iStart, ::collection::index iEnd)
840{
841 if(iEnd == -1)
842 iEnd = this->get_upper_bound();
843 for(::collection::index i = iStart; i <= iEnd; i++)
844 {
845 this->set_at(i, t);
846 }
847}
848
849
850template < typename TYPE, ::enum_type t_etypeContainer >
851void numeric_array_base < TYPE, t_etypeContainer >::divide(TYPE div)
852{
853 ::collection::index i;
854 for(i = 0; i < this->get_size(); i++)
855 {
856 this->element_at(i) = this->element_at(i) / div;
857 }
858}
859
860template < typename TYPE, ::enum_type t_etypeContainer >
861numeric_array_base < TYPE, t_etypeContainer > numeric_array_base < TYPE, t_etypeContainer >::operator - (const numeric_array_base < TYPE, t_etypeContainer > & a) const
862{
863
864 numeric_array_base < TYPE, t_etypeContainer > aRet(*this);
865
866 aRet.erase_array(a);
867
868 return aRet;
869
870}
871
872template < typename TYPE, ::enum_type t_etypeContainer >
873numeric_array_base < TYPE, t_etypeContainer > numeric_array_base < TYPE, t_etypeContainer >::operator + (const numeric_array_base < TYPE, t_etypeContainer > & a) const
874{
875
876 numeric_array_base < TYPE, t_etypeContainer > aRet(*this);
877
878 aRet.append(a);
879
880 return aRet;
881
882}
883
884template < typename TYPE, ::enum_type t_etypeContainer >
885numeric_array_base < TYPE, t_etypeContainer > & numeric_array_base < TYPE, t_etypeContainer >::operator -= (const numeric_array_base < TYPE, t_etypeContainer > & a)
886{
887
888 this->erase_array(a);
889
890 return *this;
891
892}
893
894template < typename TYPE, ::enum_type t_etypeContainer >
895numeric_array_base < TYPE, t_etypeContainer > & numeric_array_base < TYPE, t_etypeContainer >::operator += (const numeric_array_base < TYPE, t_etypeContainer > & a)
896{
897
898 this->append(a);
899
900 return *this;
901
902}
903
904
905
906template < typename TYPE, ::enum_type t_etypeContainer >
907inline void numeric_array_base < TYPE, t_etypeContainer > ::push_last()
908{
909
910 this->add(this->last());
911
912}
913
914
915template < typename TYPE, ::enum_type t_etypeContainer >
916inline TYPE numeric_array_base < TYPE, t_etypeContainer > ::pop_max()
917{
918
919 TYPE lastelement = this->last();
920
921 TYPE nowpop = this->pop();
922
923 this->last() = maximum(nowpop, lastelement);
924
925 return this->last();
926
927}
928
929
930
931template < typename TYPE, ::enum_type t_etypeContainer >
932inline TYPE numeric_array_base < TYPE, t_etypeContainer > ::pop_max_last_add_up(TYPE tLastAddUp)
933{
934
935 TYPE lastelement = this->last();
936
937 TYPE nowpop = this->pop();
938
939 this->last() = maximum(nowpop, lastelement + tLastAddUp);
940
941 return this->last();
942
943}
944
945
946
947template < typename TYPE, ::enum_type t_etypeContainer >
948inline TYPE numeric_array_base < TYPE, t_etypeContainer > ::pop_to()
949{
950
951 TYPE lastelement = this->pop();
952
953 this->last() = lastelement;
954
955 return this->last();
956
957}
958
959
960
961template < typename TYPE, ::enum_type t_etypeContainer >
962unique_number_sort_array < TYPE, t_etypeContainer >::
963unique_number_sort_array()
964{
965}
966
967template < typename TYPE, ::enum_type t_etypeContainer >
968unique_number_sort_array < TYPE, t_etypeContainer >::
969unique_number_sort_array(const unique_number_sort_array < TYPE, t_etypeContainer > & a)
970{
971 numeric_array_base < TYPE, t_etypeContainer > ::operator = (a);
972}
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026namespace acme
1027{
1028
1029 namespace numeric_array_base
1030 {
1031
1032 template < class ARRAY >
1033 typename ARRAY::BASE_TYPE big_average(const ARRAY & a)
1034 {
1035 ::collection::count c = a.get_count();
1036 if(c == 0)
1037 return 0.0;
1038 typename ARRAY::BASE_TYPE f = 0.0;
1039 typename ARRAY::BASE_TYPE fCount = (typename ARRAY::BASE_TYPE) c;
1040 for(::collection::index i = 0; i < c; i++)
1041 {
1042 f += a.element_at(i) / fCount;
1043 }
1044 return f;
1045 }
1046
1047 } // namespace numeric_array_base
1048
1049} // namespace acme
1050
1051
1052#include "numeric_array_range.h"
1053
1054
1055
1056namespace acme
1057{
1058
1059 namespace array
1060 {
1061
1062
1063 template<class ARRAY>
1064 bool binary_search(ARRAY & a,typename ARRAY::BASE_ARG_TYPE t,::collection::index & iIndex,::collection::index(* fCompare) (typename ARRAY::BASE_ARG_TYPE,typename ARRAY::BASE_ARG_TYPE));
1065
1066 template<class ARRAY, prototype_array INDEX_ARRAY >
1067 bool binary_search(ARRAY & a,typename ARRAY::BASE_ARG_TYPE t,::collection::index & iIndex, less_predicate_base < typename ARRAY::BASE_ARG_TYPE > * pcompare, INDEX_ARRAY & ia);
1068
1069 template<class ARRAY, prototype_array INDEX_ARRAY>
1070 ::collection::index sort_add(ARRAY & a,typename ARRAY::BASE_ARG_TYPE t,::collection::index(* fCompare) (typename ARRAY::BASE_ARG_TYPE,typename ARRAY::BASE_ARG_TYPE),INDEX_ARRAY & ia)
1071 {
1072 ::collection::index iIndex = 0;
1073 binary_search(a, t, iIndex, fCompare, ia);
1074 a.insert_at(iIndex, t);
1075 ia.add(iIndex);
1076 return iIndex;
1077 }
1078
1079 template<class ARRAY, class ARRAY2, prototype_array INDEX_ARRAY >
1080 ::collection::count sort_add_array(ARRAY & a,ARRAY2 & a2,::collection::index(* fCompare) (typename ARRAY::BASE_ARG_TYPE,typename ARRAY::BASE_ARG_TYPE),INDEX_ARRAY & ia)
1081 {
1082 for(::collection::index i = 0; i < a2.get_count(); i++)
1083 {
1084 sort_add(a,a2[i],fCompare,ia);
1085 }
1086 return a2.get_count();
1087 }
1088
1089
1090 template<class ARRAY, prototype_array INDEX_ARRAY >
1091 ::collection::count sort_erase(ARRAY & a,typename ARRAY::BASE_ARG_TYPE t,::collection::index(* fCompare) (typename ARRAY::BASE_ARG_TYPE,typename ARRAY::BASE_ARG_TYPE), INDEX_ARRAY & ia)
1092 {
1093 ::collection::count ca = 0;
1094 ::collection::index iFind = 0;
1095 while(binary_search(a,t, iFind, fCompare, ia))
1096 {
1097 a.erase_at(iFind);
1098 ::collection::index iIndex = ia[iFind];
1099 ia.erase_at(iFind);
1100 for(::collection::index i = 0; i < ia.get_size(); i++)
1101 {
1102 if(ia[i] > iIndex)
1103 {
1104 ia[i]--;
1105 }
1106 }
1107 iFind = 0;
1108 ca++;
1109 }
1110 return ca;
1111 }
1112
1113
1114
1115 } // namespace array
1116
1117
1118
1119
1120 template < typename TYPE, ::enum_type t_etypeContainer >
1121 numeric_array_each < ::numeric_array_base < TYPE, t_etypeContainer > > each(::numeric_array_base < TYPE, t_etypeContainer > & a) { return a; }
1122 template < typename TYPE, ::enum_type t_etypeContainer >
1123 numeric_array_each < ::numeric_array_base < TYPE, t_etypeContainer > > all(::numeric_array_base < TYPE, t_etypeContainer > & a) { return a; }
1124 template < typename TYPE, ::enum_type t_etypeContainer >
1125 numeric_array_each < ::numeric_array_base < TYPE, t_etypeContainer > > range(::numeric_array_base < TYPE, t_etypeContainer > & a) { return a; }
1126
1127 template < typename TYPE, ::enum_type t_etypeContainer >
1128 numeric_array_range < ::numeric_array_base < TYPE, t_etypeContainer > > each(::numeric_array_base < TYPE, t_etypeContainer > & a,::collection::index iBeg,::collection::count iCount) { return numeric_array_range < ::numeric_array_base < TYPE, t_etypeContainer > >(a,iBeg,iCount); }
1129 template < typename TYPE, ::enum_type t_etypeContainer >
1130 numeric_array_range < ::numeric_array_base < TYPE, t_etypeContainer > > all(::numeric_array_base < TYPE, t_etypeContainer > & a,::collection::index iBeg,::collection::count iCount) { return numeric_array_range < ::numeric_array_base < TYPE, t_etypeContainer > >(a,iBeg,iCount); }
1131 template < typename TYPE, ::enum_type t_etypeContainer >
1132 numeric_array_range < ::numeric_array_base < TYPE, t_etypeContainer > > range(::numeric_array_base < TYPE, t_etypeContainer > & a,::collection::index iBeg,::collection::count iCount) { return numeric_array_range < ::numeric_array_base < TYPE, t_etypeContainer > >(a,iBeg,iCount); }
1133
1134 template < typename TYPE, ::enum_type t_etypeContainer >
1135 void quick_sort(::numeric_array_base < TYPE, t_etypeContainer > & a, bool bAsc = true);
1136
1137 template < typename TYPE, ::enum_type t_etypeContainer >
1138 ::collection::count erase_greater_than(::numeric_array_base < TYPE, t_etypeContainer > & a,TYPE hi)
1139 {
1140
1141 ::collection::count ca = 0;
1142
1143 for(::collection::index i = a.get_upper_bound(); i >= 0; i--)
1144 {
1145 if(a.element_at(i) > hi)
1146 {
1147 a.erase_at(i);
1148 ca++;
1149 }
1150 }
1151
1152 return ca;
1153
1154 }
1155
1156
1157 template < typename TYPE, ::enum_type t_etypeContainer >
1158 ::collection::count erase_greater_than_or_equal(::numeric_array_base < TYPE, t_etypeContainer > & a,TYPE hi)
1159 {
1160
1161 ::collection::count ca = 0;
1162
1163 for(::collection::index i = a.get_upper_bound(); i >= 0; i--)
1164 {
1165 if(a.element_at(i) >= hi)
1166 {
1167 a.erase_at(i);
1168 ca++;
1169 }
1170 }
1171
1172 return ca;
1173
1174 }
1175
1176
1177 template < typename TYPE, ::enum_type t_etypeContainer >
1178 ::collection::count erase_lesser_than(::numeric_array_base < TYPE, t_etypeContainer > & a,TYPE lo)
1179 {
1180
1181 ::collection::count ca = 0;
1182
1183 for(::collection::index i = a.get_upper_bound(); i >= 0; i--)
1184 {
1185 if(a.element_at(i) < lo)
1186 {
1187 a.erase_at(i);
1188 ca++;
1189 }
1190 }
1191
1192 return ca;
1193
1194 }
1195
1196
1197 template < typename TYPE, ::enum_type t_etypeContainer >
1198 ::collection::count erase_lesser_than_or_equal(::numeric_array_base < TYPE, t_etypeContainer > & a,TYPE lo)
1199 {
1200
1201 ::collection::count ca = 0;
1202
1203 for(::collection::index i = a.get_upper_bound(); i >= 0; i--)
1204 {
1205 if(a.element_at(i) <= lo)
1206 {
1207 a.erase_at(i);
1208 ca++;
1209 }
1210 }
1211
1212 return ca;
1213
1214 }
1215
1216
1217 template < typename TYPE, ::enum_type t_etypeContainer >
1218 ::collection::count erase_lesser_than_or_greater_than(::numeric_array_base < TYPE, t_etypeContainer > & a,TYPE lo,TYPE hi)
1219 {
1220
1221 ::collection::count ca = 0;
1222
1223 for(::collection::index i = a.get_upper_bound(); i >= 0; i--)
1224 {
1225 if(a.element_at(i) < lo)
1226 {
1227 a.erase_at(i);
1228 ca++;
1229 }
1230 else if(a.element_at(i) > hi)
1231 {
1232 a.erase_at(i);
1233 ca++;
1234 }
1235 }
1236
1237 return ca;
1238
1239 }
1240
1241
1242 template < typename TYPE, ::enum_type t_etypeContainer >
1243 ::collection::count erase_lesser_than_or_greater_than_or_equal(::numeric_array_base < TYPE, t_etypeContainer > & a,TYPE lo,TYPE hi)
1244 {
1245
1246 ::collection::count ca = 0;
1247
1248 for(::collection::index i = a.get_upper_bound(); i >= 0; i--)
1249 {
1250 if(a.element_at(i) < lo)
1251 {
1252 a.erase_at(i);
1253 ca++;
1254 }
1255 else if(a.element_at(i) >= hi)
1256 {
1257 a.erase_at(i);
1258 ca++;
1259 }
1260 }
1261
1262 return ca;
1263
1264 }
1265
1266
1267 template < typename TYPE, ::enum_type t_etypeContainer >
1268 ::collection::count erase_lesser_than_or_equal_or_greater_than(::numeric_array_base < TYPE, t_etypeContainer > & a,TYPE lo,TYPE hi)
1269 {
1270
1271 ::collection::count ca = 0;
1272
1273 for(::collection::index i = a.get_upper_bound(); i >= 0; i--)
1274 {
1275 if(a.element_at(i) <= lo)
1276 {
1277 a.erase_at(i);
1278 ca++;
1279 }
1280 else if(a.element_at(i) > hi)
1281 {
1282 a.erase_at(i);
1283 ca++;
1284 }
1285 }
1286
1287 return ca;
1288
1289 }
1290
1291
1292 template < typename TYPE, ::enum_type t_etypeContainer >
1293 ::collection::count erase_lesser_than_or_equal_or_greater_than_or_equal(::numeric_array_base < TYPE, t_etypeContainer > & a, TYPE lo,TYPE hi)
1294 {
1295
1296 ::collection::count ca = 0;
1297
1298 for(::collection::index i = a.get_upper_bound(); i >= 0; i--)
1299 {
1300 if(a.element_at(i) <= lo)
1301 {
1302 a.erase_at(i);
1303 ca++;
1304 }
1305 else if(a.element_at(i) >= hi)
1306 {
1307 a.erase_at(i);
1308 ca++;
1309 }
1310 }
1311
1312
1313 return ca;
1314
1315 }
1316
1317} // namespace acme
1318
1319
1320//#include "sort.h"
1321
1322//template < typename TYPE, ::enum_type t_etypeContainer >
1323//void numeric_array_base < TYPE, t_etypeContainer >::sort(bool bAsc)
1324//{
1325//
1326// if (bAsc)
1327// {
1328//
1329// sort::QuickSortAsc(*this);
1330//
1331// }
1332// else
1333// {
1334//
1335// sort::QuickSortDesc(*this);
1336//
1337// }
1338//
1339//}
1340
1341
1342// using i32_2a = array < i32_array_base >;
1343
1344
1345// using f32_2a = array < f32_array >;
1346
1347
1348// using f64_2a = array < f64_array >;
1349
1350
1351
1352
1353
1354namespace acme
1355{
1356
1357
1358 namespace array
1359 {
1360
1361
1362 template < typename ARRAY1, typename ARRAY2 >
1363 inline bool is_equal(const ARRAY1 & a1, const ARRAY2 & a2)
1364 {
1365
1366 if (a1.get_count() != a2.get_count())
1367 {
1368
1369 return false;
1370
1371 }
1372
1373 for (::i32 i = 0; i < a1.get_count(); i++)
1374 {
1375
1376 if (a1[i] != a2[i])
1377 {
1378
1379 return false;
1380
1381 }
1382
1383 }
1384
1385 return true;
1386
1387 }
1388
1389
1390 template < typename ARRAY_TYPE, typename PRED >
1391 void predicate_sort(ARRAY_TYPE & a, PRED pred)
1392 {
1393
1394 index_array stackLowerBound;
1395
1396 index_array stackUpperBound;
1397
1398 iptr iLowerBound;
1399
1400 iptr iUpperBound;
1401
1402 iptr iLPos, iUPos, iMPos;
1403
1404 if (a.get_size() >= 2)
1405 {
1406
1407 stackLowerBound.push(0);
1408
1409 stackUpperBound.push(a.get_size() - 1);
1410
1411 while (true)
1412 {
1413
1414 iLowerBound = stackLowerBound.pop();
1415
1416 iUpperBound = stackUpperBound.pop();
1417
1418 iLPos = iLowerBound;
1419
1420 iMPos = iLowerBound;
1421
1422 iUPos = iUpperBound;
1423
1424 while (true)
1425 {
1426
1427 while (true)
1428 {
1429
1430 if (iMPos >= iUPos)
1431 {
1432
1433 goto break_mid_loop;
1434
1435 }
1436
1437 if (!pred(a[iUPos], a[iMPos]))
1438 {
1439
1440 iUPos--;
1441
1442 }
1443 else
1444 {
1445
1446 a.__swap(iMPos, iUPos);
1447
1448 break;
1449
1450 }
1451
1452 }
1453
1454 iMPos = iUPos;
1455
1456 while (true)
1457 {
1458
1459 if (iLPos >= iMPos)
1460 {
1461
1462 goto break_mid_loop;
1463
1464 }
1465
1466 if (!pred(a[iMPos], a[iLPos]))
1467 {
1468
1469 iLPos++;
1470
1471 }
1472 else
1473 {
1474
1475 a.__swap(iLPos, iMPos);
1476
1477 break;
1478
1479 }
1480
1481
1482 }
1483
1484 iMPos = iLPos;
1485
1486 }
1487
1488 break_mid_loop:
1489
1490 if (iLowerBound < iMPos - 1)
1491 {
1492
1493 stackLowerBound.push(iLowerBound);
1494
1495 stackUpperBound.push(iMPos - 1);
1496
1497 }
1498
1499 if (iMPos + 1 < iUpperBound)
1500 {
1501
1502 stackLowerBound.push(iMPos + 1);
1503
1504 stackUpperBound.push(iUpperBound);
1505
1506 }
1507
1508 if (stackLowerBound.count() == 0)
1509 {
1510
1511 break;
1512
1513 }
1514
1515 }
1516
1517 }
1518
1519 }
1520
1521 template < typename ARRAY_TYPE, typename T, typename PRED >
1522 iptr predicate_binary_search(const ARRAY_TYPE & a, const T & t, PRED pred)
1523 {
1524
1525 iptr iLPos, iUPos, iMPos;
1526
1527 iLPos = 0;
1528
1529 iUPos = a.get_upper_bound();
1530
1531 while(iLPos <= iUPos)
1532 {
1533
1534 iMPos = (iLPos + iUPos) / 2;
1535
1536 if (pred(a[iMPos], t))
1537 {
1538
1539 if (pred(t, a[iMPos]))
1540 {
1541
1542 return iMPos;
1543
1544 }
1545 else
1546 {
1547
1548 iLPos = iMPos + 1;
1549
1550 }
1551
1552 }
1553 else
1554 {
1555
1556 if (!pred(t, a[iMPos]))
1557 {
1558
1559 return iMPos;
1560
1561 }
1562 else
1563 {
1564
1565 iUPos = iMPos - 1;
1566
1567 }
1568
1569 }
1570
1571 }
1572
1573 return -1;
1574
1575 }
1576
1577
1578
1579 } // namespace array
1580
1581
1582} // namespace acme
1583
1584
1585
1586template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1587template < typename PRED >
1588void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::predicate_sort(PRED pred)
1589{
1590
1591 ::acme::array::predicate_sort(*this, pred);
1592
1593}
1594
1595
1596template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY,::enum_type t_etypeContainer >
1597template < typename T, typename PRED >
1598::collection::index base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::predicate_binary_search(const T & t, PRED pred) const
1599{
1600
1601 return ::acme::array::predicate_binary_search(*this, t, pred);
1602
1603}
1604
1605
1606template < prototype_container CONTAINER1, prototype_container CONTAINER2 >
1607CONTAINER1 operator + (const CONTAINER1 & container1, const CONTAINER2 & container2)
1608{
1609
1610 auto container = container1;
1611
1612 container.append(container2);
1613
1614 return ::transfer(container);
1615
1616}
1617
1618
1619
::collection::index erase_at(::collection::index nIndex, ::collection::count nCount=1)
Definition aaa__array_base_impl.h:62
Definition numeric_array.h:37
Definition numeric_info.h:672
include "aura/graphics/image/context.h"
Definition aaaa__defer.h:32