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