codac 1.5.6
Loading...
Searching...
No Matches
codac2_CtcUnion.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include <type_traits>
13#include "codac2_CtcWrapper.h"
14#include "codac2_Collection.h"
16
17namespace codac2
18{
19 template<typename... X>
20 class CtcUnion : public Ctc<CtcUnion<X...>,X...>
21 {
22 public:
23
24 explicit CtcUnion(Index n)
25 : Ctc<CtcUnion<X...>,X...>(n)
26 {
27 if constexpr(std::is_same_v<X...,Interval>)
28 assert_release(n == 1);
29 }
30
31 template<typename C>
32 requires (IsCtcBaseOrPtr<C,X...> && !std::is_same_v<CtcUnion<X...>,C>)
33 CtcUnion(const C& c)
34 : Ctc<CtcUnion<X...>,X...>(size_of(c)), _ctcs(c)
35 { }
36
37 template<typename... C>
38 requires (IsCtcBaseOrPtr<C,X...> && ...)
39 CtcUnion(const C&... c)
40 : Ctc<CtcUnion<X...>,X...>(size_first_item(c...)), _ctcs(c...)
41 {
42 assert_release(all_same_size(c...));
43 }
44
45 template<typename X_> // single type
46 void contract_impl(X_& x) const
47 {
48 auto result = x;
49 result.set_empty();
50
51 for(const auto& ci : _ctcs)
52 {
53 auto saved_x = x;
54 ci->contract(saved_x);
55 result |= saved_x;
56 }
57
58 x = result;
59 }
60
61 void contract(X&... x) const
62 {
63 // contract_impl(..) method for multiple types is not yet implemented
64 contract_impl(x...);
65 }
66
67 template<typename C>
68 requires std::is_base_of_v<CtcBase<X...>,C>
69 CtcUnion<X...>& operator|=(const C& c)
70 {
71 assert_release(c.size() == this->size());
72 _ctcs.push_object_back(c);
73 return *this;
74 }
75
76 CtcUnion<X...>& operator|=(const std::shared_ptr<CtcBase<X...>>& c)
77 {
78 assert_release(c->size() == this->size());
79 _ctcs.push_back(c);
80 return *this;
81 }
82
83 protected:
84
85 Collection<CtcBase<X...>> _ctcs;
86 };
87
88 template <>
89 class CtcUnion<> : public CtcUnion<IntervalVector>
90 { };
91
92 template<typename Tuple>
93 struct CtcUnionType;
94
95 template<typename... T>
96 struct CtcUnionType<std::tuple<T...>> {
97 using Ctc = CtcUnion<T...>;
98 };
99
100 template<typename C1, typename C2>
101 typename CtcUnionType<typename C1::ContractedTypes>::Ctc operator|(const C1& c1, const C2& c2)
102 {
103 return { c1, c2 };
104 }
105
106 template<typename C2>
107 requires std::is_base_of_v<CtcBase<IntervalVector>,C2>
108 inline CtcUnion<IntervalVector> operator|(const IntervalVector& c1, const C2& c2)
109 {
110 assert_release(c1.size() == c2.size());
111 return CtcUnion<IntervalVector>(CtcWrapper(c1),c2);
112 }
113
114 template<typename C1>
115 requires std::is_base_of_v<CtcBase<IntervalVector>,C1>
116 inline CtcUnion<IntervalVector> operator|(const C1& c1, const IntervalVector& c2)
117 {
118 assert_release(c1.size() == c2.size());
119 return CtcUnion<IntervalVector>(c1,CtcWrapper(c2));
120 }
121}