Closed wolfv closed 5 years ago
I checked to see how close we are to optional support and I think it would require at least another day of debugging.
Current issues:
This is a xtensor-only reproducer for the printing issue if someone wants to debug it:
template <class XT>
struct rna_proxy
{
using cpp_type = std::decay_t<XT>;
// constexpr static int rtype = Rcpp::traits::r_sexptype_traits<cpp_type>::rtype;
rna_proxy(XT val) : m_val(val) {};
inline operator bool() const
{
return !(m_val == -123);
}
inline rna_proxy& operator=(bool val)
{
if (val == false)
{
m_val = -123;
}
else if (m_val == -123)
{
m_val = 0;
}
return *this;
}
XT m_val;
};
template <class XT>
struct xproxy_inner_types<rna_proxy<XT>>
{
using proxy = rna_proxy<XT>;
using reference = rna_proxy<XT>;
using pointer = rna_proxy<XT>;
};
template <class T>
struct rna_proxy_functor
{
using underlying_type = std::decay_t<T>;
template <class xunderlying_type, class requested_type>
using simd_return_type = xsimd::simd_return_type<xunderlying_type, requested_type>;
using cpp_type = std::decay_t<T>;
using value_type = bool;
using reference = rna_proxy<underlying_type&>;
using const_reference = rna_proxy<const underlying_type&>;
using pointer = rna_proxy<underlying_type*>;
using const_pointer = rna_proxy<const underlying_type*>;
reference operator()(T& val) {
return val;
}
const_reference operator()(const T& val) const {
return val;
}
// template <class align, class requested_type, std::size_t N, class E>
// auto proxy_simd_load(const E& expr, std::size_t n) const
// {
// using simd_value_type = typename E::simd_value_type;
// return expr.template load_simd<align, requested_type, N>(n) == simd_value_type(NA_INTEGER);
// }
// template <class align, class simd, class E>
// auto proxy_simd_store(E& expr, std::size_t n, const simd& batch) const
// {
// using simd_value_type = typename E::simd_value_type;
// return expr.template store_simd<align>(n, xsimd::select(batch, simd_value_type(0), simd_value_type(NA_INTEGER)));
// }
};
template <class T>
class roptional_assembly;
template <class T>
struct xcontainer_inner_types<roptional_assembly<T>>
{
using raw_value_expression = xarray<T, layout_type::column_major>;
using value_storage_type = typename raw_value_expression::storage_type&;
using raw_flag_expression = xfunctor_adaptor<rna_proxy_functor<T>, xarray<T, layout_type::column_major>&>;
using flag_storage_type = xfunctor_adaptor<rna_proxy_functor<T>, xarray<T, layout_type::column_major>&>;
using storage_type = xoptional_assembly_storage<value_storage_type&, flag_storage_type&>;
using temporary_type = roptional_assembly<T>;
};
template <class T>
struct xiterable_inner_types<roptional_assembly<T>>
{
using assembly_type = roptional_assembly<T>;
using inner_shape_type = typename xarray<T, layout_type::column_major>::inner_shape_type;
using stepper = xoptional_assembly_stepper<assembly_type, false>;
using const_stepper = xoptional_assembly_stepper<assembly_type, true>;
};
template <class T>
class roptional_assembly : public xoptional_assembly_base<roptional_assembly<T>>,
public xcontainer_semantic<roptional_assembly<T>>
{
public:
using base_type = xoptional_assembly_base<roptional_assembly<T>>;
using storage_type = typename base_type::storage_type;
using assembly_type = roptional_assembly<T>;
// using base_type::base_type;
// roptional_assembly() : m_value(), m_flag(m_value) {};
roptional_assembly(xarray<T>&& rhs) : m_value(std::move(rhs)), m_flag(m_value), m_storage_proxy(m_value.storage(), m_flag)
{
}
using base_type::resize;
using base_type::reshape;
protected:
auto& value_impl() {
return m_value;
}
const auto& value_impl() const {
return m_value;
}
auto& has_value_impl() {
return m_flag;
}
const auto& has_value_impl() const {
return m_flag;
}
auto& storage_impl() {
return m_storage_proxy;
}
const auto& storage_impl() const {
return m_storage_proxy;
}
private:
xarray<T, layout_type::column_major> m_value;
xfunctor_adaptor<rna_proxy_functor<T>, xarray<T, layout_type::column_major>&> m_flag;
storage_type m_storage_proxy;
friend xoptional_assembly_base<roptional_assembly<T>>;
};
int main()
{
using d_opt_ass_type = roptional_assembly<int>;
xarray<int, layout_type::column_major> aopt = {{1, -123}, {3, 4}};
d_opt_ass_type xopti(std::move(aopt));
// {{1,2}, {xtl::missing<int>(), 4}}));
std::cout << xopti << std::endl;
}
We should probably rename the current roptional_assembly to rarray_optional
and also add a rtensor_optional
.
We should be able to merge this one should be ready to go if we require xtensor
0.19.1
and with a test.