HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
placement.hpp
1// Copyright Take Vos 2019, 2021-2022.
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 "../utility/utility.hpp"
8#include "../macros.hpp"
9#include <span>
10
11
12
13hi_warning_push();
14// C26492: Don't use const_cast to cast away const or volatile (type.3).
15// placement new requires non-const pointer, even if the non-constructor initializer doesn't
16// modify the memory.
17hi_warning_ignore_msvc(26492);
18// We are going to remove placement.hpp anyway.
19hi_warning_ignore_msvc(26403);
20hi_warning_ignore_msvc(26460);
21
22namespace hi::inline v1 {
23template<typename T>
24inline bool check_alignment(void const *ptr) noexcept
25{
26 return std::bit_cast<uintptr_t>(ptr) % alignof(T) == 0;
27}
28
29template<typename T>
31public:
32 static_assert(std::is_trivially_default_constructible_v<T>);
33 static_assert(std::is_trivially_destructible_v<T>);
34
35 using value_type = T;
36
37 template<byte_like Byte>
38 placement_ptr(std::span<Byte> bytes, std::size_t& offset)
39 {
40 if (offset + sizeof(value_type) > bytes.size()) {
41 throw std::bad_alloc();
42 }
43
44 auto ptr = bytes.data() + offset;
45 offset += sizeof(value_type);
46 std::uninitialized_default_construct_n(reinterpret_cast<value_type *>(ptr), 1);
47 _ptr = std::launder(reinterpret_cast<value_type *>(ptr));
48 }
49
51 {
52 std::destroy_at(_ptr);
53 }
54
55 placement_ptr() = delete;
56 placement_ptr(placement_ptr const&) = delete;
57 placement_ptr(placement_ptr&&) = delete;
58 placement_ptr& operator=(placement_ptr const&) = delete;
59 placement_ptr& operator=(placement_ptr&&) = delete;
60
61 value_type *operator->() const noexcept
62 {
63 return _ptr;
64 }
65
66 value_type& operator*() const noexcept
67 {
68 return *_ptr;
69 }
70
71private:
72 value_type *_ptr;
73};
74
75template<typename T, typename Byte>
76[[nodiscard]] auto make_placement_ptr(std::span<Byte> bytes, std::size_t& offset)
77{
79}
80
81template<typename T, typename Byte>
82[[nodiscard]] auto make_placement_ptr(std::span<Byte> bytes, std::size_t&& offset = 0)
83{
84 std::size_t _offset = offset;
85 return make_placement_ptr<T>(bytes, _offset);
86}
87
88template<typename T>
90public:
91 static_assert(std::is_trivially_default_constructible_v<T>);
92 static_assert(std::is_trivially_destructible_v<T>);
93
94 using value_type = T;
95 using container_type = std::span<value_type>;
96 using iterator = container_type::iterator;
97 using reference = container_type::reference;
98 using pointer = container_type::pointer;
99
100 template<byte_like Byte>
101 placement_array(std::span<Byte> bytes, std::size_t& offset, std::size_t n)
102 {
103 if (offset + n * sizeof(T) > bytes.size()) {
104 throw std::bad_alloc();
105 }
106
107 hilet ptr = bytes.data() + offset;
108 offset += sizeof(T) * n;
109
110 std::uninitialized_default_construct_n(reinterpret_cast<value_type *>(ptr), n);
111 _items = {std::launder(reinterpret_cast<value_type *>(ptr)), n};
112 }
113
114 placement_array(placement_array const&) = delete;
116 placement_array& operator=(placement_array const&) = delete;
117 placement_array& operator=(placement_array&&) = delete;
118
120 {
121 std::destroy(begin(), end());
122 }
123
124 operator std::span<value_type>() const noexcept
125 {
126 return _items;
127 }
128
129 std::size_t size() const noexcept
130 {
131 return std::distance(begin(), end());
132 }
133
134 iterator begin() const noexcept
135 {
136 return _items.begin();
137 }
138
139 iterator end() const noexcept
140 {
141 return _items.end();
142 }
143
144 reference operator[](ssize_t offset) const noexcept
145 {
146 return _items[offset];
147 }
148
149private:
150 std::span<value_type> _items;
151};
152
153template<typename T, byte_like Byte>
154[[nodiscard]] auto make_placement_array(std::span<Byte> bytes, std::size_t& offset, std::size_t n)
155{
156 return placement_array<copy_cv_t<T, Byte>>(bytes, offset, n);
157}
158
159template<typename T, byte_like Byte>
160[[nodiscard]] auto make_placement_array(std::span<Byte> bytes, std::size_t&& offset, std::size_t n)
161{
162 std::size_t _offset = offset;
163 return make_placement_array<T>(bytes, _offset, n);
164}
165
166template<typename T, byte_like Byte>
167[[nodiscard]] auto make_placement_array(std::span<Byte> bytes, std::size_t& offset)
168{
169 hilet n = bytes.size() / ssizeof(T);
170 return make_placement_array<T>(bytes, offset, n);
171}
172
173template<typename T, byte_like Byte>
174[[nodiscard]] auto make_placement_array(std::span<Byte> bytes, std::size_t&& offset = 0)
175{
176 std::size_t _offset = offset;
177 return make_placement_array<T>(bytes, _offset);
178}
179
180} // namespace hi::inline v1
DOXYGEN BUG.
Definition algorithm.hpp:16
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Definition placement.hpp:30
Definition placement.hpp:89
T distance(T... args)