10#ifndef XOPTIONAL_ASSEMBLY_STORAGE_HPP
11#define XOPTIONAL_ASSEMBLY_STORAGE_HPP
13#include "xoptional.hpp"
14#include "xsemantic.hpp"
15#include "xtl/xiterator_base.hpp"
19 template <
class VE,
class FE,
bool is_const>
20 class xoptional_assembly_linear_iterator;
26 template <
class VE,
class FE>
33 using value_storage = std::remove_reference_t<VE>;
34 using flag_storage = std::remove_reference_t<FE>;
36 using value_type = xtl::xoptional<typename value_storage::value_type, typename flag_storage::value_type>;
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>;
47 using pointer = xtl::xclosure_pointer<reference>;
48 using const_pointer = xtl::xclosure_pointer<const_reference>;
50 using size_type =
typename value_storage::size_type;
51 using difference_type =
typename value_storage::difference_type;
55 using reverse_iterator = std::reverse_iterator<iterator>;
56 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
58 template <
class VE1,
class FE1>
61 template <
class VE1,
class FE1>
69 bool empty()
const noexcept;
70 size_type size()
const noexcept;
71 void resize(size_type size);
73 reference operator[](size_type
i);
74 const_reference operator[](size_type
i)
const;
77 const_reference front()
const;
80 const_reference back()
const;
82 pointer data()
noexcept;
83 const_pointer data()
const noexcept;
94 reverse_iterator rbegin()
noexcept;
95 reverse_iterator rend()
noexcept;
97 const_reverse_iterator rbegin()
const noexcept;
98 const_reverse_iterator rend()
const noexcept;
100 const_reverse_iterator crbegin()
const noexcept;
101 const_reverse_iterator crend()
const noexcept;
105 value_storage& value()
noexcept;
106 const value_storage& value()
const noexcept;
108 flag_storage& has_value()
noexcept;
109 const flag_storage& has_value()
const noexcept;
117 template <
class VE,
class FE>
121 template <
class VE,
class FE>
125 template <
class VE,
class FE>
129 template <
class VE,
class FE>
133 template <
class VE,
class FE>
137 template <
class VE,
class FE>
141 template <
class VE,
class FE>
148 template <
class VE,
class FE,
bool is_const>
151 template <
class VE,
class FE,
bool is_const>
156 using value_type =
typename xoptional_assembly_storage_type::value_type;
157 using reference = std::conditional_t<
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<
164 typename xoptional_assembly_storage_type::const_pointer,
165 typename xoptional_assembly_storage_type::pointer>;
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>>
175 using base_type = xtl::xrandom_access_iterator_base2<
179 using value_iterator = std::conditional_t<
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<
185 typename xoptional_assembly_storage_type::flag_storage::const_iterator,
186 typename xoptional_assembly_storage_type::flag_storage::iterator>;
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;
203 reference operator*()
const;
204 pointer operator->()
const;
211 value_iterator m_value_it;
212 flag_iterator m_flag_it;
219 template <
class VE,
class FE>
220 template <
class VE1,
class FE1>
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)
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)
242 template <
class VE,
class FE>
243 inline auto xoptional_assembly_storage<VE, FE>::operator=(
const self_type& rhs) -> self_type&
245 m_value = rhs.m_value;
246 m_has_value = rhs.m_has_value;
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))
257 template <
class VE,
class FE>
258 inline auto xoptional_assembly_storage<VE, FE>::operator=(self_type&& rhs) -> self_type&
260 m_value = std::forward<VE>(rhs.m_value);
261 m_has_value = std::forward<FE>(rhs.m_has_value);
265 template <
class VE,
class FE>
266 inline bool xoptional_assembly_storage<VE, FE>::empty() const noexcept
268 return value().empty();
271 template <
class VE,
class FE>
272 inline auto xoptional_assembly_storage<VE, FE>::size() const noexcept -> size_type
274 return value().size();
277 template <
class VE,
class FE>
278 inline void xoptional_assembly_storage<VE, FE>::resize(size_type size)
280 value().resize(size);
281 has_value().resize(size);
284 template <
class VE,
class FE>
285 inline auto xoptional_assembly_storage<VE, FE>::operator[](size_type i) -> reference
287 return reference(value()[i], has_value()[i]);
290 template <
class VE,
class FE>
291 inline auto xoptional_assembly_storage<VE, FE>::operator[](size_type i)
const -> const_reference
293 return const_reference(value()[i], has_value()[i]);
296 template <
class VE,
class FE>
297 inline auto xoptional_assembly_storage<VE, FE>::front() -> reference
299 return reference(value()[0], has_value()[0]);
302 template <
class VE,
class FE>
303 inline auto xoptional_assembly_storage<VE, FE>::front() const -> const_reference
305 return const_reference(value()[0], has_value()[0]);
308 template <
class VE,
class FE>
309 inline auto xoptional_assembly_storage<VE, FE>::back() -> reference
311 return reference(value()[size() - 1], has_value()[size() - 1]);
314 template <
class VE,
class FE>
315 inline auto xoptional_assembly_storage<VE, FE>::back() const -> const_reference
317 return const_reference(value()[size() - 1], has_value()[size() - 1]);
320 template <
class VE,
class FE>
321 inline auto xoptional_assembly_storage<VE, FE>::data() noexcept -> pointer
326 template <
class VE,
class FE>
327 inline auto xoptional_assembly_storage<VE, FE>::data() const noexcept -> const_pointer
329 const_pointer(front());
332 template <
class VE,
class FE>
333 inline auto xoptional_assembly_storage<VE, FE>::begin() noexcept -> iterator
335 return iterator(value().begin(), has_value().begin());
338 template <
class VE,
class FE>
339 inline auto xoptional_assembly_storage<VE, FE>::end() noexcept -> iterator
341 return iterator(value().end(), has_value().end());
344 template <
class VE,
class FE>
345 inline auto xoptional_assembly_storage<VE, FE>::begin() const noexcept -> const_iterator
350 template <
class VE,
class FE>
351 inline auto xoptional_assembly_storage<VE, FE>::end() const noexcept -> const_iterator
356 template <
class VE,
class FE>
357 inline auto xoptional_assembly_storage<VE, FE>::cbegin() const noexcept -> const_iterator
359 return const_iterator(value().begin(), has_value().begin());
362 template <
class VE,
class FE>
363 inline auto xoptional_assembly_storage<VE, FE>::cend() const noexcept -> const_iterator
365 return const_iterator(value().end(), has_value().end());
368 template <
class VE,
class FE>
369 inline auto xoptional_assembly_storage<VE, FE>::rbegin() noexcept -> reverse_iterator
371 return reverse_iterator(end());
374 template <
class VE,
class FE>
375 inline auto xoptional_assembly_storage<VE, FE>::rend() noexcept -> reverse_iterator
377 return reverse_iterator(begin());
380 template <
class VE,
class FE>
381 inline auto xoptional_assembly_storage<VE, FE>::rbegin() const noexcept -> const_reverse_iterator
386 template <
class VE,
class FE>
387 inline auto xoptional_assembly_storage<VE, FE>::rend() const noexcept -> const_reverse_iterator
392 template <
class VE,
class FE>
393 inline auto xoptional_assembly_storage<VE, FE>::crbegin() const noexcept -> const_reverse_iterator
395 return const_reverse_iterator(cend());
398 template <
class VE,
class FE>
399 inline auto xoptional_assembly_storage<VE, FE>::crend() const noexcept -> const_reverse_iterator
401 return const_reverse_iterator(cbegin());
404 template <
class VE,
class FE>
405 inline void xoptional_assembly_storage<VE, FE>::swap(self_type& rhs)
noexcept
407 m_value.swap(rhs.m_value);
408 m_has_value.swap(rhs.m_has_value);
411 template <
class VE,
class FE>
412 inline auto xoptional_assembly_storage<VE, FE>::value() noexcept -> value_storage&
417 template <
class VE,
class FE>
418 inline auto xoptional_assembly_storage<VE, FE>::value() const noexcept -> const value_storage&
423 template <
class VE,
class FE>
424 inline auto xoptional_assembly_storage<VE, FE>::has_value() noexcept -> flag_storage&
429 template <
class VE,
class FE>
430 inline auto xoptional_assembly_storage<VE, FE>::has_value() const noexcept -> const flag_storage&
435 template <
class VE,
class FE>
437 operator==(
const xoptional_assembly_storage<VE, FE>& lhs,
const xoptional_assembly_storage<VE, FE>& rhs)
439 return lhs.value() == rhs.value() && lhs.has_value() == rhs.has_value();
442 template <
class VE,
class FE>
444 operator!=(
const xoptional_assembly_storage<VE, FE>& lhs,
const xoptional_assembly_storage<VE, FE>& rhs)
446 return !(lhs == rhs);
449 template <
class VE,
class FE>
450 bool operator<(
const xoptional_assembly_storage<VE, FE>& lhs,
const xoptional_assembly_storage<VE, FE>& rhs)
452 return lhs.value() < rhs.value() && lhs.has_value() == rhs.has_value();
455 template <
class VE,
class FE>
457 operator<=(
const xoptional_assembly_storage<VE, FE>& lhs,
const xoptional_assembly_storage<VE, FE>& rhs)
459 return lhs.value() <= rhs.value() && lhs.has_value() == rhs.has_value();
462 template <
class VE,
class FE>
463 bool operator>(
const xoptional_assembly_storage<VE, FE>& lhs,
const xoptional_assembly_storage<VE, FE>& rhs)
465 return lhs.value() > rhs.value() && lhs.has_value() == rhs.has_value();
468 template <
class VE,
class FE>
470 operator>=(
const xoptional_assembly_storage<VE, FE>& lhs,
const xoptional_assembly_storage<VE, FE>& rhs)
472 return lhs.value() >= rhs.value() && lhs.has_value() == rhs.has_value();
475 template <
class VE,
class FE>
476 void swap(xoptional_assembly_storage<VE, FE>& lhs, xoptional_assembly_storage<VE, FE>& rhs)
noexcept
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
490 : m_value_it(value_it)
495 template <
class VE,
class FE,
bool C>
496 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator++() -> self_type&
503 template <
class VE,
class FE,
bool C>
504 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator--() -> self_type&
511 template <
class VE,
class FE,
bool C>
512 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator+=(difference_type n) -> self_type&
519 template <
class VE,
class FE,
bool C>
520 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator-=(difference_type n) -> self_type&
527 template <
class VE,
class FE,
bool C>
528 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator-(
const self_type& rhs)
const
531 return m_value_it - rhs.m_value_it;
534 template <
class VE,
class FE,
bool C>
535 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator*() const -> reference
537 return reference(*m_value_it, *m_flag_it);
540 template <
class VE,
class FE,
bool C>
541 inline auto xoptional_assembly_linear_iterator<VE, FE, C>::operator->() const -> pointer
546 template <
class VE,
class FE,
bool C>
547 inline bool xoptional_assembly_linear_iterator<VE, FE, C>::operator==(
const self_type& rhs)
const
549 return m_value_it == rhs.m_value_it;
552 template <
class VE,
class FE,
bool C>
553 inline bool xoptional_assembly_linear_iterator<VE, FE, C>::operator<(
const self_type& rhs)
const
555 return m_value_it < rhs.m_value_it;
558 template <
class VE,
class FE>
559 inline xoptional_assembly_storage<VE, FE> optional_assembly_storage(
const VE& value,
const FE& flag)
561 return xoptional_assembly_storage<VE, FE>(value, flag);
564 template <
class VE,
class FE>
565 inline xoptional_assembly_storage<VE, FE> optional_assembly_storage(VE& value, FE& flag)
567 return xoptional_assembly_storage<VE, FE>(value, flag);
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.