xtensor
Loading...
Searching...
No Matches
xoptional_assembly_storage.hpp
1/***************************************************************************
2 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
3 * Copyright (c) QuantStack *
4 * *
5 * Distributed under the terms of the BSD 3-Clause License. *
6 * *
7 * The full license is in the file LICENSE, distributed with this software. *
8 ****************************************************************************/
9
10#ifndef XOPTIONAL_ASSEMBLY_STORAGE_HPP
11#define XOPTIONAL_ASSEMBLY_STORAGE_HPP
12
13#include "xoptional.hpp"
14#include "xsemantic.hpp"
15#include "xtl/xiterator_base.hpp"
16
17namespace xt
18{
19 template <class VE, class FE, bool is_const>
20 class xoptional_assembly_linear_iterator;
21
22 /******************************
23 * xoptional_assembly_storage *
24 ******************************/
25
26 template <class VE, class FE>
28 {
29 public:
30
32
33 using value_storage = std::remove_reference_t<VE>;
34 using flag_storage = std::remove_reference_t<FE>;
35
36 using value_type = xtl::xoptional<typename value_storage::value_type, typename flag_storage::value_type>;
37
38 static constexpr bool is_val_const = std::is_const<value_storage>::value;
39 static constexpr bool is_flag_const = std::is_const<flag_storage>::value;
40 using val_reference = std::
41 conditional_t<is_val_const, typename value_storage::const_reference, typename value_storage::reference>;
42 using flag_reference = std::
43 conditional_t<is_flag_const, typename flag_storage::const_reference, typename flag_storage::reference>;
44 using reference = xtl::xoptional<val_reference, flag_reference>;
45 using const_reference = xtl::xoptional<typename value_storage::const_reference, typename flag_storage::const_reference>;
46
47 using pointer = xtl::xclosure_pointer<reference>;
48 using const_pointer = xtl::xclosure_pointer<const_reference>;
49
50 using size_type = typename value_storage::size_type;
51 using difference_type = typename value_storage::difference_type;
52
55 using reverse_iterator = std::reverse_iterator<iterator>;
56 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
57
58 template <class VE1, class FE1>
60
61 template <class VE1, class FE1>
63
68
69 bool empty() const noexcept;
70 size_type size() const noexcept;
71 void resize(size_type size);
72
73 reference operator[](size_type i);
74 const_reference operator[](size_type i) const;
75
76 reference front();
77 const_reference front() const;
78
79 reference back();
80 const_reference back() const;
81
82 pointer data() noexcept;
83 const_pointer data() const noexcept;
84
85 iterator begin() noexcept;
86 iterator end() noexcept;
87
88 const_iterator begin() const noexcept;
89 const_iterator end() const noexcept;
90
91 const_iterator cbegin() const noexcept;
92 const_iterator cend() const noexcept;
93
94 reverse_iterator rbegin() noexcept;
95 reverse_iterator rend() noexcept;
96
97 const_reverse_iterator rbegin() const noexcept;
98 const_reverse_iterator rend() const noexcept;
99
100 const_reverse_iterator crbegin() const noexcept;
101 const_reverse_iterator crend() const noexcept;
102
103 void swap(self_type& rhs) noexcept;
104
105 value_storage& value() noexcept;
106 const value_storage& value() const noexcept;
107
108 flag_storage& has_value() noexcept;
109 const flag_storage& has_value() const noexcept;
110
111 private:
112
113 VE m_value;
114 FE m_has_value;
115 };
116
117 template <class VE, class FE>
118 bool
120
121 template <class VE, class FE>
122 bool
124
125 template <class VE, class FE>
126 bool
128
129 template <class VE, class FE>
130 bool
132
133 template <class VE, class FE>
134 bool
136
137 template <class VE, class FE>
138 bool
140
141 template <class VE, class FE>
143
144 /***************************************
145 * xoptional_assembly_linear_iterator *
146 ***************************************/
147
148 template <class VE, class FE, bool is_const>
150
151 template <class VE, class FE, bool is_const>
153 {
156 using value_type = typename xoptional_assembly_storage_type::value_type;
157 using reference = std::conditional_t<
158 is_const,
159 typename xoptional_assembly_storage_type::const_reference,
160 typename xoptional_assembly_storage_type::reference>;
161 using difference_type = typename xoptional_assembly_storage_type::difference_type;
162 using pointer = std::conditional_t<
163 is_const,
164 typename xoptional_assembly_storage_type::const_pointer,
165 typename xoptional_assembly_storage_type::pointer>;
166 };
167
168 template <class VE, class FE, bool is_const>
170 : public xtl::xrandom_access_iterator_base2<xoptional_assembly_linear_iterator_traits<VE, FE, is_const>>
171 {
172 public:
173
175 using base_type = xtl::xrandom_access_iterator_base2<
177
179 using value_iterator = std::conditional_t<
180 is_const,
181 typename xoptional_assembly_storage_type::value_storage::const_iterator,
182 typename xoptional_assembly_storage_type::value_storage::iterator>;
183 using flag_iterator = std::conditional_t<
184 is_const,
185 typename xoptional_assembly_storage_type::flag_storage::const_iterator,
186 typename xoptional_assembly_storage_type::flag_storage::iterator>;
187
188 using value_type = typename base_type::value_type;
189 using reference = typename base_type::reference;
190 using pointer = typename base_type::pointer;
191 using difference_type = typename base_type::difference_type;
192
193 xoptional_assembly_linear_iterator(value_iterator value_it, flag_iterator flag_it);
194
195 self_type& operator++();
196 self_type& operator--();
197
198 self_type& operator+=(difference_type n);
199 self_type& operator-=(difference_type n);
200
201 difference_type operator-(const self_type& rhs) const;
202
203 reference operator*() const;
204 pointer operator->() const;
205
206 bool operator==(const self_type& rhs) const;
207 bool operator<(const self_type& rhs) const;
208
209 private:
210
211 value_iterator m_value_it;
212 flag_iterator m_flag_it;
213 };
214
215 /*********************************************
216 * xoptional_assembly_storage implementation *
217 *********************************************/
218
219 template <class VE, class FE>
220 template <class VE1, class FE1>
222 : m_value(value_stor)
223 , m_has_value(flag_stor)
224 {
225 }
226
227 template <class VE, class FE>
228 template <class VE1, class FE1>
229 inline xoptional_assembly_storage<VE, FE>::xoptional_assembly_storage(VE1& value_stor, FE1& flag_stor)
230 : m_value(value_stor)
231 , m_has_value(flag_stor)
232 {
233 }
234
235 template <class VE, class FE>
236 inline xoptional_assembly_storage<VE, FE>::xoptional_assembly_storage(const self_type& rhs)
237 : m_value(rhs.m_value)
238 , m_has_value(rhs.m_has_value)
239 {
240 }
241
242 template <class VE, class FE>
243 inline auto xoptional_assembly_storage<VE, FE>::operator=(const self_type& rhs) -> self_type&
244 {
245 m_value = rhs.m_value;
246 m_has_value = rhs.m_has_value;
247 return *this;
248 }
249
250 template <class VE, class FE>
251 inline xoptional_assembly_storage<VE, FE>::xoptional_assembly_storage(self_type&& rhs)
252 : m_value(std::forward<VE>(rhs.m_value))
253 , m_has_value(std::forward<FE>(rhs.m_has_value))
254 {
255 }
256
257 template <class VE, class FE>
258 inline auto xoptional_assembly_storage<VE, FE>::operator=(self_type&& rhs) -> self_type&
259 {
260 m_value = std::forward<VE>(rhs.m_value);
261 m_has_value = std::forward<FE>(rhs.m_has_value);
262 return *this;
263 }
264
265 template <class VE, class FE>
266 inline bool xoptional_assembly_storage<VE, FE>::empty() const noexcept
267 {
268 return value().empty();
269 }
270
271 template <class VE, class FE>
272 inline auto xoptional_assembly_storage<VE, FE>::size() const noexcept -> size_type
273 {
274 return value().size();
275 }
276
277 template <class VE, class FE>
278 inline void xoptional_assembly_storage<VE, FE>::resize(size_type size)
279 {
280 value().resize(size);
281 has_value().resize(size);
282 }
283
284 template <class VE, class FE>
285 inline auto xoptional_assembly_storage<VE, FE>::operator[](size_type i) -> reference
286 {
287 return reference(value()[i], has_value()[i]);
288 }
289
290 template <class VE, class FE>
291 inline auto xoptional_assembly_storage<VE, FE>::operator[](size_type i) const -> const_reference
292 {
293 return const_reference(value()[i], has_value()[i]);
294 }
295
296 template <class VE, class FE>
297 inline auto xoptional_assembly_storage<VE, FE>::front() -> reference
298 {
299 return reference(value()[0], has_value()[0]);
300 }
301
302 template <class VE, class FE>
303 inline auto xoptional_assembly_storage<VE, FE>::front() const -> const_reference
304 {
305 return const_reference(value()[0], has_value()[0]);
306 }
307
308 template <class VE, class FE>
309 inline auto xoptional_assembly_storage<VE, FE>::back() -> reference
310 {
311 return reference(value()[size() - 1], has_value()[size() - 1]);
312 }
313
314 template <class VE, class FE>
315 inline auto xoptional_assembly_storage<VE, FE>::back() const -> const_reference
316 {
317 return const_reference(value()[size() - 1], has_value()[size() - 1]);
318 }
319
320 template <class VE, class FE>
321 inline auto xoptional_assembly_storage<VE, FE>::data() noexcept -> pointer
322 {
323 pointer(front());
324 }
325
326 template <class VE, class FE>
327 inline auto xoptional_assembly_storage<VE, FE>::data() const noexcept -> const_pointer
328 {
329 const_pointer(front());
330 }
331
332 template <class VE, class FE>
333 inline auto xoptional_assembly_storage<VE, FE>::begin() noexcept -> iterator
334 {
335 return iterator(value().begin(), has_value().begin());
336 }
337
338 template <class VE, class FE>
339 inline auto xoptional_assembly_storage<VE, FE>::end() noexcept -> iterator
340 {
341 return iterator(value().end(), has_value().end());
342 }
343
344 template <class VE, class FE>
345 inline auto xoptional_assembly_storage<VE, FE>::begin() const noexcept -> const_iterator
346 {
347 return cbegin();
348 }
349
350 template <class VE, class FE>
351 inline auto xoptional_assembly_storage<VE, FE>::end() const noexcept -> const_iterator
352 {
353 return cend();
354 }
355
356 template <class VE, class FE>
357 inline auto xoptional_assembly_storage<VE, FE>::cbegin() const noexcept -> const_iterator
358 {
359 return const_iterator(value().begin(), has_value().begin());
360 }
361
362 template <class VE, class FE>
363 inline auto xoptional_assembly_storage<VE, FE>::cend() const noexcept -> const_iterator
364 {
365 return const_iterator(value().end(), has_value().end());
366 }
367
368 template <class VE, class FE>
369 inline auto xoptional_assembly_storage<VE, FE>::rbegin() noexcept -> reverse_iterator
370 {
371 return reverse_iterator(end());
372 }
373
374 template <class VE, class FE>
375 inline auto xoptional_assembly_storage<VE, FE>::rend() noexcept -> reverse_iterator
376 {
377 return reverse_iterator(begin());
378 }
379
380 template <class VE, class FE>
381 inline auto xoptional_assembly_storage<VE, FE>::rbegin() const noexcept -> const_reverse_iterator
382 {
383 return crbegin();
384 }
385
386 template <class VE, class FE>
387 inline auto xoptional_assembly_storage<VE, FE>::rend() const noexcept -> const_reverse_iterator
388 {
389 return crend();
390 }
391
392 template <class VE, class FE>
393 inline auto xoptional_assembly_storage<VE, FE>::crbegin() const noexcept -> const_reverse_iterator
394 {
395 return const_reverse_iterator(cend());
396 }
397
398 template <class VE, class FE>
399 inline auto xoptional_assembly_storage<VE, FE>::crend() const noexcept -> const_reverse_iterator
400 {
401 return const_reverse_iterator(cbegin());
402 }
403
404 template <class VE, class FE>
405 inline void xoptional_assembly_storage<VE, FE>::swap(self_type& rhs) noexcept
406 {
407 m_value.swap(rhs.m_value);
408 m_has_value.swap(rhs.m_has_value);
409 }
410
411 template <class VE, class FE>
412 inline auto xoptional_assembly_storage<VE, FE>::value() noexcept -> value_storage&
413 {
414 return m_value;
415 }
416
417 template <class VE, class FE>
418 inline auto xoptional_assembly_storage<VE, FE>::value() const noexcept -> const value_storage&
419 {
420 return m_value;
421 }
422
423 template <class VE, class FE>
424 inline auto xoptional_assembly_storage<VE, FE>::has_value() noexcept -> flag_storage&
425 {
426 return m_has_value;
427 }
428
429 template <class VE, class FE>
430 inline auto xoptional_assembly_storage<VE, FE>::has_value() const noexcept -> const flag_storage&
431 {
432 return m_has_value;
433 }
434
435 template <class VE, class FE>
436 bool
437 operator==(const xoptional_assembly_storage<VE, FE>& lhs, const xoptional_assembly_storage<VE, FE>& rhs)
438 {
439 return lhs.value() == rhs.value() && lhs.has_value() == rhs.has_value();
440 }
441
442 template <class VE, class FE>
443 bool
444 operator!=(const xoptional_assembly_storage<VE, FE>& lhs, const xoptional_assembly_storage<VE, FE>& rhs)
445 {
446 return !(lhs == rhs);
447 }
448
449 template <class VE, class FE>
450 bool operator<(const xoptional_assembly_storage<VE, FE>& lhs, const xoptional_assembly_storage<VE, FE>& rhs)
451 {
452 return lhs.value() < rhs.value() && lhs.has_value() == rhs.has_value();
453 }
454
455 template <class VE, class FE>
456 bool
457 operator<=(const xoptional_assembly_storage<VE, FE>& lhs, const xoptional_assembly_storage<VE, FE>& rhs)
458 {
459 return lhs.value() <= rhs.value() && lhs.has_value() == rhs.has_value();
460 }
461
462 template <class VE, class FE>
463 bool operator>(const xoptional_assembly_storage<VE, FE>& lhs, const xoptional_assembly_storage<VE, FE>& rhs)
464 {
465 return lhs.value() > rhs.value() && lhs.has_value() == rhs.has_value();
466 }
467
468 template <class VE, class FE>
469 bool
470 operator>=(const xoptional_assembly_storage<VE, FE>& lhs, const xoptional_assembly_storage<VE, FE>& rhs)
471 {
472 return lhs.value() >= rhs.value() && lhs.has_value() == rhs.has_value();
473 }
474
475 template <class VE, class FE>
476 void swap(xoptional_assembly_storage<VE, FE>& lhs, xoptional_assembly_storage<VE, FE>& rhs) noexcept
477 {
478 lhs.swap(rhs);
479 }
480
481 /******************************************************
482 * xoptional_assembly_linear_iterator implementation *
483 ******************************************************/
484
485 template <class VE, class FE, bool C>
486 inline xoptional_assembly_linear_iterator<VE, FE, C>::xoptional_assembly_linear_iterator(
487 value_iterator value_it,
488 flag_iterator flag_it
489 )
490 : m_value_it(value_it)
491 , m_flag_it(flag_it)
492 {
493 }
494
495 template <class VE, class FE, bool C>
496 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator++() -> self_type&
497 {
498 ++m_value_it;
499 ++m_flag_it;
500 return *this;
501 }
502
503 template <class VE, class FE, bool C>
504 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator--() -> self_type&
505 {
506 --m_value_it;
507 --m_flag_it;
508 return *this;
509 }
510
511 template <class VE, class FE, bool C>
512 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator+=(difference_type n) -> self_type&
513 {
514 m_value_it += n;
515 m_flag_it += n;
516 return *this;
517 }
518
519 template <class VE, class FE, bool C>
520 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator-=(difference_type n) -> self_type&
521 {
522 m_value_it -= n;
523 m_flag_it -= n;
524 return *this;
525 }
526
527 template <class VE, class FE, bool C>
528 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator-(const self_type& rhs) const
529 -> difference_type
530 {
531 return m_value_it - rhs.m_value_it;
532 }
533
534 template <class VE, class FE, bool C>
535 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator*() const -> reference
536 {
537 return reference(*m_value_it, *m_flag_it);
538 }
539
540 template <class VE, class FE, bool C>
541 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator->() const -> pointer
542 {
543 return &(this->operator*());
544 }
545
546 template <class VE, class FE, bool C>
547 inline bool xoptional_assembly_linear_iterator<VE, FE, C>::operator==(const self_type& rhs) const
548 {
549 return m_value_it == rhs.m_value_it;
550 }
551
552 template <class VE, class FE, bool C>
553 inline bool xoptional_assembly_linear_iterator<VE, FE, C>::operator<(const self_type& rhs) const
554 {
555 return m_value_it < rhs.m_value_it;
556 }
557
558 template <class VE, class FE>
559 inline xoptional_assembly_storage<VE, FE> optional_assembly_storage(const VE& value, const FE& flag)
560 {
561 return xoptional_assembly_storage<VE, FE>(value, flag);
562 }
563
564 template <class VE, class FE>
565 inline xoptional_assembly_storage<VE, FE> optional_assembly_storage(VE& value, FE& flag)
566 {
567 return xoptional_assembly_storage<VE, FE>(value, flag);
568 }
569}
570
571#endif
auto operator*(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< detail::multiplies, E1, E2 >
Multiplication.
standard mathematical functions for xexpressions
bool operator==(const xaxis_iterator< CT > &lhs, const xaxis_iterator< CT > &rhs)
Checks equality of the iterators.
bool operator!=(const xaxis_iterator< CT > &lhs, const xaxis_iterator< CT > &rhs)
Checks inequality of the iterators.