Embedded Template Library 1.0
Loading...
Searching...
No Matches
queue_lockable.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2019 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_QUEUE_LOCKABLE_INCLUDED
32#define ETL_QUEUE_LOCKABLE_INCLUDED
33
34#include "platform.h"
35#include "integral_limits.h"
36#include "memory.h"
37#include "memory_model.h"
38#include "parameter_type.h"
39#include "placement_new.h"
40#include "utility.h"
41
42#include <stddef.h>
43
44namespace etl
45{
46 //***************************************************************************
49 //***************************************************************************
50 class queue_lockable_exception : public exception
51 {
52 public:
53
54 queue_lockable_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
55 : exception(reason_, file_name_, line_number_)
56 {
57 }
58 };
59
60 //***************************************************************************
63 //***************************************************************************
64 class queue_lockable_empty : public queue_lockable_exception
65 {
66 public:
67
68 queue_lockable_empty(string_type file_name_, numeric_type line_number_)
69 : queue_lockable_exception(ETL_ERROR_TEXT("queue_lockable:empty", ETL_QUEUE_SPSC_LOCKABLE_FILE_ID"A"), file_name_, line_number_)
70 {
71 }
72 };
73
74 template <size_t VMemory_Model = etl::memory_model::MEMORY_MODEL_LARGE>
75 class queue_lockable_base
76 {
77 public:
78
81
82 //*************************************************************************
84 //*************************************************************************
86
87 //*************************************************************************
90 //*************************************************************************
92 {
93 return available_implementation();
94 }
95
96 //*************************************************************************
98 //*************************************************************************
100 {
101 this->lock();
102
103 size_type result = available_implementation();
104
105 this->unlock();
106
107 return result;
108 }
109
110 //*************************************************************************
113 //*************************************************************************
114 bool empty_unlocked() const
115 {
116 return empty_implementation();
117 }
118
119 //*************************************************************************
121 //*************************************************************************
122 bool empty() const
123 {
124 this->lock();
125
126 size_type result = empty_implementation();
127
128 this->unlock();
129
130 return result;
131 }
132
133 //*************************************************************************
136 //*************************************************************************
137 bool full_unlocked() const
138 {
139 return full_implementation();
140 }
141
142 //*************************************************************************
144 //*************************************************************************
145 bool full() const
146 {
147 this->lock();
148
149 size_type result = full_implementation();
150
151 this->unlock();
152
153 return result;
154 }
155
156 //*************************************************************************
159 //*************************************************************************
161 {
162 return size_implementation();
163 }
164
165 //*************************************************************************
167 //*************************************************************************
169 {
170 this->lock();
171
172 size_type result = size_implementation();
173
174 this->unlock();
175
176 return result;
177 }
178
179 //*************************************************************************
181 //*************************************************************************
183 {
184 return Max_Size;
185 }
186
187 //*************************************************************************
189 //*************************************************************************
191 {
192 return Max_Size;
193 }
194
195 protected:
196
198 : write_index(0)
199 , read_index(0)
200 , current_size(0)
201 , Max_Size(max_size_)
202 {
203 }
204
205 //*************************************************************************
207 //*************************************************************************
209 {
210 ++index;
211
212 if (index == maximum) ETL_UNLIKELY
213 {
214 index = 0;
215 }
216
217 return index;
218 }
219
220 //*************************************************************************
222 //*************************************************************************
223 virtual void lock() const = 0;
224 virtual void unlock() const = 0;
225
230
231 private:
232
233 //*************************************************************************
235 //*************************************************************************
236 size_type available_implementation() const
237 {
238 return Max_Size - current_size;
239 }
240
241 //*************************************************************************
243 //*************************************************************************
244 bool empty_implementation() const
245 {
246 return (current_size == 0);
247 }
248
249 //*************************************************************************
251 //*************************************************************************
252 bool full_implementation() const
253 {
254 return (current_size == Max_Size);
255 }
256
257 //*************************************************************************
259 //*************************************************************************
260 size_type size_implementation() const
261 {
262 return current_size;
263 }
264 };
265
266 //***************************************************************************
272 //***************************************************************************
273 template <typename T, const size_t VMemory_Model = etl::memory_model::MEMORY_MODEL_LARGE>
274 class iqueue_lockable : public etl::queue_lockable_base<VMemory_Model>
275 {
276 private:
277
278 typedef queue_lockable_base<VMemory_Model> base_t;
279
280 public:
281
282 typedef T value_type;
283 typedef T& reference;
284 typedef const T& const_reference;
285#if ETL_USING_CPP11
286 typedef T&& rvalue_reference;
287#endif
288 typedef typename base_t::size_type size_type;
289
290 //*************************************************************************
292 //*************************************************************************
294 {
295 return push_implementation(value);
296 }
297
298 //*************************************************************************
300 //*************************************************************************
302 {
303 this->lock();
304
305 bool result = push_implementation(value);
306
307 this->unlock();
308
309 return result;
310 }
311
312#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKABLE_FORCE_CPP03_IMPLEMENTATION)
313 //*************************************************************************
315 //*************************************************************************
316 bool push_unlocked(rvalue_reference value)
317 {
318 return push_implementation(value);
319 }
320
321 //*************************************************************************
323 //*************************************************************************
324 bool push(rvalue_reference value)
325 {
326 this->lock();
327
328 bool result = push_implementation(etl::move(value));
329
330 this->unlock();
331
332 return result;
333 }
334#endif
335
336#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKABLE_FORCE_CPP03_IMPLEMENTATION)
337 //*************************************************************************
339 //*************************************************************************
340 template <typename... Args>
341 bool emplace_unlocked(Args&&... args)
342 {
343 return emplace_implementation(etl::forward<Args>(args)...);
344 }
345
346 //*************************************************************************
348 //*************************************************************************
349 template <typename... Args>
350 bool emplace(Args&&... args)
351 {
352 this->lock();
353
354 bool result = emplace_implementation(etl::forward<Args>(args)...);
355
356 this->unlock();
357
358 return result;
359 }
360#else
361 //*************************************************************************
363 //*************************************************************************
364 template <typename T1>
365 bool emplace_unlocked(const T1& value1)
366 {
367 return emplace_implementation(value1);
368 }
369
370 //*************************************************************************
372 //*************************************************************************
373 template <typename T1, typename T2>
374 bool emplace_unlocked(const T1& value1, const T2& value2)
375 {
376 return emplace_implementation(value1, value2);
377 }
378
379 //*************************************************************************
381 //*************************************************************************
382 template <typename T1, typename T2, typename T3>
383 bool emplace_unlocked(const T1& value1, const T2& value2, const T3& value3)
384 {
385 return emplace_implementation(value1, value2, value3);
386 }
387
388 //*************************************************************************
390 //*************************************************************************
391 template <typename T1, typename T2, typename T3, typename T4>
392 bool emplace_unlocked(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
393 {
394 return emplace_implementation(value1, value2, value3, value4);
395 }
396
397 //*************************************************************************
399 //*************************************************************************
400 bool emplace()
401 {
402 this->lock();
403
404 bool result = emplace_implementation();
405
406 this->unlock();
407
408 return result;
409 }
410
411 //*************************************************************************
413 //*************************************************************************
414 template <typename T1>
415 bool emplace(const T1& value1)
416 {
417 this->lock();
418
419 bool result = emplace_implementation(value1);
420
421 this->unlock();
422
423 return result;
424 }
425
426 //*************************************************************************
428 //*************************************************************************
429 template <typename T1, typename T2>
430 bool emplace(const T1& value1, const T2& value2)
431 {
432 this->lock();
433
434 bool result = emplace_implementation(value1, value2);
435
436 this->unlock();
437
438 return result;
439 }
440
441 //*************************************************************************
443 //*************************************************************************
444 template <typename T1, typename T2, typename T3>
445 bool emplace(const T1& value1, const T2& value2, const T3& value3)
446 {
447 this->lock();
448
449 bool result = emplace_implementation(value1, value2, value3);
450
451 this->unlock();
452
453 return result;
454 }
455
456 //*************************************************************************
458 //*************************************************************************
459 template <typename T1, typename T2, typename T3, typename T4>
460 bool emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
461 {
462 this->lock();
463
464 bool result = emplace_implementation(value1, value2, value3, value4);
465
466 this->unlock();
467
468 return result;
469 }
470#endif
471
472 //*************************************************************************
474 //*************************************************************************
476 {
477 return pop_implementation();
478 }
479
480 //*************************************************************************
482 //*************************************************************************
483 bool pop()
484 {
485 this->lock();
486
487 bool result = pop_implementation();
488
489 this->unlock();
490
491 return result;
492 }
493
494 //*************************************************************************
496 //*************************************************************************
498 {
499 return pop_implementation(value);
500 }
501
502 //*************************************************************************
504 //*************************************************************************
505 bool pop(reference value)
506 {
507 this->lock();
508
509 bool result = pop_implementation(value);
510
511 this->unlock();
512
513 return result;
514 }
515
516 //*************************************************************************
520 //*************************************************************************
522 {
523 ETL_ASSERT_CHECK_EXTRA(!this->empty_unlocked(), ETL_ERROR(queue_lockable_empty));
524 return front_implementation();
525 }
526
527 //*************************************************************************
531 //*************************************************************************
533 {
534 ETL_ASSERT_CHECK_EXTRA(!this->empty_unlocked(), ETL_ERROR(queue_lockable_empty));
535 return front_implementation();
536 }
537
538 //*************************************************************************
542 //*************************************************************************
544 {
545#if ETL_CHECKING_EXTRA
546 this->lock();
547 if (!this->empty_unlocked())
548 {
549 reference inner_result = front_implementation();
550 this->unlock();
551 return inner_result;
552 }
553 else
554 {
555 this->unlock();
556 ETL_ASSERT_FAIL(ETL_ERROR(queue_lockable_empty));
557 // fall through to return something to satisfy the compiler, even
558 // though this should never be reached due to undefined behaviour.
559 }
560#endif
561 this->lock();
562 reference result = front_implementation();
563 this->unlock();
564 return result;
565 }
566
567 //*************************************************************************
571 //*************************************************************************
573 {
574#if ETL_CHECKING_EXTRA
575 this->lock();
576 if (!this->empty_unlocked())
577 {
578 const_reference inner_result = front_implementation();
579 this->unlock();
580 return inner_result;
581 }
582 else
583 {
584 this->unlock();
585 ETL_ASSERT_FAIL(ETL_ERROR(queue_lockable_empty));
586 // fall through to return something to satisfy the compiler, even
587 // though this should never be reached due to undefined behaviour.
588 }
589#endif
590 this->lock();
591 const_reference result = front_implementation();
592 this->unlock();
593 return result;
594 }
595
596 //*************************************************************************
598 //*************************************************************************
600 {
601 while (pop_implementation())
602 {
603 // Do nothing.
604 }
605 }
606
607 //*************************************************************************
609 //*************************************************************************
610 void clear()
611 {
612 this->lock();
613
614 if ETL_IF_CONSTEXPR (etl::is_trivially_destructible<T>::value)
615 {
616 this->write_index = 0;
617 this->read_index = 0;
618 this->current_size = 0;
619 }
620 else
621 {
622 while (pop_implementation())
623 {
624 // Do nothing.
625 }
626 }
627
628 this->unlock();
629 }
630
631 protected:
632
633 //*************************************************************************
635 //*************************************************************************
636 iqueue_lockable(T* p_buffer_, size_type max_size_)
637 : base_t(max_size_)
638 , p_buffer(p_buffer_)
639 {
640 }
641
642 private:
643
644 //*************************************************************************
646 //*************************************************************************
647 bool push_implementation(const_reference value)
648 {
649 if (this->current_size != this->Max_Size)
650 {
651 ::new (&p_buffer[this->write_index]) T(value);
652
653 this->write_index = this->get_next_index(this->write_index, this->Max_Size);
654
655 ++this->current_size;
656
657 return true;
658 }
659
660 // Queue is full.
661 return false;
662 }
663
664#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKABLE_FORCE_CPP03_IMPLEMENTATION)
665 //*************************************************************************
667 //*************************************************************************
668 bool push_implementation(rvalue_reference value)
669 {
670 if (this->current_size != this->Max_Size)
671 {
672 ::new (&p_buffer[this->write_index]) T(etl::move(value));
673
674 this->write_index = this->get_next_index(this->write_index, this->Max_Size);
675
676 ++this->current_size;
677
678 return true;
679 }
680
681 // Queue is full.
682 return false;
683 }
684#endif
685
686#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKABLE_FORCE_CPP03_IMPLEMENTATION)
687 //*************************************************************************
689 //*************************************************************************
690 template <typename... Args>
691 bool emplace_implementation(Args&&... args)
692 {
693 if (this->current_size != this->Max_Size)
694 {
695 ::new (&p_buffer[this->write_index]) T(etl::forward<Args>(args)...);
696
697 this->write_index = this->get_next_index(this->write_index, this->Max_Size);
698
699 ++this->current_size;
700
701 return true;
702 }
703
704 // Queue is full.
705 return false;
706 }
707#else
708 //*************************************************************************
710 //*************************************************************************
711 template <typename T1>
712 bool emplace_implementation(const T1& value1)
713 {
714 if (this->current_size != this->Max_Size)
715 {
716 ::new (&p_buffer[this->write_index]) T(value1);
717
718 this->write_index = this->get_next_index(this->write_index, this->Max_Size);
719
720 ++this->current_size;
721
722 return true;
723 }
724
725 // Queue is full.
726 return false;
727 }
728
729 //*************************************************************************
731 //*************************************************************************
732 template <typename T1, typename T2>
733 bool emplace_implementation(const T1& value1, const T2& value2)
734 {
735 if (this->current_size != this->Max_Size)
736 {
737 ::new (&p_buffer[this->write_index]) T(value1, value2);
738
739 this->write_index = this->get_next_index(this->write_index, this->Max_Size);
740
741 ++this->current_size;
742
743 return true;
744 }
745
746 // Queue is full.
747 return false;
748 }
749
750 //*************************************************************************
752 //*************************************************************************
753 template <typename T1, typename T2, typename T3>
754 bool emplace_implementation(const T1& value1, const T2& value2, const T3& value3)
755 {
756 if (this->current_size != this->Max_Size)
757 {
758 ::new (&p_buffer[this->write_index]) T(value1, value2, value3);
759
760 this->write_index = this->get_next_index(this->write_index, this->Max_Size);
761
762 ++this->current_size;
763
764 return true;
765 }
766
767 // Queue is full.
768 return false;
769 }
770
771 //*************************************************************************
773 //*************************************************************************
774 template <typename T1, typename T2, typename T3, typename T4>
775 bool emplace_implementation(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
776 {
777 if (this->current_size != this->Max_Size)
778 {
779 ::new (&p_buffer[this->write_index]) T(value1, value2, value3, value4);
780
781 this->write_index = this->get_next_index(this->write_index, this->Max_Size);
782
783 ++this->current_size;
784
785 return true;
786 }
787
788 // Queue is full.
789 return false;
790 }
791#endif
792
793 //*************************************************************************
795 //*************************************************************************
796 bool pop_implementation()
797 {
798 if (this->current_size == 0)
799 {
800 // Queue is empty
801 return false;
802 }
803
804 p_buffer[this->read_index].~T();
805
806 this->read_index = this->get_next_index(this->read_index, this->Max_Size);
807
808 --this->current_size;
809
810 return true;
811 }
812
813 //*************************************************************************
815 //*************************************************************************
816 bool pop_implementation(reference value)
817 {
818 if (this->current_size == 0)
819 {
820 // Queue is empty
821 return false;
822 }
823
824#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKABLE_FORCE_CPP03_IMPLEMENTATION)
825 value = etl::move(p_buffer[this->read_index]);
826#else
827 value = p_buffer[this->read_index];
828#endif
829
830 p_buffer[this->read_index].~T();
831
832 this->read_index = this->get_next_index(this->read_index, this->Max_Size);
833
834 --this->current_size;
835
836 return true;
837 }
838
839 //*************************************************************************
841 //*************************************************************************
842 reference front_implementation()
843 {
844 return p_buffer[this->read_index];
845 }
846
847 //*************************************************************************
849 //*************************************************************************
850 const_reference front_implementation() const
851 {
852 return p_buffer[this->read_index];
853 }
854
855 // Disable copy construction and assignment.
856 iqueue_lockable(const iqueue_lockable&) ETL_DELETE;
857 iqueue_lockable& operator=(const iqueue_lockable&) ETL_DELETE;
858
859#if ETL_USING_CPP11
861 iqueue_lockable& operator=(iqueue_lockable&&) = delete;
862#endif
863
864 T* p_buffer;
865 };
866
867 //***************************************************************************
874 //***************************************************************************
875 template <typename T, size_t VSize, size_t VMemory_Model = etl::memory_model::MEMORY_MODEL_LARGE>
876 class queue_lockable : public etl::iqueue_lockable<T, VMemory_Model>
877 {
878 private:
879
881
882 public:
883
884 typedef typename base_t::size_type size_type;
885
886 ETL_STATIC_ASSERT((VSize <= etl::integral_limits<size_type>::max), "Size too large for memory model");
887
888 static ETL_CONSTANT size_type Max_Size = size_type(VSize);
889 static ETL_CONSTANT size_type Memory_Model = size_type(VMemory_Model);
890
891 //*************************************************************************
893 //*************************************************************************
894
896 : base_t(reinterpret_cast<T*>(buffer.raw), Max_Size)
897 {
898 }
899
900 //*************************************************************************
902 //*************************************************************************
904 {
905 while (this->pop_unlocked())
906 {
907 // Do nothing.
908 }
909 }
910
911 private:
912
913 queue_lockable(const queue_lockable&) ETL_DELETE;
914 queue_lockable& operator=(const queue_lockable&) ETL_DELETE;
915
916#if ETL_USING_CPP11
917 queue_lockable(queue_lockable&&) = delete;
918 queue_lockable& operator=(queue_lockable&&) = delete;
919#endif
920
923 };
924
925 template <typename T, size_t VSize, size_t VMemory_Model>
927
928 template <typename T, size_t VSize, size_t VMemory_Model>
929 ETL_CONSTANT typename queue_lockable<T, VSize, VMemory_Model>::size_type queue_lockable<T, VSize, VMemory_Model>::Memory_Model;
930} // namespace etl
931
932#endif
This is the base for all queues that contain a particular type.
Definition queue_lockable.h:275
bool pop(reference value)
Pop a value from the queue.
Definition queue_lockable.h:505
reference front_unlocked()
Definition queue_lockable.h:521
bool pop_unlocked(reference value)
Pop a value from the queue without locking.
Definition queue_lockable.h:497
bool pop()
Pop a value from the queue and discard.
Definition queue_lockable.h:483
reference front()
Definition queue_lockable.h:543
bool emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Constructs a value in the queue 'in place'.
Definition queue_lockable.h:460
bool emplace(const T1 &value1)
Constructs a value in the queue 'in place'.
Definition queue_lockable.h:415
void clear()
Clear the queue.
Definition queue_lockable.h:610
bool emplace_unlocked(const T1 &value1, const T2 &value2, const T3 &value3)
Constructs a value in the queue 'in place'.
Definition queue_lockable.h:383
const_reference front_unlocked() const
Definition queue_lockable.h:532
bool emplace_unlocked(const T1 &value1)
Constructs a value in the queue 'in place'.
Definition queue_lockable.h:365
bool push_unlocked(const_reference value)
Push a value to the queue without locking.
Definition queue_lockable.h:293
bool pop_unlocked()
Pop a value from the queue without locking, and discard.
Definition queue_lockable.h:475
bool emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Constructs a value in the queue 'in place'.
Definition queue_lockable.h:445
bool emplace_unlocked(const T1 &value1, const T2 &value2)
Constructs a value in the queue 'in place'.
Definition queue_lockable.h:374
iqueue_lockable(T *p_buffer_, size_type max_size_)
The constructor that is called from derived classes.
Definition queue_lockable.h:636
bool emplace(const T1 &value1, const T2 &value2)
Constructs a value in the queue 'in place'.
Definition queue_lockable.h:430
base_t::size_type size_type
The type used for determining the size of the queue.
Definition queue_lockable.h:288
const_reference front() const
Definition queue_lockable.h:572
bool emplace()
Constructs a value in the queue 'in place'.
Definition queue_lockable.h:400
const T & const_reference
A const reference to the type used in the queue.
Definition queue_lockable.h:284
T value_type
The type stored in the queue.
Definition queue_lockable.h:282
bool emplace_unlocked(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Constructs a value in the queue 'in place'.
Definition queue_lockable.h:392
bool push(const_reference value)
Push a value to the queue.
Definition queue_lockable.h:301
void clear_unlocked()
Clear the queue, unlocked.
Definition queue_lockable.h:599
T & reference
A reference to the type used in the queue.
Definition queue_lockable.h:283
Definition queue_lockable.h:76
size_type size_unlocked() const
Definition queue_lockable.h:160
size_type capacity() const
How many items can the queue hold.
Definition queue_lockable.h:182
size_type max_size() const
How many items can the queue hold.
Definition queue_lockable.h:190
bool empty() const
Is the queue empty?
Definition queue_lockable.h:122
bool empty_unlocked() const
Definition queue_lockable.h:114
const size_type Max_Size
Definition queue_lockable.h:229
size_type read_index
Where to get the oldest data.
Definition queue_lockable.h:227
size_type current_size
The current size of the queue.
Definition queue_lockable.h:228
size_type available_unlocked() const
Definition queue_lockable.h:91
etl::size_type_lookup< VMemory_Model >::type size_type
The type used for determining the size of queue.
Definition queue_lockable.h:80
size_type write_index
Where to input new data.
Definition queue_lockable.h:226
static size_type get_next_index(size_type index, size_type maximum)
Calculate the next index.
Definition queue_lockable.h:208
size_type size() const
How many items in the queue?
Definition queue_lockable.h:168
virtual void lock() const =0
The pure virtual lock and unlock functions.
bool full_unlocked() const
Definition queue_lockable.h:137
size_type available() const
How much free space available in the queue.
Definition queue_lockable.h:99
bool full() const
Is the queue full?
Definition queue_lockable.h:145
virtual ~queue_lockable_base()
Destructor.
Definition queue_lockable.h:85
Definition queue_lockable.h:877
~queue_lockable()
Destructor.
Definition queue_lockable.h:903
queue_lockable()
Default constructor.
Definition queue_lockable.h:895
Definition memory.h:3153
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
Definition integral_limits.h:517
Definition queue_lockable.h:65
Definition absolute.h:40
Definition memory_model.h:50