CRTP base class providing common immutable interface for arrays with bitmaps.
CRTP base class providing common immutable interface for arrays with bitmaps. This class defines and implements the standard interface for arrays that hold nullable elements using a validity bitmap. It provides efficient iteration, element access, and range-based operations while maintaining Arrow format compatibility.
#pragma once
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <ranges>
#include <utility>
{
struct array_inner_types_base
{
using bitmap_type = dynamic_bitset_view<std::uint8_t>;
};
template <class D>
struct array_inner_types;
template <class D>
class array_crtp_base : public crtp_base<D>
{
public:
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using bitmap_type = typename inner_types::bitmap_type;
using bitmap_iterator = bitmap_type::iterator;
using const_reference = nullable<inner_const_reference, bitmap_const_reference>;
struct iterator_types
{
};
[[nodiscard]]
constexpr std::optional<std::string_view>
name()
const;
[[nodiscard]] std::optional<key_value_view>
metadata()
const;
[[nodiscard]]
constexpr bool empty()
const;
[[nodiscard]]
constexpr size_type
size()
const;
[[nodiscard]]
constexpr D
slice(size_type start, size_type
end)
const;
[[nodiscard]]
constexpr D
slice_view(size_type start, size_type
end)
const;
protected:
[[nodiscard]]
constexpr const arrow_proxy&
get_arrow_proxy()
const noexcept;
private:
arrow_proxy m_proxy;
friend class layout_iterator<iterator_types>;
friend class detail::array_access;
#if defined(__cpp_lib_format)
friend struct std::formatter<D>;
#endif
};
template <class D>
constexpr bool operator==(
const array_crtp_base<D>& lhs,
const array_crtp_base<D>& rhs);
template <class D>
{
return get_arrow_proxy().name();
}
template <class D>
{
return get_arrow_proxy().metadata();
}
template <class D>
{
return size() == size_type(0);
}
template <class D>
{
return static_cast<size_type>(get_arrow_proxy().length());
}
template <class D>
{
if (i >= size())
{
const std::string error_message = "Index " + std::to_string(i)
+ " is greater or equal to size of array ("
+ std::to_string(size()) + ")";
throw std::out_of_range(error_message);
}
return (*this)[i];
}
template <class D>
{
auto& derived_cast = this->derived_cast();
return const_reference(inner_const_reference(derived_cast.value(i)), derived_cast.has_value(i));
}
template <class D>
{
return (*this)[size_type(0)];
}
template <class D>
{
return (*this)[size() - 1];
}
template <class D>
{
return cbegin();
}
template <class D>
{
return cend();
}
template <class D>
{
return const_iterator(this->derived_cast().value_cbegin(), bitmap_begin());
}
template <class D>
{
return const_iterator(this->derived_cast().value_cend(), bitmap_end());
}
template <class D>
{
return crbegin();
}
template <class D>
{
return crend();
}
template <class D>
{
return const_reverse_iterator(cend());
}
template <class D>
{
return const_reverse_iterator(cbegin());
}
template <class D>
{
return const_bitmap_range(bitmap_begin(), bitmap_end());
}
template <class D>
{
return const_value_range(this->derived_cast().value_cbegin(), this->derived_cast().value_cend());
}
template <class D>
: m_proxy(std::move(proxy))
{
}
template <class D>
{
return m_proxy;
}
template <class D>
{
return m_proxy;
}
template <class D>
{
}
template <class D>
{
return sparrow::next(this->derived_cast().get_bitmap().cbegin(), get_arrow_proxy().offset());
}
template <class D>
{
}
template <class D>
{
return bitmap_begin();
}
template <class D>
{
return bitmap_end();
}
template <class D>
{
return D{get_arrow_proxy().slice(start, end)};
}
template <class D>
{
return D{get_arrow_proxy().slice_view(start, end)};
}
template <class D>
constexpr bool operator==(
const array_crtp_base<D>& lhs,
const array_crtp_base<D>& rhs)
{
return std::ranges::equal(lhs, rhs);
}
}
#if defined(__cpp_lib_format)
template <typename D>
requires std::derived_from<D, sparrow::array_crtp_base<D>>
struct std::formatter<D>
{
constexpr auto parse(std::format_parse_context& ctx)
{
return ctx.begin();
}
auto format(const D& ar, std::format_context& ctx) const
{
const auto& proxy = ar.get_arrow_proxy();
std::string type;
if (proxy.dictionary())
{
std::format_to(ctx.out(), "Dictionary<{}>", proxy.dictionary()->data_type());
}
else
{
std::format_to(ctx.out(), "{}", proxy.data_type());
}
std::format_to(ctx.out(), " [name={} | size={}] <", ar.name().value_or("nullptr"), proxy.length());
std::for_each(
ar.cbegin(),
std::prev(ar.cend()),
[&ctx](const auto& value)
{
std::format_to(ctx.out(), "{}, ", value);
}
);
return std::format_to(ctx.out(), "{}>", ar.back());
}
};
template <typename D>
requires std::derived_from<D, sparrow::array_crtp_base<D>>
std::ostream&
operator<<(std::ostream& os,
const D& value)
{
os << std::format("{}", value);
return os;
}
#endif
constexpr const_bitmap_iterator bitmap_cbegin() const
Gets const bitmap iterator to the beginning.
constexpr const_value_range values() const
Gets the raw values as a range.
array_crtp_base(arrow_proxy)
Protected constructor from Arrow proxy.
constexpr const_reverse_iterator rbegin() const
Gets reverse iterator to the beginning of reversed array.
constexpr D slice_view(size_type start, size_type end) const
Creates a sliced view of the array.
constexpr const_reference back() const
Gets reference to the last element.
typename inner_types::const_value_iterator const_value_iterator
bitmap_type::const_reference bitmap_const_reference
std::ranges::subrange< const_value_iterator > const_value_range
constexpr const_reference front() const
Gets reference to the first element.
constexpr const_bitmap_iterator bitmap_end() const
Gets bitmap iterator to the end.
constexpr const_bitmap_iterator bitmap_cend() const
Gets const bitmap iterator to the end.
constexpr bool empty() const
Checks if the array is empty.
nullable< inner_const_reference, bitmap_const_reference > const_reference
constexpr const_iterator cbegin() const
Gets const iterator to the beginning of the array.
constexpr const_reference at(size_type i) const
Gets element at specified position with bounds checking.
typename inner_types::iterator_tag iterator_tag
constexpr bitmap_const_reference has_value(size_type i) const
Checks if element at index i has a valid value.
friend class layout_iterator< iterator_types >
std::ranges::subrange< const_bitmap_iterator > const_bitmap_range
bitmap_type::const_iterator const_bitmap_iterator
constexpr const_reverse_iterator crbegin() const
Gets const reverse iterator to the beginning of reversed array.
typename inner_types::inner_const_reference inner_const_reference
constexpr const_reverse_iterator crend() const
Gets const reverse iterator to the end of reversed array.
nullable< inner_value_type > value_type
constexpr const_reference operator[](size_type i) const
Gets element at specified position without bounds checking.
layout_iterator< iterator_types > const_iterator
constexpr arrow_proxy & get_arrow_proxy() noexcept
Gets mutable reference to the Arrow proxy.
array_crtp_base< D > self_type
std::reverse_iterator< const_iterator > const_reverse_iterator
constexpr const_iterator cend() const
Gets const iterator to the end of the array.
constexpr array_crtp_base & operator=(const array_crtp_base &)=default
constexpr const_bitmap_iterator bitmap_begin() const
Gets bitmap iterator to the beginning.
array_inner_types< derived_type > inner_types
constexpr const_reverse_iterator rend() const
Gets reverse iterator to the end of reversed array.
constexpr std::optional< std::string_view > name() const
Gets the optional name of the array.
constexpr const_iterator end() const
Gets iterator to the end of the array.
constexpr D slice(size_type start, size_type end) const
Creates a sliced copy of the array.
constexpr const_iterator begin() const
Gets iterator to the beginning of the array.
constexpr const_bitmap_range bitmap() const
Gets the validity bitmap as a range.
std::optional< key_value_view > metadata() const
Gets the metadata associated with the array.
typename inner_types::inner_value_type inner_value_type
constexpr size_type size() const
Gets the number of elements in the array.
#define SPARROW_ASSERT_TRUE(expr__)
SPARROW_API bool operator==(const array &lhs, const array &rhs)
Compares the content of two arrays.
constexpr InputIt next(InputIt it, Distance n)
std::ostream & operator<<(std::ostream &os, const sparrow::nullval_t &)
self_type::const_reference reference
self_type::iterator_tag iterator_tag
self_type::value_type value_type