codac 2.0.0
Loading...
Searching...
No Matches
codac2_Slice.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_SliceBase.h"
13
14namespace codac2
15{
16 template<class T>
17 class SlicedTube;
18
19 template<class T>
20 class Slice : public SliceBase,
21 protected T
22 // T class inheritance is protected, because modifying a
23 // Slice's codomain can affect adjacent gates if they exist
24 {
25 public:
26
27 explicit Slice(const SlicedTubeBase& tube, const std::list<TSlice>::iterator& it_tslice, const T& codomain)
28 : SliceBase(tube, it_tslice), T(codomain)
29 { }
30
31 Slice(const Slice& s, const SlicedTubeBase& tube)
32 : SliceBase(tube, s._it_tslice), T(s.codomain())
33 { }
34
35 // Slice objects cannot be copyable or movable,
36 // as they are supposed to be connected to other Slice objects
37 Slice(const Slice& s) = delete;
38 Slice& operator=(const Slice&) = delete;
39 Slice(Slice&&) = delete;
40 Slice& operator=(Slice&&) = delete;
41
42 inline const SlicedTube<T>& tube() const
43 {
44 return static_cast<const SlicedTube<T>&>(_tube);
45 }
46
47 inline virtual std::shared_ptr<SliceBase> copy() const
48 {
49 return std::make_shared<Slice>(*this, this->_tube);
50 }
51
52 inline Index size() const
53 {
54 return this->T::size();
55 }
56
57 inline T& codomain()
58 {
59 return (T&)(*this);
60 }
61
62 inline const T& codomain() const
63 {
64 return (const T&)(*this);
65 }
66
67 inline bool is_gate() const
68 {
69 return t0_tf().is_degenerated();
70 }
71
72 inline std::shared_ptr<const Slice<T>> prev_slice() const
73 {
74 return std::static_pointer_cast<const Slice<T>>(
75 this->SliceBase::prev_slice());
76 }
77
78 inline std::shared_ptr<Slice<T>> prev_slice()
79 {
80 return std::const_pointer_cast<Slice<T>>(
81 static_cast<const Slice<T>&>(*this).prev_slice());
82 }
83
84 inline std::shared_ptr<const Slice<T>> next_slice() const
85 {
86 return std::static_pointer_cast<const Slice<T>>(
87 this->SliceBase::next_slice());
88 }
89
90 inline std::shared_ptr<Slice<T>> next_slice()
91 {
92 return std::const_pointer_cast<Slice<T>>(
93 static_cast<const Slice<T>&>(*this).next_slice());
94 }
95
96 inline T input_gate() const
97 {
98 if(!prev_slice())
99 return codomain();
100
101 else
102 {
103 if(prev_slice()->is_gate())
104 return prev_slice()->codomain();
105 else
106 return codomain() & prev_slice()->codomain();
107 }
108 }
109
110 inline T output_gate() const
111 {
112 if(!next_slice())
113 return codomain();
114
115 else
116 {
117 if(next_slice()->is_gate())
118 return next_slice()->codomain();
119 else
120 return codomain() & next_slice()->codomain();
121 }
122 }
123
124 inline std::pair<T,T> enclosed_bounds(const Interval& t) const
125 {
126 T x = *this; x.set_empty();
127 auto bounds = std::make_pair(x,x);
128
129 if(t.lb() < t0_tf().lb() || t.ub() > t0_tf().ub())
130 {
131 x.init(Interval(-oo,0));
132 bounds.first |= x;
133 x.init(Interval(0,oo));
134 bounds.second |= x;
135 }
136
137 if(t.contains(t0_tf().lb()))
138 {
139 bounds.first |= input_gate().lb();
140 bounds.second |= input_gate().ub();
141 }
142
143 if(t.contains(t0_tf().ub()))
144 {
145 bounds.first |= output_gate().lb();
146 bounds.second |= output_gate().ub();
147 }
148
149 if(t.is_subset(t0_tf()) && t != t0_tf().lb() && t != t0_tf().ub())
150 {
151 bounds.first |= this->lb();
152 bounds.second |= this->ub();
153 }
154
155 return bounds;
156 }
157
158 inline void set(const T& x, bool propagate = true)
159 {
160 assert_release(x.size() == this->size());
161 codomain() = x;
162 if(propagate)
163 update_adjacent_codomains();
164 }
165
166 inline void init()
167 {
168 this->T::init();
169 // Nothing to propagate to adjacent codomains
170 }
171
172 inline void set_empty()
173 {
174 set_empty(true);
175 }
176
177 inline bool operator==(const Slice& x) const
178 {
179 return codomain() == x.codomain();
180 }
181
182 friend inline std::ostream& operator<<(std::ostream& os, const Slice& x)
183 {
184 os << x.t0_tf()
185 << "↦" << x.codomain()
186 << std::flush;
187 return os;
188 }
189
190 protected:
191
192 template<typename T_>
193 friend class SlicedTube;
194
195 inline void set_empty(bool propagate)
196 {
197 this->T::set_empty();
198 if(propagate)
199 update_adjacent_codomains();
200 }
201
202 inline void update_adjacent_codomains()
203 {
204 if(prev_slice())
205 {
206 assert(prev_slice()->size() == this->size());
207 if(is_gate())
208 codomain() &= prev_slice()->codomain();
209 else if(prev_slice()->is_gate())
210 prev_slice()->codomain() &= codomain();
211 }
212
213 if(next_slice())
214 {
215 assert(next_slice()->size() == this->size());
216 if(is_gate())
217 codomain() &= next_slice()->codomain();
218 else if(next_slice()->is_gate())
219 next_slice()->codomain() &= codomain();
220 }
221 }
222 };
223}