33 template <
typename FromBufferRef,
typename T>
34 concept BufferReference = std::ranges::contiguous_range<FromBufferRef> && std::is_reference_v<FromBufferRef>
35 && (
sizeof(std::ranges::range_value_t<FromBufferRef>) <=
sizeof(T));
43 template <
typename FromBufferRef,
typename T>
55 template <
typename To, BufferReference<To> FromBufferRef>
66 static constexpr bool is_const = std::is_const_v<To>;
69 using buffer_reference = std::conditional_t<is_const, const FromBufferRef, FromBufferRef>;
71 using size_type = std::remove_cvref_t<buffer_reference>::size_type;
274 [[nodiscard]] constexpr
bool empty() const noexcept;
328 template <class InputIt>
329 requires
std::input_iterator<InputIt>
351 template <class... Args>
412 static constexpr
size_type m_to_from_size_ratio = static_cast<
size_type>(1. / m_from_to_size_ratio);
421 index_for_buffer(
size_type idx) const noexcept
423 return idx * m_to_from_size_ratio;
432 [[nodiscard]] std::remove_cvref_t<buffer_reference>::const_iterator
435 const difference_type index = std::distance(
cbegin(), pos);
436 const auto idx_for_buffer = index_for_buffer(
static_cast<size_type
>(index));
438 return std::next(m_buffer.cbegin(),
static_cast<difference_type
>(idx_for_buffer));
442 size_type m_max_size;
450 template <
class... Args>
452 :
value(
std::forward<Args>(args)...)
459 template <
typename To, BufferReference<To> FromBufferRef>
464 , m_max_size(m_buffer.
max_size() / m_to_from_size_ratio)
468 template <
typename To, BufferReference<To> FromBufferRef>
472 , m_max_size(m_buffer.max_size() / m_to_from_size_ratio)
476 template <
typename To, BufferReference<To> FromBufferRef>
477 requires T_is_const_if_FromBufferRef_is_const<FromBufferRef, To>
485 template <
typename To, BufferReference<To> FromBufferRef>
493 template <
typename To, BufferReference<To> FromBufferRef>
503 template <
typename To, BufferReference<To> FromBufferRef>
512 template <
typename To, BufferReference<To> FromBufferRef>
521 template <
typename To, BufferReference<To> FromBufferRef>
530 template <
typename To, BufferReference<To> FromBufferRef>
539 template <
typename To, BufferReference<To> FromBufferRef>
548 template <
typename To, BufferReference<To> FromBufferRef>
557 template <
typename To, BufferReference<To> FromBufferRef>
566 template <
typename To, BufferReference<To> FromBufferRef>
574 template <
typename To, BufferReference<To> FromBufferRef>
582 template <
typename To, BufferReference<To> FromBufferRef>
590 template <
typename To, BufferReference<To> FromBufferRef>
598 template <
typename To, BufferReference<To> FromBufferRef>
607 template <
typename To, BufferReference<To> FromBufferRef>
616 template <
typename To, BufferReference<To> FromBufferRef>
624 template <
typename To, BufferReference<To> FromBufferRef>
632 template <
typename To, BufferReference<To> FromBufferRef>
640 template <
typename To, BufferReference<To> FromBufferRef>
650 template <
typename To, BufferReference<To> FromBufferRef>
655 const double new_size =
static_cast<double>(m_buffer.size()) * m_from_to_size_ratio;
657 std::trunc(new_size) == new_size,
658 "The size of the buffer is not a multiple of the size of the new type"
663 template <
typename To, BufferReference<To> FromBufferRef>
671 template <
typename To, BufferReference<To> FromBufferRef>
676 return m_buffer.capacity() / m_to_from_size_ratio;
679 template <
typename To, BufferReference<To> FromBufferRef>
683 return m_buffer.empty();
686 template <
typename To, BufferReference<To> FromBufferRef>
691 m_buffer.reserve(new_cap * m_to_from_size_ratio);
694 template <
typename To, BufferReference<To> FromBufferRef>
699 m_buffer.shrink_to_fit();
704 template <
typename To, BufferReference<To> FromBufferRef>
712 template <
typename To, BufferReference<To> FromBufferRef>
721 const auto buffer_pos = get_buffer_reference_iterator(pos);
722 m_buffer.insert(buffer_pos, m_to_from_size_ratio, 0);
724 return std::next(
begin(), index);
727 template <
typename To, BufferReference<To> FromBufferRef>
736 const auto buffer_pos = get_buffer_reference_iterator(pos);
737 m_buffer.insert(buffer_pos, count * m_to_from_size_ratio, 0);
740 data()[
static_cast<size_t>(index) + i] = value;
742 return std::next(
begin(), index);
745 template <
typename To, BufferReference<To> FromBufferRef>
747 template <
class InputIt>
748 requires std::input_iterator<InputIt>
757 const auto buffer_pos = get_buffer_reference_iterator(pos);
758 m_buffer.insert(buffer_pos,
static_cast<size_type>(count) * m_to_from_size_ratio, 0);
759 std::copy(first, last,
data() + index);
760 return std::next(
begin(), index);
763 template <
typename To, BufferReference<To> FromBufferRef>
769 return insert(pos, ilist.begin(), ilist.end());
772 template <
typename To, BufferReference<To> FromBufferRef>
774 template <
class... Args>
782 const auto buffer_pos = get_buffer_reference_iterator(pos);
783 m_buffer.insert(buffer_pos, m_to_from_size_ratio, 0);
785 return std::next(
begin(), index);
788 template <
typename To, BufferReference<To> FromBufferRef>
801 const auto idx_for_buffer = index_for_buffer(
static_cast<size_type>(index));
805 std::next(m_buffer.cbegin(),
static_cast<difference_type>(idx_for_buffer)),
806 std::next(m_buffer.cbegin(),
static_cast<difference_type>(idx_for_buffer + m_to_from_size_ratio))
808 return std::next(
begin(), index);
811 template <
typename To, BufferReference<To> FromBufferRef>
825 const auto idx_for_buffer_first = index_for_buffer(
static_cast<size_type>(index_first));
827 const auto idx_for_buffer_last = index_for_buffer(
static_cast<size_type>(index_last));
830 std::next(m_buffer.cbegin(),
static_cast<difference_type>(idx_for_buffer_first)),
831 std::next(m_buffer.cbegin(),
static_cast<difference_type>(idx_for_buffer_last))
833 return std::next(
begin(), index_first);
836 template <
typename To, BufferReference<To> FromBufferRef>
844 template <
typename To, BufferReference<To> FromBufferRef>
852 template <
typename To, BufferReference<To> FromBufferRef>
857 const auto new_size_for_buffer =
static_cast<size_type>(
858 static_cast<double>(new_size) / m_from_to_size_ratio
860 m_buffer.resize(new_size_for_buffer);
863 template <
typename To, BufferReference<To> FromBufferRef>
869 const auto new_size_for_buffer =
static_cast<size_type>(
870 static_cast<double>(new_size) / m_from_to_size_ratio
872 m_buffer.resize(new_size_for_buffer, 0);
873 for (
size_type i = original_size; i < new_size; ++i)
879 template <
typename To,
class FromBufferRef>
882 constexpr bool is_const = std::is_const_v<FromBufferRef>;
883 using RealToType = std::conditional_t<is_const, const To, To>;
Class which has internally a reference to a contiguous container of a certain type and provides an AP...
constexpr size_type capacity() const noexcept
constexpr void clear() noexcept
constexpr iterator begin() noexcept
constexpr reference front()
constexpr size_type size() const noexcept(!SPARROW_CONTRACTS_THROW_ON_FAILURE)
std::remove_cvref_t< buffer_reference >::size_type size_type
const value_type & const_reference
constexpr const_iterator cbegin() const noexcept
constexpr const_iterator cend() const noexcept
constexpr reference back()
pointer_iterator< pointer > iterator
constexpr pointer data() noexcept
Returns a pointer to the underlying data.
static constexpr bool is_const
constexpr reverse_iterator rbegin() noexcept
constexpr buffer_adaptor(FromBufferRef buf)
Constructs a buffer adaptor with a non-const buffer reference.
constexpr buffer_adaptor(const FromBufferRef buf)
Constructs a buffer adaptor with a const buffer reference.
pointer_iterator< const_pointer > const_iterator
constexpr void shrink_to_fit()
constexpr void push_back(const value_type &value)
constexpr bool empty() const noexcept
constexpr void pop_back()
constexpr const_reverse_iterator crend() const noexcept
constexpr iterator emplace(const_iterator pos, Args &&... args)
constexpr iterator erase(const_iterator pos)
std::remove_cvref_t< FromBufferRef >::value_type buffer_reference_value_type
constexpr reverse_iterator rend() noexcept
std::reverse_iterator< iterator > reverse_iterator
constexpr size_type max_size() const noexcept
std::conditional_t< is_const, const FromBufferRef, FromBufferRef > buffer_reference
std::remove_cvref_t< buffer_reference >::difference_type difference_type
constexpr iterator end() noexcept
constexpr const_reverse_iterator crbegin() const noexcept
constexpr void reserve(size_type new_cap)
constexpr void resize(size_type new_size)
constexpr iterator insert(const_iterator pos, const value_type &value)
constexpr reference operator[](size_type idx)
Returns a reference to the element at the specified index.
std::reverse_iterator< const_iterator > const_reverse_iterator
const value_type * const_pointer
Concept that checks if a type is a buffer reference suitable for adaptation.
Concept that ensures T is const if FromBufferRef is const.
Concept for matching qualifier requirements.
#define SPARROW_ASSERT_TRUE(expr__)
#define SPARROW_ASSERT(expr__, message__)
#define SPARROW_CONTRACTS_THROW_ON_FAILURE
auto make_buffer_adaptor(FromBufferRef &buf)