COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
Tuple.h
Go to the documentation of this file.
1//
2// Copyright 2013 - 2024 (C). Alex Robenko. All rights reserved.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
10
11#pragma once
12
13#include <tuple>
14#include <utility>
15#include <type_traits>
16
20#include "comms/Assert.h"
21
22COMMS_GNU_WARNING_PUSH
23COMMS_GNU_WARNING_DISABLE("-Wtype-limits")
24
25namespace comms
26{
27
28namespace util
29{
30
34template <typename TType>
35struct IsTuple
36{
39 static constexpr bool Value = false;
40};
41
43template <typename... TArgs>
44struct IsTuple<std::tuple<TArgs...> >
45{
46 static constexpr bool Value = true;
47};
49
53template <typename TType>
54constexpr bool isTuple()
55{
57}
58
59//----------------------------------------
60
61namespace details
62{
63
64template <bool THasElems, typename...>
65struct IsInTupleHelper // <true>
66{
67 template <typename TType, typename TFirst, typename... TRest>
68 using Type =
70 std::is_same<TType, TFirst>::value
71 >::template Type<
72 std::true_type,
73 typename IsInTupleHelper<(sizeof...(TRest) != 0U)>::template Type<TType, TRest...>
74 >;
75};
76
77template <typename... TParams>
78struct IsInTupleHelper<false, TParams...>
79{
80 template <typename TType, typename...>
81 using Type = std::false_type;
82};
83
84} // namespace details
85
94template <typename TTuple>
95struct IsInTuple;
96
98
99template <typename... TTypes>
100struct IsInTuple<std::tuple<TTypes...> >
101{
102 template <typename TType>
103 using Type =
104 typename details::IsInTupleHelper<(sizeof...(TTypes) != 0U)>::template Type<TType, TTypes...>;
105};
106
108
109//----------------------------------------
110
111namespace details
112{
113
114template <bool THasElems, typename...>
115class TupleAsAlignedUnionHelper // <true>
116{
117 template <typename TElem>
118 using ElemAlignmentType = std::integral_constant<std::size_t, alignof(TElem)>;
119
120 template <typename TElem>
121 using ElemSizeType = std::integral_constant<std::size_t, sizeof(TElem)>;
122
123public:
124 template <typename TElem, typename... TRest>
125 using AlignmentType =
126 comms::util::IntMaxBinaryOp<>::template Type<
127 ElemAlignmentType<TElem>,
128 typename TupleAsAlignedUnionHelper<(0U < sizeof...(TRest))>::template AlignmentType<TRest...>
129 >;
130
131 template <typename TElem, typename... TRest>
132 using SizeType =
133 comms::util::IntMaxBinaryOp<>::template Type<
134 ElemSizeType<TElem>,
135 typename TupleAsAlignedUnionHelper<(0U < sizeof...(TRest))>::template SizeType<TRest...>
136 >;
137};
138
139template <typename... TParams>
140class TupleAsAlignedUnionHelper<false, TParams...>
141{
142public:
143 template <typename...>
144 using AlignmentType = std::integral_constant<std::size_t, 0U>;
145
146 template <typename...>
147 using SizeType = std::integral_constant<std::size_t, 0U>;
148};
149
150} // namespace details
151
156template <typename TTuple>
158{
160 static_assert(IsTuple<TTuple>::Value, "TTuple must be std::tuple");
162
166 using Type = void;
167};
168
170template <typename... TTypes>
171class TupleAsAlignedUnion<std::tuple<TTypes...> >
172{
173 using AlignmentType =
174 typename details::TupleAsAlignedUnionHelper<(0U < sizeof...(TTypes))>::template AlignmentType<TTypes...>;
175
176 using SizeType =
177 typename details::TupleAsAlignedUnionHelper<(0U < sizeof...(TTypes))>::template SizeType<TTypes...>;
178public:
179 using Type = comms::util::AlignedStorage<SizeType::value, AlignmentType::value>;
180};
182
184template <typename TTuple>
186
187//----------------------------------------
188
189namespace details
190{
191
192template <bool THasElems>
193struct TupleForEachHelper
194{
195 template <std::size_t TOff, std::size_t TRem, typename TTuple, typename TFunc>
196 static void exec(TTuple&& tuple, TFunc&& func)
197 {
198 using Tuple = typename std::decay<TTuple>::type;
199 static_assert(IsTuple<Tuple>::Value, "TTuple must be std::tuple");
200 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
201 static constexpr std::size_t OffsetedRem = TRem + TOff;
202 static_assert(OffsetedRem <= TupleSize, "Incorrect parameters");
203
204 static constexpr std::size_t Idx = TupleSize - OffsetedRem;
205 static constexpr std::size_t NextRem = TRem - 1;
206 static constexpr bool HasElemsToProcess = (NextRem != 0U);
207 func(std::get<Idx>(std::forward<TTuple>(tuple)));
208 TupleForEachHelper<HasElemsToProcess>::template exec<TOff, NextRem>(
209 std::forward<TTuple>(tuple),
210 std::forward<TFunc>(func));
211 }
212};
213
214template <>
215struct TupleForEachHelper<false>
216{
217 template <std::size_t TOff, std::size_t TRem, typename TTuple, typename TFunc>
218 static void exec(TTuple&& tuple, TFunc&& func)
219 {
220 static_cast<void>(tuple);
221 static_cast<void>(func);
222 }
223};
224
225} // namespace details
226
238template <typename TTuple, typename TFunc>
239void tupleForEach(TTuple&& tuple, TFunc&& func)
240{
241 using Tuple = typename std::decay<TTuple>::type;
242 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
243 static constexpr bool HasTupleElems = (TupleSize != 0U);
244
245 details::TupleForEachHelper<HasTupleElems>::template exec<0, TupleSize>(
246 std::forward<TTuple>(tuple),
247 std::forward<TFunc>(func));
248}
249
259template <std::size_t TIdx, typename TTuple, typename TFunc>
260void tupleForEachUntil(TTuple&& tuple, TFunc&& func)
261{
262 using Tuple = typename std::decay<TTuple>::type;
263 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
264 static_assert(TIdx <= TupleSize,
265 "The index is too big.");
266
267 static constexpr bool HasTupleElems = (TIdx != 0U);
268
269 details::TupleForEachHelper<HasTupleElems>::template exec<TupleSize - TIdx, TIdx>(
270 std::forward<TTuple>(tuple),
271 std::forward<TFunc>(func));
272}
273
282template <std::size_t TIdx, typename TTuple, typename TFunc>
283void tupleForEachFrom(TTuple&& tuple, TFunc&& func)
284{
285 using Tuple = typename std::decay<TTuple>::type;
286 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
287 static_assert(TIdx <= TupleSize,
288 "The index is too big.");
289 static constexpr std::size_t RemCount = TupleSize - TIdx;
290 static constexpr bool HasTupleElems = (RemCount != 0U);
291
292 details::TupleForEachHelper<HasTupleElems>::template exec<0, RemCount>(
293 std::forward<TTuple>(tuple),
294 std::forward<TFunc>(func));
295}
296
308template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TTuple, typename TFunc>
309void tupleForEachFromUntil(TTuple&& tuple, TFunc&& func)
310{
311 using Tuple = typename std::decay<TTuple>::type;
312 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
313 static_assert(TFromIdx <= TupleSize,
314 "The from index is too big.");
315
316 static_assert(TUntilIdx <= TupleSize,
317 "The until index is too big.");
318
319 static_assert(TFromIdx <= TUntilIdx,
320 "The from index must be less than until index.");
321
322 static constexpr std::size_t FieldsCount = TUntilIdx - TFromIdx;
323 static constexpr bool HasTupleElems = (FieldsCount != 0U);
324
325 details::TupleForEachHelper<HasTupleElems>::template exec<TupleSize - TUntilIdx, FieldsCount>(
326 std::forward<TTuple>(tuple),
327 std::forward<TFunc>(func));
328}
329//----------------------------------------
330
331namespace details
332{
333
334template <bool THasElems>
335struct TupleForEachTypeHelper
336{
337 template <std::size_t TRem, typename TTuple, typename TFunc>
338 static void exec(TFunc&& func)
339 {
340 using Tuple = typename std::decay<TTuple>::type;
341 static_assert(IsTuple<Tuple>::Value, "TTuple must be std::tuple");
342 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
343 static_assert(TRem <= TupleSize, "Incorrect TRem");
344
345 static constexpr std::size_t Idx = TupleSize - TRem;
346 static constexpr std::size_t NextRem = TRem - 1U;
347 static constexpr bool NextHasElems = (NextRem != 0U);
348
349 using ElemType = typename std::tuple_element<Idx, Tuple>::type;
350#if COMMS_IS_MSVC
351 // VS compiler
352 func.operator()<ElemType>();
353#else // #if COMMS_IS_MSVC
354 func.template operator()<ElemType>();
355#endif // #if COMMS_IS_MSVC
356 TupleForEachTypeHelper<NextHasElems>::template exec<NextRem, TTuple>(
357 std::forward<TFunc>(func));
358 }
359};
360
361template <>
362struct TupleForEachTypeHelper<false>
363{
364 template <std::size_t TRem, typename TTuple, typename TFunc>
365 static void exec(TFunc&& func)
366 {
367 static_cast<void>(func);
368 }
369};
370
371} // namespace details
372
383template <typename TTuple, typename TFunc>
384void tupleForEachType(TFunc&& func)
385{
386 using Tuple = typename std::decay<TTuple>::type;
387 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
388 static constexpr bool HasElems = (TupleSize != 0U);
389
390 details::TupleForEachTypeHelper<HasElems>::template exec<TupleSize, Tuple>(
391 std::forward<TFunc>(func));
392}
393//----------------------------------------
394
395
396namespace details
397{
398
399template <bool THasElems>
400struct TupleForEachWithIdxHelper
401{
402 template <std::size_t TRem, typename TTuple, typename TFunc>
403 static void exec(TTuple&& tuple, TFunc&& func)
404 {
405 using Tuple = typename std::decay<TTuple>::type;
406 static_assert(IsTuple<Tuple>::Value, "TTuple must be std::tuple");
407 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
408 static_assert(TRem <= TupleSize, "Incorrect TRem");
409
410 static constexpr std::size_t Idx = TupleSize - TRem;
411 static constexpr std::size_t NextRem = TRem - 1;
412 static constexpr bool NextHasElems = (NextRem != 0U);
413
414 func(std::get<Idx>(std::forward<TTuple>(tuple)), Idx);
415 TupleForEachWithIdxHelper<NextHasElems>::template exec<NextRem>(
416 std::forward<TTuple>(tuple),
417 std::forward<TFunc>(func));
418 }
419};
420
421template <>
422struct TupleForEachWithIdxHelper<false>
423{
424 template <std::size_t TRem, typename TTuple, typename TFunc>
425 static void exec(TTuple&& tuple, TFunc&& func)
426 {
427 static_cast<void>(tuple);
428 static_cast<void>(func);
429 }
430};
431
432} // namespace details
433
448template <typename TTuple, typename TFunc>
449void tupleForEachWithIdx(TTuple&& tuple, TFunc&& func)
450{
451 using Tuple = typename std::decay<TTuple>::type;
452 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
453 static constexpr bool HasElems = (TupleSize != 0U);
454
455 details::TupleForEachWithIdxHelper<HasElems>::template exec<TupleSize>(
456 std::forward<TTuple>(tuple),
457 std::forward<TFunc>(func));
458}
459
460namespace details
461{
462
463template <bool THasElems>
464struct TupleForEachWithTemplateParamIdxHelper
465{
466 template <std::size_t TRem, typename TTuple, typename TFunc>
467 static void exec(TTuple&& tuple, TFunc&& func)
468 {
469 using Tuple = typename std::decay<TTuple>::type;
470 static_assert(IsTuple<Tuple>::Value, "TTuple must be std::tuple");
471 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
472 static_assert(TRem <= TupleSize, "Incorrect TRem");
473
474 static constexpr std::size_t Idx = TupleSize - TRem;
475 static constexpr std::size_t NextRem = TRem - 1;
476 static constexpr bool NextHasElems = (NextRem != 0U);
477
478#if COMMS_IS_MSVC
479 // VS compiler
480 func.operator()<Idx>(std::get<Idx>(std::forward<TTuple>(tuple)));
481#else // #if COMMS_IS_MSVC
482 func.template operator()<Idx>(std::get<Idx>(std::forward<TTuple>(tuple)));
483#endif // #if COMMS_IS_MSVC
484 TupleForEachWithTemplateParamIdxHelper<NextHasElems>::template exec<NextRem>(
485 std::forward<TTuple>(tuple),
486 std::forward<TFunc>(func));
487 }
488};
489
490template <>
491struct TupleForEachWithTemplateParamIdxHelper<false>
492{
493 template <std::size_t TRem, typename TTuple, typename TFunc>
494 static void exec(TTuple&& tuple, TFunc&& func)
495 {
496 static_cast<void>(tuple);
497 static_cast<void>(func);
498 }
499};
500
501} // namespace details
502
518
519template <typename TTuple, typename TFunc>
520void tupleForEachWithTemplateParamIdx(TTuple&& tuple, TFunc&& func)
521{
522 using Tuple = typename std::decay<TTuple>::type;
523 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
524 static constexpr bool HasElems = (TupleSize != 0U);
525
526 details::TupleForEachWithTemplateParamIdxHelper<HasElems>::template exec<TupleSize>(
527 std::forward<TTuple>(tuple),
528 std::forward<TFunc>(func));
529}
530
531
532//----------------------------------------
533
534namespace details
535{
536
537template <bool THasElems>
538struct TupleAccumulateHelper
539{
540 template <std::size_t TOff, std::size_t TRem, typename TTuple, typename TValue, typename TFunc>
541 static constexpr TValue exec(TTuple&& tuple, const TValue& value, TFunc&& func)
542 {
543 using Tuple = typename std::decay<TTuple>::type;
544 static_assert(IsTuple<Tuple>::Value, "TTuple must be std::tuple");
545 static_assert((TOff + TRem) <= std::tuple_size<Tuple>::value, "Incorrect params");
546
547 return
548 TupleAccumulateHelper<(1U < TRem)>::template exec<TOff + 1, TRem - 1U>(
549 std::forward<TTuple>(tuple),
550 func(value, std::get<TOff>(std::forward<TTuple>(tuple))),
551 std::forward<TFunc>(func));
552 }
553};
554
555template <>
556struct TupleAccumulateHelper<false>
557{
558 template <std::size_t TOff, std::size_t TRem, typename TTuple, typename TValue, typename TFunc>
559 static constexpr TValue exec(TTuple&& /* tuple */, const TValue& value, TFunc&& /* func */)
560 {
561 return value;
562 }
563};
564
565} // namespace details
566
585template <typename TTuple, typename TValue, typename TFunc>
586constexpr TValue tupleAccumulate(TTuple&& tuple, const TValue& value, TFunc&& func)
587{
588 using Tuple = typename std::decay<TTuple>::type;
589
590 return details::TupleAccumulateHelper<std::tuple_size<Tuple>::value != 0>::template exec<0, std::tuple_size<Tuple>::value>(
591 std::forward<TTuple>(tuple),
592 value,
593 std::forward<TFunc>(func));
594}
595
613template <std::size_t TFrom, std::size_t TUntil, typename TTuple, typename TValue, typename TFunc>
614constexpr TValue tupleAccumulateFromUntil(TTuple&& tuple, const TValue& value, TFunc&& func)
615{
616 using Tuple = typename std::decay<TTuple>::type;
617
618 static_assert(TFrom <= TUntil, "TFrom mustn't be greater that TUntil");
619 static_assert(TUntil <= std::tuple_size<Tuple>::value, "TUntil mustn't exceed size of the tuple");
620
621 return details::TupleAccumulateHelper<(TFrom < TUntil)>::template exec<TFrom, TUntil - TFrom>(
622 std::forward<TTuple>(tuple),
623 value,
624 std::forward<TFunc>(func));
625}
626
627//----------------------------------------
628
629namespace details
630{
631
632template <bool THasElems>
633class TupleTypeAccumulateHelper
634{
635
636public:
637 template <std::size_t TOff, std::size_t TRem, typename TTuple, typename TValue, typename TFunc>
638 static constexpr TValue exec(const TValue& value, TFunc&& func)
639 {
640 using Tuple = typename std::decay<TTuple>::type;
641 static_assert(IsTuple<Tuple>::Value, "TTuple must be std::tuple");
642 static_assert((TOff + TRem) <= std::tuple_size<Tuple>::value, "Incorrect TRem");
643
644 return TupleTypeAccumulateHelper<(1U < TRem)>::template exec<TOff + 1, TRem - 1, Tuple>(
645#if COMMS_IS_MSVC
646 func.operator()
647#else // #if COMMS_IS_MSVC
648 func.template operator()
649#endif // #if COMMS_IS_MSVC
650 <typename std::tuple_element<TOff, Tuple>::type>(value),
651 std::forward<TFunc>(func));
652 }
653
654};
655
656template <>
657class TupleTypeAccumulateHelper<false>
658{
659
660public:
661 template <std::size_t TOff, std::size_t TRem, typename TTuple, typename TValue, typename TFunc>
662 static constexpr TValue exec(const TValue& value, TFunc&& /* func */)
663 {
664 return value;
665 }
666};
667
668} // namespace details
669
684template <typename TTuple, typename TValue, typename TFunc>
685constexpr TValue tupleTypeAccumulate(const TValue& value, TFunc&& func)
686{
687 using Tuple = typename std::decay<TTuple>::type;
688 return
689 details::TupleTypeAccumulateHelper<
690 (0U < std::tuple_size<Tuple>::value)
691 >::template exec<0, std::tuple_size<Tuple>::value, Tuple>(
692 value,
693 std::forward<TFunc>(func));
694}
695
712template <std::size_t TFrom, std::size_t TUntil, typename TTuple, typename TValue, typename TFunc>
713constexpr TValue tupleTypeAccumulateFromUntil(const TValue& value, TFunc&& func)
714{
715 using Tuple = typename std::decay<TTuple>::type;
716 static_assert(TFrom <= TUntil, "TFrom mustn't be greater that TUntil");
717 static_assert(TUntil <= std::tuple_size<Tuple>::value, "TUntil mustn't exceed size of the tuple");
718 return
719 details::TupleTypeAccumulateHelper<
720 (TFrom < TUntil)
721 >::template exec<TFrom, TUntil - TFrom, Tuple>(
722 value,
723 std::forward<TFunc>(func));
724}
725
726
727//----------------------------------------
728
729
733template <typename TFirst, typename TSecond>
735{
736 static_assert(IsTuple<TFirst>::Value, "TFirst must be tuple");
737 static_assert(IsTuple<TSecond>::Value, "TSecond must be tuple");
738
740 using Type = typename std::decay<decltype(std::tuple_cat(std::declval<TFirst>(), std::declval<TSecond>()))>::type;
741};
742
745template <typename TField, typename TTuple>
747
748//----------------------------------------
749
750namespace details
751{
752
753template <bool THasElems>
754struct TupleSelectedTypeHelper;
755
756template <>
757struct TupleSelectedTypeHelper<false>
758{
759 template <std::size_t TFromIdx, std::size_t TToIdx, std::size_t TCount, typename TTuple, typename TFunc>
760 static void exec(std::size_t idx, TFunc&& func)
761 {
762 static_assert((TFromIdx + 1) == TToIdx, "Internal error: Bad parameters");
763 static_assert(TCount == 1, "Internal error: Bad parameters");
764 static_cast<void>(idx);
765 COMMS_ASSERT(idx == TFromIdx);
766 using ElemType = typename std::tuple_element<TFromIdx, TTuple>::type;
767#if COMMS_IS_MSVC
768 // VS compiler
769 func.operator()<TFromIdx, ElemType>();
770#else // #if COMMS_IS_MSVC
771 func.template operator()<TFromIdx, ElemType>();
772#endif // #if COMMS_IS_MSVC
773 }
774};
775
776template <bool THasElems>
777struct TupleSelectedTypeHelper
778{
779 template <std::size_t TFromIdx, std::size_t TToIdx, std::size_t TCount, typename TTuple, typename TFunc>
780 static void exec(std::size_t idx, TFunc&& func)
781 {
782 static_assert(1U < TCount, "Internal error: Bad parameters");
783 static_assert(TCount == (TToIdx - TFromIdx), "Internal error: Bad parameters");
784 static_assert(TFromIdx < TToIdx, "Internal error: Bad parameters");
785
786 using Tuple = typename std::decay<TTuple>::type;
787 static_assert(IsTuple<Tuple>::Value, "TTuple must be std::tuple");
788 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
789 static_assert(TCount <= TupleSize, "Incorrect TCount");
790 static_assert(0U < TCount, "Incorrect instantiation");
791
792 COMMS_ASSERT(TFromIdx <= idx);
793 COMMS_ASSERT(idx < TToIdx);
794 if (idx == TFromIdx) {
795 TupleSelectedTypeHelper<false>::template exec<TFromIdx, TFromIdx + 1, 1U, TTuple>(
796 idx, std::forward<TFunc>(func));
797 return;
798 }
799
800 static constexpr std::size_t MidIdx = TFromIdx + TCount / 2;
801 static_assert(MidIdx < TToIdx, "Internal error: bad calculation");
802 static_assert(TFromIdx <= MidIdx, "Internal error: bad calculation");
803 if (MidIdx <= idx) {
804 static constexpr std::size_t NextCount = TToIdx - MidIdx;
805 static constexpr bool HasNextElems = (1U < NextCount);
806
807 TupleSelectedTypeHelper<HasNextElems>::template exec<MidIdx, TToIdx, NextCount, TTuple>(
808 idx, std::forward<TFunc>(func));
809 return;
810 }
811
812 static constexpr std::size_t NextCount = MidIdx - TFromIdx;
813 static constexpr bool HasNextElems = (1U < NextCount);
814
815 TupleSelectedTypeHelper<HasNextElems>::template exec<TFromIdx, MidIdx, NextCount, TTuple>(
816 idx, std::forward<TFunc>(func));
817 }
818};
819
820} // namespace details
821
836template <typename TTuple, typename TFunc>
837void tupleForSelectedType(std::size_t idx, TFunc&& func)
838{
839 using Tuple = typename std::decay<TTuple>::type;
840 static_assert(isTuple<Tuple>(), "Provided tupe must be std::tuple");
841 static constexpr std::size_t TupleSize = std::tuple_size<Tuple>::value;
842 static_assert(0U < TupleSize, "Empty tuples are not supported");
843
844 details::TupleSelectedTypeHelper<(1U < TupleSize)>::template exec<0, TupleSize, TupleSize, Tuple>(
845 idx, std::forward<TFunc>(func));
846}
847//----------------------------------------
848
849namespace details
850{
851
852template <bool THasElems>
853struct TupleStripFirstN
854{
855 template <std::size_t TCount, typename TFirst, typename... TElems>
856 using Type =
857 typename TupleStripFirstN<
858 (1U < TCount)
859 >::template Type<
860 TCount - 1,
861 TElems...
862 >;
863};
864
865template <>
866struct TupleStripFirstN<false>
867{
868 template <std::size_t TCount, typename... TElems>
869 using Type = std::tuple<TElems...>;
870};
871
872template <typename TTuple>
873struct TuplePackedStripFirstN;
874
875template <typename... TElems>
876struct TuplePackedStripFirstN<std::tuple<TElems...> >
877{
878 template <std::size_t TCount>
879 using Type =
880 typename TupleStripFirstN<
881 (0 < TCount)
882 >::template Type<TCount, TElems...>;
883};
884
885template <bool TMustStrip>
886struct TupleTailCheckHelpler
887{
888 template <std::size_t TCount, typename TElems>
889 using StrippedTail =
890 typename TuplePackedStripFirstN<TElems>::template Type<
891 TCount
892 >;
893
894 template <typename TTail, typename TElems>
895 using Type =
896 std::integral_constant<
897 bool,
898 std::is_same<
899 TTail,
900 StrippedTail<
901 (std::tuple_size<TElems>::value - std::tuple_size<TTail>::value),
902 TElems
903 >
904 >::value
905 >;
906};
907
908template <>
909struct TupleTailCheckHelpler<false>
910{
911 template <typename TTail, typename TElems>
912 using Type =
913 std::integral_constant<
914 bool,
915 std::is_same<TTail, TElems>::value
916 >;
917};
918
919} // namespace details
920
924template <typename TTail, typename TTuple>
925constexpr bool tupleIsTailOf()
926{
927 static_assert(isTuple<TTail>(), "TTail param must be tuple");
928 static_assert(isTuple<TTuple>(), "TTuple param must be tuple");
929 return
930 details::TupleTailCheckHelpler<
931 std::tuple_size<TTail>::value < std::tuple_size<TTuple>::value
932 >::template Type<TTail, TTuple>::value;
933}
934
935//----------------------------------------
936
937namespace details
938{
939
940template <bool THasElems>
941class TupleTypeIsAnyOfHelper
942{
943public:
944 template <std::size_t TRem, typename TTuple, typename TFunc>
945 static constexpr bool check(TFunc&& func)
946 {
947 using Tuple = typename std::decay<TTuple>::type;
948 static_assert(IsTuple<Tuple>::Value, "TTuple must be std::tuple");
949 static_assert(TRem <= std::tuple_size<Tuple>::value, "Incorrect TRem");
950 using ElemType = typename std::tuple_element<std::tuple_size<Tuple>::value - TRem, Tuple>::type;
951 return
952#if COMMS_IS_MSVC
953 // VS compiler
954 func.operator()<ElemType>() ||
955#else // #if COMMS_IS_MSVC
956 func.template operator()<ElemType>() ||
957#endif // #if COMMS_IS_MSVC
958 TupleTypeIsAnyOfHelper<1U < TRem>::template check<TRem - 1, TTuple>(
959 std::forward<TFunc>(func));
960 }
961};
962
963template <>
964class TupleTypeIsAnyOfHelper<false>
965{
966
967public:
968 template <std::size_t TRem, typename TTuple, typename TFunc>
969 static constexpr bool check(TFunc&&)
970 {
971 return false;
972 }
973};
974
975}
976
989template <typename TTuple, typename TFunc>
990constexpr bool tupleTypeIsAnyOf(TFunc&& func)
991{
992 static_assert(isTuple<TTuple>(), "Tuple as argument is expected");
993 return details::TupleTypeIsAnyOfHelper<(0U < std::tuple_size<TTuple>::value)>::
994 template check<std::tuple_size<TTuple>::value, TTuple>(std::forward<TFunc>(func));
995}
996
997} // namespace util
998
999} // namespace comms
1000
1001COMMS_GNU_WARNING_POP
Replacement of std::aligned_storage due to deprecation since C++23.
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
Contains various compiler related definitions.
constexpr TValue tupleTypeAccumulate(const TValue &value, TFunc &&func)
Performs "accumulate" algorithm on every type of the tuple.
Definition Tuple.h:685
constexpr TValue tupleTypeAccumulateFromUntil(const TValue &value, TFunc &&func)
Performs "accumulate" algorithm on specified types inside the tuple.
Definition Tuple.h:713
void tupleForEachFrom(TTuple &&tuple, TFunc &&func)
Invoke provided functor for every element in the tuple starting from element with specified index.
Definition Tuple.h:283
constexpr bool tupleTypeIsAnyOf(TFunc &&func)
Compile time check of whether any type within a tuple has a certain condition.
Definition Tuple.h:990
void tupleForEach(TTuple &&tuple, TFunc &&func)
Invoke provided functor for every element in the tuple.
Definition Tuple.h:239
void tupleForEachFromUntil(TTuple &&tuple, TFunc &&func)
Invoke provided functor for every element in the tuple which indices are in range [TFromIdx,...
Definition Tuple.h:309
void tupleForSelectedType(std::size_t idx, TFunc &&func)
Invoke provided functor for a selected type when element index is known only at run time.
Definition Tuple.h:837
void tupleForEachType(TFunc &&func)
Invoke provided functor for every type in the tuple.
Definition Tuple.h:384
void tupleForEachWithTemplateParamIdx(TTuple &&tuple, TFunc &&func)
Invoke provided functor for every element in the tuple while providing information about element inde...
Definition Tuple.h:520
constexpr TValue tupleAccumulateFromUntil(TTuple &&tuple, const TValue &value, TFunc &&func)
Performs "accumulate" algorithm on every element of the tuple.
Definition Tuple.h:614
constexpr bool tupleIsTailOf()
Compile time check of whether one tuple is a "tail" of another.
Definition Tuple.h:925
void tupleForEachUntil(TTuple &&tuple, TFunc &&func)
Invoke provided functor for every element in the tuple until element with specified index is reached.
Definition Tuple.h:260
void tupleForEachWithIdx(TTuple &&tuple, TFunc &&func)
Invoke provided functor for every element in the tuple while providing information about element inde...
Definition Tuple.h:449
constexpr bool isTuple()
Check whether provided type is a variant of std::tuple.
Definition Tuple.h:54
typename TupleAsAlignedUnion< TTuple >::Type TupleAsAlignedUnionT
Alias to TupleAsAlignedUnion::Type.
Definition Tuple.h:185
constexpr TValue tupleAccumulate(TTuple &&tuple, const TValue &value, TFunc &&func)
Performs "accumulate" algorithm on every element of the tuple.
Definition Tuple.h:586
Main namespace for all classes / functions of COMMS library.
STL namespace.
Replacement to std::conditional.
Definition type_traits.h:28
Check whether TType type is included in the tuple TTuple.
Definition Tuple.h:95
Check whether provided type is a variant of std::tuple.
Definition Tuple.h:36
Calculated "aligned union" storage type for all the types in provided tuple.
Definition Tuple.h:158
void Type
Type definition is invalid for any type that is not std::tuple, will be specialised to proper value.
Definition Tuple.h:166
Provides the type of std::tuple_cat operation.
Definition Tuple.h:735
typename TupleCat< TField, TTuple >::Type TupleCatT
Alias to typename TupleCat<TField, TTuple>::Type.
Definition Tuple.h:746
typename std::decay< decltype(std::tuple_cat(std::declval< TFirst >(), std::declval< TSecond >()))>::type Type
Result type of tuples concatenation.
Definition Tuple.h:740
Replacement to some types from standard type_traits.