acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
_impl.h
1//
2// Created by camilo on 23/12/2022 16:26 <3ThomasBorregaardSorensen!!
3//
4#pragma once
5
6
7#include "_impl_generic_map.h"
8#include "_impl_numeric_array.h"
9#include "_impl_payload.h"
10
11
12template<typename ITERATOR_TYPE>
13inline auto & range < ITERATOR_TYPE >::first() { return ::get(this->begin()); }
14template<typename ITERATOR_TYPE>
15inline auto & range < ITERATOR_TYPE >::first() const { return (CONST_ITEM &) ::get(this->begin()); }
16
17
18template<typename ITERATOR_TYPE>
19inline const ::block block_range < ITERATOR_TYPE >::block() const
20{
21
22 return {(const void *) (ITERATOR_TYPE) this->data(), this->size_in_bytes()};
23
24}
25
26
27template<typename ITERATOR_TYPE>
28inline ::block block_range < ITERATOR_TYPE >::block()
29{
30
31 return {(const void *) (ITERATOR_TYPE) this->data(), this->size_in_bytes()};
32
33}
34
35#include "acme/handler/dispatch_array.h"
36
37
38// inline sequence_continuation particle::user_send(const ::procedure & procedure)
39// {
40// return { this, e_dispatch_user_send, procedure };
41// }
42inline dispatch_arrayø particle::user_sendø()
43{
44 return { this, e_dispatch_user_send };
45}
46// inline sequence_continuation particle::user_sync()
47// {
48// return { this, e_dispatch_user_send, (::subparticle*) this };
49// }
50
51
52
53
54// inline sequence_continuation particle::user_post(const ::procedure & procedure)
55// {
56// return { this, e_dispatch_user_post, procedure };
57// }
58inline dispatch_arrayø particle::user_postø()
59{
60 return { this, e_dispatch_user_post };
61}
62// inline sequence_continuation particle::user_async()
63// {
64// return { this, e_dispatch_user_post, (::subparticle*) this };
65// }
66
67
68// inline sequence_continuation particle::main_send(const ::procedure & procedure)
69// {
70// return { this, e_dispatch_main_send, procedure };
71// }
72inline dispatch_arrayø particle::main_sendø()
73{
74 return { this, e_dispatch_main_send };
75}
76// inline sequence_continuation particle::main_sync()
77// {
78// return { this, e_dispatch_main_send, this };
79// }
80
81
82// inline sequence_continuation particle::main_post(const ::procedure & procedure)
83// {
84// return { this, e_dispatch_main_post, procedure };
85// }
86inline dispatch_arrayø particle::main_postø()
87{
88 return { this, e_dispatch_main_post };
89}
90// inline sequence_continuation particle::main_async()
91// {
92// return { this, e_dispatch_main_post, this };
93// }
94
95
96// inline sequence_continuation particle::send(const ::procedure & procedure)
97// {
98// return { this, e_dispatch_send, procedure };
99// }
100inline dispatch_arrayø particle::sendø()
101{
102 return { this, e_dispatch_send };
103}
104
105
106// inline sequence_continuation particle::sync(const class ::time & timeTimeout)
107// {
108//
109// ::procedure procedure;
110//
111// procedure.m_p = this;
112//
113// if (!timeTimeout.is_null())
114// {
115//
116// procedure.m_timeTimeout = timeTimeout;
117//
118// }
119//
120// return { this, e_dispatch_send, procedure };
121//
122// }
123//
124//
125// inline sequence_continuation particle::post(const ::procedure & procedure)
126// {
127// return { this, e_dispatch_post, procedure };
128// }
129inline dispatch_arrayø particle::postø()
130{
131 return { this, e_dispatch_post };
132}
133// inline sequence_continuation particle::async()
134// {
135//
136// return { this, e_dispatch_post, this };
137// }
138
139#include "acme/exception/cancel.h"
140
141
142
143
144 template < typename CONTEXT_TYPE >
145 void procedure_array_with_context<CONTEXT_TYPE>::run()
146 {
147
148 try
149 {
150
151 for (auto & procedure : *this)
152 {
153
154 procedure();
155
156 }
157
158 }
159 catch (const ::cancel_exception<CONTEXT_TYPE> & cancelexception)
160 {
161
162 informationf("procedure_array : cancel_exception(%s) : %s", cancelexception.m_strContext.c_str(), cancelexception.m_strMessage.c_str());
163
164 }
165
166
167 }
168
169
170
171
172
173template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
174::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::_allocate(::collection::count nNewSize, bool bShrink, bool bRaw, bool bFollowingIsArray, const TYPE * ptype)
175{
176
177 //if (this->m_erange & e_range_array_allocate)
178 //{
179
180 // if (nNewSize > this->m_countAllocation)
181 // {
182
183 // throw ::exception(error_wrong_state);
184
185 // }
186
187 // if (nNewSize > this->m_countAllocation + this->m_countAllocationOffset)
188 // {
189
190 // auto countOffset = this->m_countAllocationOffset;
191
192 // for (auto p = this->m_begin; p < this->m_end; p++)
193 // {
194
195 // p[countOffset] = *p;
196
197 // }
198
199 // this->m_begin += countOffset;
200
201 // this->m_end += countOffset;
202
203 // this->m_countAllocationOffset = 0;
204
205 // }
206
207 // if (ptype)
208 // {
209
210 // auto nOldSize = this->size();
211
212 // TYPED::destruct_count(this->m_begin + nOldSize, nNewSize - nOldSize);
213
214 // TYPED::copy_construct_count(this->m_begin + nOldSize, nNewSize - nOldSize, *ptype);
215
216 // }
217
218 // this->m_end = this->m_begin + nNewSize;
219
220 // if (this->m_end == this->m_begin)
221 // {
222
223 // if (this->m_countAllocationOffset != 0)
224 // {
225
226 // this->m_begin += this->m_countAllocationOffset;
227
228 // this->m_end = this->m_begin;
229
230 // }
231
232 // }
233
234 // return nNewSize;
235
236 //}
237
238 ASSERT(nNewSize >= 0);
239
240 if(nNewSize < 0)
241 {
242
243 throw_exception(error_bad_argument);
244
245 }
246
247 ::collection::count countOld = get_count();
248
249 if(nNewSize == countOld)
250 {
251
252 return countOld;
253
254 }
255
256 if(nNewSize == 0)
257 {
258
259 if(this->m_begin != nullptr)
260 {
261
262 TYPED::destruct_count(this->m_begin, this->size());
263
264 if(bShrink)
265 {
266
267 //if(!(this->m_erange & e_range_array_allocate))
268 {
269
270 MEMORY::free(this->m_begin + this->m_countAllocationOffset);
271 m_countAllocation = 0;
272 this->m_begin = nullptr;
273
274
275 }
276 //else
277 //{
278 //
279 // TYPED::construct_count(this->m_begin, this->size());
280 // this->m_end = this->m_begin;
281
282 //}
283
284 this->m_countAllocationOffset = 0;
285
286
287 }
288 else
289 {
290
291 if (this->m_erange & e_range_array_clear_on_allocate)
292 {
293
294 memset((void *) this->m_begin, 0, maximum(0, countOld) * sizeof(TYPE));
295
296 }
297
298 }
299
300 }
301
302 this->m_end = this->m_begin;
303
304 }
305 else if(this->m_begin == nullptr)
306 {
307
308 if(nNewSize > UPTR_MAXIMUM / sizeof(TYPE))
309 {
310
311 throw_exception(error_no_memory);
312
313 }
314
315 auto nAllocSize = maximum(nNewSize, m_countAddUp);
316
317#if MEMDLEAK || defined(__MCRTDBG)
318
319 if(::get_task() != nullptr)
320 {
321
322#if defined(__MCRTDBG)
323
324 if(::get_task()->m_strFile.has_character())
325 {
326
327 this->m_begin = MEMORY::allocate(nAllocSize, ::get_task()->m_strFile, ::get_task()->m_iLine);
328
329 }
330 else
331 {
332
333 this->m_begin = MEMORY::allocate(nAllocSize, __FILE__, __LINE__);
334
335 }
336
337#else
338
339 if (::get_task_object_debug().has_character())
340 {
341
342 this->m_begin = MEMORY::allocate(nAllocSize, "thread://" + ::get_task_object_name() + ", " + ::get_task_object_debug() + ", " + string(__FILE__), __LINE__);
343
344 }
345 else
346 {
347
348 this->m_begin = MEMORY::allocate(nAllocSize, "thread://" + ::get_task_object_name() + ", " + string(__FILE__), __LINE__);
349
350 }
351
352#endif
353
354 }
355 else
356 {
357
358 this->m_begin = MEMORY::allocate(nAllocSize, __FILE__, __LINE__);
359
360 }
361
362#else
363
364 this->m_begin = MEMORY::allocate(nAllocSize, &nAllocSize);
365
366#endif
367
368 if (this->m_erange & e_range_array_clear_on_allocate)
369 {
370
371 memset((void *) this->m_begin, 0, nAllocSize * sizeof(TYPE));
372
373 }
374
375 if(!bRaw)
376 {
377
378 if (::is_null(ptype))
379 {
380
381 TYPED::construct_count(this->m_begin, nNewSize);
382
383 }
384 else
385 {
386
387 TYPED::copy_construct_count(this->m_begin, nNewSize, *ptype);
388
389 }
390
391 }
392
393 this->m_end = this->m_begin + nNewSize;
394
395 m_countAllocation = nAllocSize;
396
397 }
398 else if(nNewSize <= m_countAllocation)
399 {
400
401 defer_erase_allocation_offset();
402
403 if (!bRaw)
404 {
405
406 if (nNewSize > countOld)
407 {
408
409 if (::is_null(ptype))
410 {
411
412 TYPED::construct_count(this->m_begin + countOld, nNewSize - countOld);
413
414 }
415 else
416 {
417
418 TYPED::copy_construct_count(this->m_begin + countOld, nNewSize - countOld, *ptype);
419
420 }
421
422 }
423 else if (countOld > nNewSize)
424 {
425
426 TYPED::destruct_count(this->m_begin + nNewSize, countOld - nNewSize);
427
428 if (this->m_erange & e_range_array_clear_on_allocate)
429 {
430
431 memset((void *) (this->m_begin + nNewSize), 0, (countOld - nNewSize) * sizeof(TYPE));
432
433 }
434 else
435 {
436
437 TYPED::construct_count(this->m_begin + nNewSize, countOld - nNewSize);
438
439 }
440
441 }
442
443 }
444
445 this->m_end = this->m_begin + nNewSize;
446
447 }
448 else
449 {
450
451 auto countAddUp = m_countAddUp;
452
453 if(countAddUp <= 0)
454 {
455
456 countAddUp = this->size();
457
458 constrain(countAddUp, 4, 1024);
459
460 }
461
462 ::collection::count countNewAllocation;
463
464 if(nNewSize < m_countAllocation + countAddUp)
465 {
466
467 countNewAllocation = m_countAllocation + countAddUp;
468
469 }
470 else
471 {
472
473 countNewAllocation = nNewSize;
474
475 }
476
477 if(countNewAllocation > UPTR_MAXIMUM / sizeof(TYPE))
478 {
479
480 throw_exception(error_no_memory);
481
482 }
483
484#if MEMDLEAK || defined(__MCRTDBG)
485
486 TYPE* pNewData = nullptr;
487
488 if(::get_task() != nullptr)
489 {
490
491#if defined(__MCRTDBG)
492
493 if(::get_task()->m_strFile.has_character())
494 {
495
496 pNewData = MEMORY::allocate(countNewAllocation, ::get_task()->m_strFile,::get_task()->m_iLine);
497
498 }
499 else
500 {
501
502 pNewData = MEMORY::allocate(countNewAllocation, __FILE__, __LINE__);
503
504 }
505
506#else
507
508 if (::get_task_object_debug().has_character())
509 {
510
511 pNewData = MEMORY::allocate(countNewAllocation, "thread://" + ::get_task_object_name() + ", " + ::get_task_object_debug() + ", " + string(__FILE__), __LINE__);
512
513 }
514 else
515 {
516
517 pNewData = MEMORY::allocate(countNewAllocation, "thread://" + ::get_task_object_name() + ", " + string(__FILE__), __LINE__);
518
519 }
520
521#endif
522
523 }
524 else
525 {
526
527 pNewData = MEMORY::allocate(countNewAllocation, __FILE__, __LINE__);
528
529 }
530
531
532#else
533
534 TYPE * pNewData = MEMORY::allocate(countNewAllocation, &countNewAllocation);
535
536#endif
537
538 // copy ___new data from old
539 ::safe_memory_copy2(pNewData, (size_t)countNewAllocation, this->m_begin, (size_t) countOld);
540
541 if (this->m_erange & e_range_array_clear_on_allocate)
542 {
543
544 memset((void *) (this->m_begin + countOld), 0, (countNewAllocation - countOld) * sizeof(TYPE));
545
546 }
547
548 if(!bRaw)
549 {
550
551 // construct remaining elements
552 ASSERT(nNewSize > countOld);
553
554 if (nNewSize > countOld)
555 {
556
557 if (::is_null(ptype))
558 {
559
560 TYPED::construct_count(pNewData + countOld, nNewSize - countOld);
561
562 }
563 else
564 {
565
566 TYPED::copy_construct_count(pNewData + countOld, nNewSize - countOld, *ptype);
567
568 }
569
570 }
571
572 }
573
574 //if(!(this->m_erange & e_range_array_allocate))
575 {
576
577 // get rid of old stuff (note: no destructors called)
578 MEMORY::free(this->m_begin + this->m_countAllocationOffset);
579
580 }
581 //else
582 //{
583 //
584 // this->m_erange = (::enum_range) (this->m_erange & ~e_range_array_allocate);
585 //
586 //}
587
588 this->m_begin = pNewData;
589
590 this->m_end = this->m_begin + nNewSize;
591
592 this->m_countAllocationOffset = 0;
593
594 m_countAllocation = countNewAllocation;
595
596 }
597
598 return countOld;
599
600}
601
602
603template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
604void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::array_base_ok() const
605{
606
607 if (this->m_begin)
608 {
609
610 ASSERT(this->m_end);
611
612 ASSERT(this->m_countAllocation > 0);
613
614 }
615 else
616 {
617
618 ASSERT(!this->m_end);
619
620 ASSERT(this->m_countAllocation == 0);
621
622 }
623
624}
625
626
627
628template < class TYPE, class ARG_TYPE >
629void list_base < TYPE, ARG_TYPE >::list_base_ok() const
630{
631
632 if (this->m_begin)
633 {
634
635 ASSERT(this->m_end);
636
637 ASSERT(this->m_count > 0);
638
639 }
640 else
641 {
642
643 ASSERT(!this->m_end);
644
645 ASSERT(this->m_count == 0);
646
647 }
648
649}
650
651
652template < typename ITEM, enum_allocate t_eallocate >
653void node_set_base < ITEM, t_eallocate >::container_ok() const
654{
655
656 if (this->m_begin)
657 {
658
659 ASSERT(this->m_end);
660
661 ASSERT(this->m_count > 0);
662
663 }
664 else
665 {
666
667 ASSERT(!this->m_end);
668
669 ASSERT(this->m_count == 0);
670
671 }
672
673}
674
675
676template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
677base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(const base_array< TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > & array)
678{
679
680 this->m_begin = nullptr;
681 this->m_end = nullptr;
682 this->m_erange = e_range_none;
683 //this->m_erange = e_array_none;
684 m_countAddUp = 0;
685 m_countAllocation = 0;
686 m_countAllocationOffset = 0;
687 set_size(array.get_size());
688
689
690 TYPED::copy_count(this->m_begin, array.m_begin, this->size());
691 // for (::collection::index i = 0; i < array.get_size(); i++)
692 // {
693 //
694 // this->element_at(i) = array[i];
695 //
696 // }
697
698}
699
700
701template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
702base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(base_array< TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > && array) noexcept :
703 ARRAY_RANGE(no_initialize_t{})
704{
705
706 this->m_begin = array.m_begin;
707 this->m_end = array.m_end;
708 this->m_erange = array.m_erange;
709 this->m_countAddUp = array.m_countAddUp;
710 this->m_countAllocation = array.m_countAllocation;
711 this->m_countAllocationOffset = array.m_countAllocationOffset;
712
713 array.m_begin = nullptr;
714 array.m_end = nullptr;
715 array.m_erange = e_range_none;
716 array.m_countAllocation = 0;
717 array.m_countAllocation = 0;
718 array.m_countAllocationOffset = 0;
719
720}
721
722
723template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
724template < typename OTHER_RANGE >
725base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::
726base_array(const OTHER_RANGE & range) requires
727(container_range < OTHER_RANGE >
728 && !::std::is_base_of_v < base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >, ::std::remove_cvref_t < OTHER_RANGE > >) :
729 base_array()
730{
731
732 for (auto p = range.begin(); range.is_iterator_ok(p); p++)
733 {
734
735 this->add((ARG_TYPE) *p);
736
737 }
738
739}
740
741
742
743
744
Definition base_array.h:112
Definition dispatch_array.h:180
Definition range.h:223
Definition _structures.h:51