Iros
 
Loading...
Searching...
No Matches
ring.h
Go to the documentation of this file.
1#pragma once
2
13#include "di/platform/prelude.h"
14#include "di/types/prelude.h"
16#include "di/util/exchange.h"
19
20namespace di::container {
21template<typename T, concepts::Allocator Alloc = platform::DefaultAllocator>
22class Ring : public MutableRingInterface<Ring<T, Alloc>, T> {
23public:
24 using Value = T;
25 using ConstValue = T const;
26
27 constexpr Ring() = default;
28 constexpr Ring(Ring const&) = delete;
29 constexpr Ring(Ring&& other)
30 : m_data(util::exchange(other.m_data, nullptr))
31 , m_size(util::exchange(other.m_size, 0))
32 , m_capacity(util::exchange(other.m_capacity, 0))
33 , m_head(util::exchange(other.m_head, 0))
34 , m_tail(util::exchange(other.m_tail, 0))
35 , m_allocator(util::move(other.m_allocator)) {}
36
37 constexpr ~Ring() { deallocate(); }
38
39 constexpr auto operator=(Ring const&) -> Ring& = delete;
40 constexpr auto operator=(Ring&& other) -> Ring& {
41 deallocate();
42 this->m_data = util::exchange(other.m_data, nullptr);
43 this->m_size = util::exchange(other.m_size, 0);
44 this->m_capacity = util::exchange(other.m_capacity, 0);
45 this->m_head = util::exchange(other.m_head, 0);
46 this->m_tail = util::exchange(other.m_tail, 0);
47 this->m_allocator = util::move(other.m_allocator);
48 return *this;
49 }
50
51 constexpr auto span() -> Span<Value> { return { m_data, m_size }; }
52 constexpr auto span() const -> Span<ConstValue> { return { m_data, m_size }; }
53
54 constexpr auto capacity() const -> usize { return m_capacity; }
55 constexpr auto max_size() const -> usize { return static_cast<usize>(-1); }
56
57 constexpr auto reserve_from_nothing(usize n) {
58 DI_ASSERT(capacity() == 0U);
59
60 return as_fallible(di::allocate_many<T>(m_allocator, n)) % [&](AllocationResult<T> result) {
61 auto [data, new_capacity] = result;
62 m_data = data;
63 m_capacity = new_capacity;
65 }
66 constexpr void assume_size(usize size) { m_size = size; }
67 constexpr auto grow_capacity(usize min_capacity) const -> usize {
68 constexpr auto smallest_allowed_capacity = 32zu;
69 if (m_capacity >= min_capacity) {
70 return min_capacity;
71 }
72 return di::max({ min_capacity, 2 * m_capacity, smallest_allowed_capacity });
73 }
74
75 constexpr auto head() const -> usize { return m_head; }
76 constexpr auto tail() const -> usize { return m_tail; }
77
78 constexpr void assume_head(usize head) { m_head = head; }
79 constexpr void assume_tail(usize tail) { m_tail = tail; }
80
81private:
82 constexpr void deallocate() {
83 this->clear();
84 if (m_data) {
85 di::deallocate_many<T>(m_allocator, m_data, m_capacity);
86 }
87 }
88
89 T* m_data { nullptr };
90 usize m_size { 0 };
91 usize m_capacity { 0 };
92 usize m_head { 0 };
93 usize m_tail { 0 };
94 [[no_unique_address]] Alloc m_allocator {};
95};
96
97template<concepts::InputContainer Con, typename T = meta::ContainerValue<Con>>
99}
100
101namespace di {
102using container::Ring;
103}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition mutable_ring_interface.h:8
constexpr void clear()
Definition mutable_ring_interface.h:36
Definition ring.h:22
constexpr auto reserve_from_nothing(usize n)
Definition ring.h:57
constexpr Ring()=default
constexpr void assume_size(usize size)
Definition ring.h:66
T Value
Definition ring.h:24
constexpr auto span() -> Span< Value >
Definition ring.h:51
constexpr auto head() const -> usize
Definition ring.h:75
constexpr Ring(Ring const &)=delete
constexpr void assume_head(usize head)
Definition ring.h:78
constexpr Ring(Ring &&other)
Definition ring.h:29
constexpr auto span() const -> Span< ConstValue >
Definition ring.h:52
constexpr auto grow_capacity(usize min_capacity) const -> usize
Definition ring.h:67
constexpr auto tail() const -> usize
Definition ring.h:76
constexpr auto operator=(Ring const &) -> Ring &=delete
constexpr ~Ring()
Definition ring.h:37
constexpr auto max_size() const -> usize
Definition ring.h:55
constexpr auto capacity() const -> usize
Definition ring.h:54
constexpr void assume_tail(usize tail)
Definition ring.h:79
T const ConstValue
Definition ring.h:25
constexpr auto operator=(Ring &&other) -> Ring &
Definition ring.h:40
Definition span_forward_declaration.h:10
Definition sequence.h:12
constexpr auto deallocate
Definition deallocate.h:23
constexpr auto move
Definition move.h:38
constexpr auto size
Definition size.h:54
constexpr auto data
Definition data.h:51
size_t usize
Definition integers.h:33
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition vocab.h:96
constexpr auto exchange(T &object, U &&new_value) -> T
Definition exchange.h:8
Definition zstring_parser.h:9
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
constexpr auto exchange(T &object, U &&new_value) -> T
Definition exchange.h:8
constexpr auto as_fallible
Definition as_fallible.h:26
constexpr auto try_infallible
Definition try_infallible.h:31
constexpr auto deallocate_many
Definition deallocate_many.h:28
constexpr auto allocate_many
Definition allocate_many.h:48
constexpr auto max
Definition max.h:47
Definition allocation_result.h:7
Definition in_place_template.h:5