10#ifndef XOPTIONAL_ASSEMBLY_HPP
11#define XOPTIONAL_ASSEMBLY_HPP
13#include "xoptional.hpp"
14#include "xoptional_assembly_base.hpp"
15#include "xsemantic.hpp"
24 template <
class VE,
class FE>
25 class xoptional_assembly;
27 template <
class VE,
class FE>
31 using value_storage_type =
typename raw_value_expression::storage_type&;
33 using flag_storage_type =
typename raw_flag_expression::storage_type&;
38 template <
class VE,
class FE>
42 using inner_shape_type =
typename VE::inner_shape_type;
60 template <
class VE,
class FE>
69 using raw_value_expression =
typename base_type::raw_value_expression;
70 using raw_flag_expression =
typename base_type::raw_flag_expression;
71 using value_expression =
typename base_type::value_expression;
72 using flag_expression =
typename base_type::flag_expression;
73 using const_value_expression =
typename base_type::const_value_expression;
74 using const_flag_expression =
typename base_type::const_flag_expression;
75 using storage_type =
typename base_type::storage_type;
76 using value_type =
typename base_type::value_type;
77 using reference =
typename base_type::reference;
78 using const_reference =
typename base_type::const_reference;
79 using pointer =
typename base_type::pointer;
80 using const_pointer =
typename base_type::const_pointer;
81 using shape_type =
typename base_type::shape_type;
82 using strides_type =
typename base_type::strides_type;
89 const shape_type&
shape,
90 const value_type&
value,
109 template <
class S = shape_type>
128 storage_type& storage_impl()
noexcept;
129 const storage_type& storage_impl()
const noexcept;
131 value_expression value_impl()
noexcept;
132 const_value_expression value_impl()
const noexcept;
134 flag_expression has_value_impl()
noexcept;
135 const_flag_expression has_value_impl()
const noexcept;
137 raw_value_expression m_value;
138 raw_flag_expression m_has_value;
139 storage_type m_storage;
148 template <
class VEC,
class FEC>
151 template <
class VEC,
class FEC>
154 using raw_value_expression = std::remove_reference_t<VEC>;
155 using value_storage_type = std::conditional_t<
156 std::is_const<raw_value_expression>::value,
157 const typename raw_value_expression::storage_type&,
158 typename raw_value_expression::storage_type&>;
159 using raw_flag_expression = std::remove_reference_t<FEC>;
160 using flag_storage_type = std::conditional_t<
161 std::is_const<raw_flag_expression>::value,
162 const typename raw_flag_expression::storage_type&,
163 typename raw_flag_expression::storage_type&>;
168 template <
class VEC,
class FEC>
172 using inner_shape_type =
typename std::decay_t<VEC>::inner_shape_type;
189 template <
class VEC,
class FEC>
198 using storage_type =
typename base_type::storage_type;
199 using value_expression =
typename base_type::value_expression;
200 using flag_expression =
typename base_type::flag_expression;
201 using const_value_expression =
typename base_type::const_value_expression;
202 using const_flag_expression =
typename base_type::const_flag_expression;
203 using value_type =
typename base_type::value_type;
204 using reference =
typename base_type::reference;
205 using const_reference =
typename base_type::const_reference;
206 using pointer =
typename base_type::pointer;
207 using const_pointer =
typename base_type::const_pointer;
208 using shape_type =
typename base_type::shape_type;
209 using strides_type =
typename base_type::strides_type;
210 using temporary_type =
typename semantic_base::temporary_type;
214 template <
class OVE,
class OFE>
231 storage_type& storage_impl()
noexcept;
232 const storage_type& storage_impl()
const noexcept;
234 value_expression value_impl()
noexcept;
235 const_value_expression value_impl()
const noexcept;
237 flag_expression has_value_impl()
noexcept;
238 const_flag_expression has_value_impl()
const noexcept;
242 storage_type m_storage;
253 template <
class T,
class S>
254 inline void nested_optional_copy(T&&
iter,
const S&
s)
256 iter->value() =
s.value();
257 iter->has_value() =
s.has_value();
261 template <
class T,
class S>
262 inline void nested_optional_copy(T&& iter, std::initializer_list<S> s)
264 for (
auto it = s.begin(); it != s.end(); ++it)
266 nested_optional_copy(std::forward<T>(iter), *it);
278 template <
class VE,
class FE>
282 , m_storage(m_value.storage(), m_has_value.storage())
292 template <
class VE,
class FE>
295 , m_has_value(shape,
l)
296 , m_storage(m_value.storage(), m_has_value.storage())
307 template <
class VE,
class FE>
309 const shape_type& shape,
310 const value_type& value,
313 : m_value(shape, value.value(),
l)
314 , m_has_value(shape, value.has_value(),
l)
315 , m_storage(m_value.storage(), m_has_value.storage())
324 template <
class VE,
class FE>
328 , m_storage(m_value.storage(), m_has_value.storage())
339 template <
class VE,
class FE>
341 const shape_type& shape,
343 const value_type& value
345 : m_value(shape,
strides, value.value())
346 , m_has_value(shape,
strides, value.has_value())
347 , m_storage(m_value.storage(), m_has_value.storage())
356 template <
class VE,
class FE>
358 : m_value(value.value())
359 , m_has_value(value.has_value())
360 , m_storage(m_value.storage(), m_has_value.storage())
369 template <
class VE,
class FE>
372 , m_has_value(
ve.shape(),
true,
ve.layout())
373 , m_storage(m_value.storage(), m_has_value.storage())
384 template <
class VE,
class FE>
387 , m_has_value(
ve.shape(),
true,
ve.layout())
388 , m_storage(m_value.storage(), m_has_value.storage())
398 template <
class VE,
class FE>
399 template <
class OVE,
class OFE,
typename>
403 , m_storage(m_value.storage(), m_has_value.storage())
417 template <
class VE,
class FE>
422 , m_storage(m_value.storage(), m_has_value.storage())
427 condition ? detail::nested_optional_copy(this->linear_begin(),
t)
435 template <
class VE,
class FE>
440 , m_storage(m_value.storage(), m_has_value.storage())
445 condition ? detail::nested_optional_copy(this->linear_begin(),
t)
453 template <
class VE,
class FE>
458 , m_storage(m_value.storage(), m_has_value.storage())
463 condition ? detail::nested_optional_copy(this->linear_begin(),
t)
471 template <
class VE,
class FE>
476 , m_storage(m_value.storage(), m_has_value.storage())
481 condition ? detail::nested_optional_copy(this->linear_begin(),
t)
489 template <
class VE,
class FE>
494 , m_storage(m_value.storage(), m_has_value.storage())
499 condition ? detail::nested_optional_copy(this->linear_begin(),
t)
509 template <
class VE,
class FE>
513 shape_type shape = xtl::forward_sequence<shape_type, S>(
s);
517 template <
class VE,
class FE>
521 , m_value(
rhs.m_value)
522 , m_has_value(
rhs.m_has_value)
523 , m_storage(m_value.storage(), m_has_value.storage())
527 template <
class VE,
class FE>
531 , m_value(rhs.m_value)
532 , m_has_value(rhs.m_has_value)
533 , m_storage(m_value.storage(), m_has_value.storage())
537 template <
class VE,
class FE>
538 inline auto xoptional_assembly<VE, FE>::operator=(
const self_type& rhs) -> self_type&
540 base_type::operator=(rhs);
541 m_value = rhs.m_value;
542 m_has_value = rhs.m_has_value;
546 template <
class VE,
class FE>
547 inline auto xoptional_assembly<VE, FE>::operator=(self_type&& rhs) -> self_type&
549 base_type::operator=(rhs);
550 m_value = std::move(rhs.m_value);
551 m_has_value = std::move(rhs.m_has_value);
562 template <
class VE,
class FE>
568 , m_storage(m_value.storage(), m_has_value.storage())
570 semantic_base::assign(
e);
576 template <
class VE,
class FE>
580 return semantic_base::operator=(
e);
585 template <
class VE,
class FE>
591 template <
class VE,
class FE>
592 inline auto xoptional_assembly<VE, FE>::storage_impl() const noexcept -> const storage_type&
597 template <
class VE,
class FE>
598 inline auto xoptional_assembly<VE, FE>::value_impl() noexcept -> value_expression
603 template <
class VE,
class FE>
604 inline auto xoptional_assembly<VE, FE>::value_impl() const noexcept -> const_value_expression
609 template <
class VE,
class FE>
610 inline auto xoptional_assembly<VE, FE>::has_value_impl() noexcept -> flag_expression
615 template <
class VE,
class FE>
616 inline auto xoptional_assembly<VE, FE>::has_value_impl() const noexcept -> const_flag_expression
635 template <
class VEC,
class FEC>
636 template <
class OVE,
class OFE>
640 , m_storage(m_value.storage(), m_has_value.storage())
646 template <
class VEC,
class FEC>
650 , m_value(
rhs.m_value)
651 , m_has_value(
rhs.m_has_value)
652 , m_storage(m_value.storage(), m_has_value.storage())
656 template <
class VEC,
class FEC>
657 inline auto xoptional_assembly_adaptor<VEC, FEC>::operator=(
const self_type& rhs) -> self_type&
659 base_type::operator=(rhs);
660 m_value = rhs.m_value;
661 m_has_value = rhs.m_has_value;
665 template <
class VEC,
class FEC>
669 , m_value(rhs.m_value)
670 , m_has_value(rhs.m_has_value)
671 , m_storage(m_value.storage(), m_has_value.storage())
675 template <
class VEC,
class FEC>
676 inline auto xoptional_assembly_adaptor<VEC, FEC>::operator=(self_type&& rhs) -> self_type&
678 base_type::operator=(std::move(rhs));
679 m_value = rhs.m_value;
680 m_has_value = rhs.m_has_value;
684 template <
class VEC,
class FEC>
685 inline auto xoptional_assembly_adaptor<VEC, FEC>::operator=(temporary_type&& tmp) -> self_type&
687 m_value = std::move(tmp.value());
688 m_has_value = std::move(tmp.has_value());
699 template <
class VEC,
class FEC>
703 return semantic_base::operator=(
e);
708 template <
class VEC,
class FEC>
714 template <
class VEC,
class FEC>
715 inline auto xoptional_assembly_adaptor<VEC, FEC>::storage_impl() const noexcept -> const storage_type&
720 template <
class VEC,
class FEC>
721 inline auto xoptional_assembly_adaptor<VEC, FEC>::value_impl() noexcept -> value_expression
726 template <
class VEC,
class FEC>
727 inline auto xoptional_assembly_adaptor<VEC, FEC>::value_impl() const noexcept -> const_value_expression
732 template <
class VEC,
class FEC>
733 inline auto xoptional_assembly_adaptor<VEC, FEC>::has_value_impl() noexcept -> flag_expression
738 template <
class VEC,
class FEC>
739 inline auto xoptional_assembly_adaptor<VEC, FEC>::has_value_impl() const noexcept -> const_flag_expression
Implementation of the xsemantic_base interface for dense multidimensional containers.
Dense multidimensional adaptor holding optional values, optimized for tensor operations.
xoptional_assembly_adaptor(OVE &&ve, OFE &&fe)
Constructs an xoptional_assembly_adaptor of the given value and missing mask expressions.
Base class for dense multidimensional optional assemblies.
const inner_shape_type & shape() const noexcept
Returns the shape of the optional assembly.
value_expression value() noexcept
Return an expression for the values of the optional assembly.
const inner_strides_type & strides() const noexcept
Returns the strides of the optional assembly.
void resize(const S &shape, bool force=false)
Resizes the optional assembly.
Dense multidimensional container holding optional values, optimized for tensor operations.
xoptional_assembly()
Allocates an uninitialized xoptional_assembly that holds 0 element.
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
standard mathematical functions for xexpressions