codac 1.5.6
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 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)
159 {
160 set(x, true);
161 }
162
163 inline void init()
164 {
165 this->T::init();
166 // Nothing to propagate to adjacent codomains
167 }
168
169 inline void set_empty()
170 {
171 set_empty(true);
172 }
173
174 inline bool operator==(const Slice& x) const
175 {
176 return codomain() == x.codomain();
177 }
178
179 friend inline std::ostream& operator<<(std::ostream& os, const Slice& x)
180 {
181 os << x.t0_tf()
182 << "↦" << x.codomain()
183 << std::flush;
184 return os;
185 }
186
187 protected:
188
189 template<typename T_>
190 friend class SlicedTube;
191
192 inline void set(const T& x, bool propagate)
193 {
194 assert_release(x.size() == this->size());
195 codomain() = x;
196 if(propagate)
197 update_adjacent_codomains();
198 }
199
200 inline void set_empty(bool propagate)
201 {
202 this->T::set_empty();
203 if(propagate)
204 update_adjacent_codomains();
205 }
206
207 inline void update_adjacent_codomains()
208 {
209 if(prev_slice())
210 {
211 assert(prev_slice()->size() == this->size());
212 if(is_gate())
213 codomain() &= prev_slice()->codomain();
214 else if(prev_slice()->is_gate())
215 prev_slice()->codomain() &= codomain();
216 }
217
218 if(next_slice())
219 {
220 assert(next_slice()->size() == this->size());
221 if(is_gate())
222 codomain() &= next_slice()->codomain();
223 else if(next_slice()->is_gate())
224 next_slice()->codomain() &= codomain();
225 }
226 }
227 };
228}