HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
vspan.hpp
1// Copyright Take Vos 2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "required.hpp"
8#include "assert.hpp"
9#include <span>
10#include <iterator>
11#include <memory>
12#include <new>
13
14namespace tt {
15
16template<typename T>
18public:
19 using value_type = T;
21
22private:
23 value_type *ptr;
24
25public:
26 vspan_iterator() noexcept : ptr(nullptr) {}
27 vspan_iterator(vspan_iterator const &other) noexcept = default;
28 vspan_iterator(vspan_iterator &&other) noexcept = default;
29 vspan_iterator &operator=(vspan_iterator const &other) noexcept = default;
30 vspan_iterator &operator=(vspan_iterator &&other) noexcept = default;
31 ~vspan_iterator() = default;
32
33 vspan_iterator(value_type *ptr) noexcept : ptr(ptr) {
34 tt_axiom(ptr != nullptr);
35 }
36
37 vspan_iterator &operator=(value_type *ptr) noexcept {
38 tt_axiom(ptr != nullptr);
39 this->ptr = ptr;
40 return *this;
41 }
42
43 [[nodiscard]] value_type &operator*() noexcept { return *std::launder(ptr); }
44 [[nodiscard]] value_type const &operator*() const noexcept { return *std::launder(ptr); }
45 [[nodiscard]] value_type *operator->() noexcept { return std::launder(ptr); }
46 [[nodiscard]] value_type const *operator->() const noexcept { return std::launder(ptr); }
47 [[nodiscard]] value_type &operator[](size_t i) noexcept { return *std::launder(ptr + i); }
48 [[nodiscard]] value_type const &operator[](size_t i) const noexcept { return *std::launder(ptr + i); }
49
50 vspan_iterator &operator++() noexcept { ++ptr; return *this; }
51 vspan_iterator operator++(int) noexcept { auto tmp = *this; ++ptr; return tmp; }
52 vspan_iterator &operator--() noexcept { --ptr; return *this; }
53 vspan_iterator operator--(int) noexcept { auto tmp = *this; --ptr; return tmp; }
54
55 vspan_iterator &operator+=(ssize_t rhs) noexcept { ptr += rhs; return *this; }
56 vspan_iterator &operator-=(ssize_t rhs) noexcept { ptr -= rhs; return *this; }
57
58 [[nodiscard]] friend bool operator==(vspan_iterator const &lhs, vspan_iterator const &rhs) noexcept { return lhs.ptr == rhs.ptr; }
59 [[nodiscard]] friend bool operator!=(vspan_iterator const &lhs, vspan_iterator const &rhs) noexcept { return lhs.ptr != rhs.ptr; }
60 [[nodiscard]] friend bool operator<(vspan_iterator const &lhs, vspan_iterator const &rhs) noexcept { return lhs.ptr < rhs.ptr; }
61 [[nodiscard]] friend bool operator>(vspan_iterator const &lhs, vspan_iterator const &rhs) noexcept { return lhs.ptr > rhs.ptr; }
62 [[nodiscard]] friend bool operator<=(vspan_iterator const &lhs, vspan_iterator const &rhs) noexcept { return lhs.ptr <= rhs.ptr; }
63 [[nodiscard]] friend bool operator>=(vspan_iterator const &lhs, vspan_iterator const &rhs) noexcept { return lhs.ptr >= rhs.ptr; }
64
65 [[nodiscard]] friend vspan_iterator operator+(vspan_iterator const &lhs, ssize_t rhs) noexcept { return vspan_iterator{lhs.ptr + rhs}; }
66 [[nodiscard]] friend vspan_iterator operator-(vspan_iterator const &lhs, ssize_t rhs) noexcept { return vspan_iterator{lhs.ptr - rhs}; }
67 [[nodiscard]] friend vspan_iterator operator+(ssize_t lhs, vspan_iterator const &rhs) noexcept { return vspan_iterator{lhs + rhs.ptr}; }
68
69 [[nodiscard]] friend difference_type operator-(vspan_iterator const &lhs, vspan_iterator const &rhs) noexcept { return lhs.ptr - rhs.ptr; }
70};
71
72template<typename T>
73class vspan {
74public:
75 using value_type = T;
78
79private:
80 value_type *_begin;
81 value_type *_end;
82 value_type *_max;
83
84public:
85 vspan() noexcept :
86 _begin(nullptr), _end(nullptr), _max(nullptr) {}
87
88 vspan(value_type *buffer, ssize_t nr_elements) noexcept :
89 _begin(buffer), _end(buffer), _max(buffer + nr_elements)
90 {
91 tt_axiom(nr_elements >= 0);
92 }
93
94 vspan(std::span<value_type> span) noexcept :
95 _begin(span.data()), _end(span.data()), _max(span.data() + span.size()) {}
96
97 vspan(vspan const &other) = default;
98 vspan(vspan &&other) = default;
99 vspan &operator=(vspan const &other) = default;
100 vspan &operator=(vspan &&other) = default;
101 ~vspan() = default;
102
103 [[nodiscard]] iterator begin() noexcept { return _begin; }
104 [[nodiscard]] const_iterator begin() const noexcept { return _begin; }
105 [[nodiscard]] const_iterator cbegin() const noexcept { return _begin; }
106
107 [[nodiscard]] iterator end() noexcept { return _end; }
108 [[nodiscard]] const_iterator end() const noexcept { return _end; }
109 [[nodiscard]] const_iterator cend() const noexcept { return _end; }
110
111 [[nodiscard]] size_t size() const noexcept { return std::distance(_begin, _end); }
112
113 [[nodiscard]] value_type &operator[](size_t i) noexcept { tt_axiom(i < size()); return *std::launder(_begin + i); }
114 [[nodiscard]] value_type const &operator[](size_t i) const noexcept { tt_axiom(i < size()); return *std::launder(_begin + i); }
115
116 value_type &front() noexcept { tt_axiom(_end != _begin); return *std::launder(_begin); }
117 value_type const &front() const noexcept { tt_axiom(_end != _begin); return *std::launder(_begin); }
118 value_type &back() noexcept { tt_axiom(_end != _begin); return *std::launder(_end - 1); }
119 value_type const &back() const noexcept { tt_axiom(_end != _begin); return *std::launder(_end - 1); }
120
121 vspan &clear() noexcept {
122 for (auto i = _begin; i != _end; ++i) {
123 std::destroy_at(std::launder(i));
124 }
125 _end = _begin;
126 return *this;
127 }
128
129 void push_back(value_type const &rhs) noexcept {
130 tt_axiom(_end != _max);
131 // Since we throw away the pointer, we have to std::launder all access to this object.
132 [[maybe_unused]] value_type *ptr = new (_end) value_type(rhs);
133 ++_end;
134 }
135
136 void push_back(value_type &&rhs) noexcept {
137 tt_axiom(_end != _max);
138 // Since we throw away the pointer, we have to std::launder all access to this object.
139 [[maybe_unused]] value_type *ptr = new (_end) value_type(std::move(rhs));
140 ++_end;
141 }
142
143 template<typename... Args>
144 void emplace_back(Args &&... args) noexcept {
145 tt_axiom(_end != _max);
146 // Since we throw away the pointer, we have to std::launder all access to this object.
147 [[maybe_unused]] value_type *ptr = new (_end) value_type(std::forward<Args>(args)...);
148 ++_end;
149 }
150
151 void pop_back() noexcept {
152 tt_axiom(_end != _begin);
153 --_end;
154 std::destroy_at(std::launder(_end));
155 }
156};
157
158}
Definition vspan.hpp:17
Definition vspan.hpp:73
T distance(T... args)
T move(T... args)