HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
secure_vector.hpp
1// Copyright Take Vos 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 "../security/module.hpp"
8#include "../macros.hpp"
9
10// namespace hi::inline v1 {
11//
12// template<typename Allocator>
13// class secure_vector_base {
14// public:
15// using pointer = std::allocator_traits<Allocator>::pointer;
16//
17// protected:
18// [[nodiscard]] constexpr pointer allocate(size_t n)
19// {
20// return std::allocator_traits<Allocator>::allocate(Allocator{}, n);
21// }
22//
23// constexpr void deallocate(pointer p, size_t n)
24// {
25// return std::allocator_traits<Allocator>::deallocate(Allocator{}, p, n);
26// }
27// };
28//
29// template<typename Allocator> requires(not std::allocator_traits<Allocator>::is_always_equal::value)
30// class secure_vector_base<Allocator> {
31// public:
32// using pointer = std::allocator_traits<Allocator>::pointer;
33//
34// protected:
35// Allocator _allocator;
36//
37// [[nodiscard]] constexpr pointer allocate(size_t n)
38// {
39// return std::allocator_traits<Allocator>::allocate(_allocator, n);
40// }
41//
42// constexpr void deallocate(pointer p, size_t n)
43// {
44// return std::allocator_traits<Allocator>::deallocate(_allocator, p, n);
45// }
46// };
47//
48// /** Secure vector.
49// *
50// * The data being held by the vector will be securly cleared from memory
51// * when the vector is destructed. Useful for temporarilly storing passwords and other secrets.
52// */
53// template<typename T, typename Allocator = std::allocator<T>>
54// class secure_vector : public secure_vector_base<Allocator> {
55// public:
56// using value_type = T;
57// using allocator_type = Allocator;
58// using size_type = std::size_t;
59// using difference_type = std::ptrdiff_t;
60// using reference = value_type &;
61// using const_reference = value_type const &;
62// using pointer = std::allocator_traits<allocator_type>::pointer;
63// using const_pointer = std::allocator_traits<allocator_type>::const_pointer;
64// using iterator = value_type *;
65// using const_iterator = value_type const *;
66// using reverse_iterator = std::reverse_iterator<iterator>;
67// using const_reverse_iterator = std::reverse_iterator<const_iterator>;
68//
69// constexpr static bool is_static_allocator = // std::allocator_traits<allocator_type>::is_always_equal::value;
70//
71// constexpr secure_vector() noexcept : _begin(nullptr), _end(nullptr), _bound(nullptr) {}
72//
73// constexpr ~secure_vector()
74// {
75// resize(0);
76// shrink_to_fit();
77// hi_assert(_begin == nullptr);
78// hi_assert(_end == nullptr);
79// hi_assert(_bound == nullptr);
80// }
81//
82// [[nodiscard]] constexpr bool empty() const noexcept
83// {
84// return _begin == _end;
85// }
86//
87// [[nodiscard]] constexpr size_type size() const noexcept
88// {
89// return static_cast<size_type>(_end - _begin);
90// }
91//
92// [[nodiscard]] constexpr size_type max_size() const noexcept
93// {
94// return std::allocator_traits<allocator_type>::max_size();
95// }
96//
97// [[nodiscard]] constexpr size_type capacity() const noexcept
98// {
99// return static_cast<size_type>(_bound - _begin);
100// }
101//
102// [[nodiscard]] constexpr reference at(size_type pos)
103// {
104// auto *ptr = _begin + pos;
105// if (ptr >= _end) {
106// throw std::out_of_range();
107// }
108//
109// return *ptr;
110// }
111//
112// [[nodiscard]] constexpr const_reference at(size_type pos) const
113// {
114// auto *ptr = _begin + pos;
115// if (ptr >= _end) {
116// throw std::out_of_range();
117// }
118//
119// return *ptr;
120// }
121//
122// [[nodiscard]] constexpr reference operator[](size_type pos) noexcept
123// {
124// auto *ptr = _begin + pos;
125// hi_assert(ptr < _end);
126// return *ptr;
127// }
128//
129// [[nodiscard]] constexpr const_reference operator[](size_type pos) const noexcept
130// {
131// auto *ptr = _begin + pos;
132// hi_assert(ptr < _end);
133// return *ptr;
134// }
135//
136// [[nodiscard]] constexpr reference front() noexcept
137// {
138// hi_assert(not empty());
139// return *_begin;
140// }
141//
142// [[nodiscard]] constexpr const_reference front() const noexcept
143// {
144// hi_assert(not empty());
145// return *_begin;
146// }
147//
148// [[nodiscard]] constexpr reference back() noexcept
149// {
150// hi_assert(not empty());
151// return *(_end - 1);
152// }
153//
154// [[nodiscard]] constexpr const_reference back() const noexcept
155// {
156// hi_assert(not empty());
157// return *(_end - 1);
158// }
159//
160// [[nodiscard]] constexpr pointer data() noexcept
161// {
162// return _begin;
163// }
164//
165// [[nodiscard]] constexpr const_pointer data() const noexcept
166// {
167// return _begin;
168// }
169//
170// [[nodiscard]] constexpr iterator begin() noexcept
171// {
172// return _begin;
173// }
174//
175// [[nodiscard]] constexpr const_iterator begin() const noexcept
176// {
177// return _begin;
178// }
179//
180// [[nodiscard]] constexpr const_iterator cbegin() const noexcept
181// {
182// return _begin;
183// }
184//
185// [[nodiscard]] constexpr iterator end() noexcept
186// {
187// return _end;
188// }
189//
190// [[nodiscard]] constexpr const_iterator end() const noexcept
191// {
192// return _end;
193// }
194//
195// [[nodiscard]] constexpr const_iterator cend() const noexcept
196// {
197// return _end;
198// }
199//
200//
201// constexpr void resize(size_type new_size)
202// {
203// return _resize(new_size);
204// }
205//
206// constexpr void resize(size_type new_size, value_type const &value)
207// {
208// return _resize(new_size, value);
209// }
210//
211// constexpr void clear()
212// {
213// return resize(0);
214// }
215//
216// constexpr reference emplace_back(auto &&...args)
217// {
218// grow(1);
219// auto tmp = std::construct_at(_end, tt_forward(args)...);
220// ++_end;
221// return *tmp;
222// }
223//
224// constexpr void push_back(value_type const &value)
225// {
226// emplace_back(value);
227// }
228//
229// constexpr void push_back(value_type &&value)
230// {
231// emplace_back(std::move(value));
232// }
233//
234// constexpr void pop_back()
235// {
236// secure_destroy_at(back());
237// --_end;
238// }
239//
240// constexpr iterator emplace(const_iterator pos, auto &&...args)
241// {
242// hilet index = std::distance(begin(), pos);
243// hilet n_first = &emplace_back(hi_forward(args)...);
244//
245// // Rotate the newly back-emplaced item to it's intended position.
246// hilet first = _begin + index;
247// if (first != n_first) {
248// std::rotate(first, n_first, _end);
249// }
250// return first;
251// }
252//
253// constexpr iterator insert(const_iterator pos, value_type const &value)
254// {
255// return emplace(pos, value);
256// }
257//
258// constexpr iterator insert(const_iterator pos, value_type &&value)
259// {
260// return emplace(pos, std::move(value));
261// }
262//
263// constexpr void reserve(size_type new_capacity)
264// {
265// if (new_capacity <= capacity()) {
266// return;
267// }
268//
269// hilet tmp = allocate(new_capacity);
270// try {
271// secure_unitialized_move(_begin, _end, _tmp);
272// _end = tmp + size();
273// _bound = tmp + new_capacity;
274// _begin = tmp;
275// } catch (...) {
276// deallocate(tmp, new_capacity);
277// throw;
278// }
279// }
280//
281// constexpr void shrink_to_fit()
282// {
283// if (empty()) {
284// if (_begin != nullptr) {
285// deallocate(_begin, capacity());
286// _begin = _end = _bound = nullptr;
287// }
288//
289// } else {
290// hilet new_capacity = size();
291// hilet tmp = allocate(new_capacity);
292// try {
293// secure_unitialized_move(_begin, _end, _tmp);
294// _end = tmp + size();
295// _bound = tmp + new_capacity;
296// _begin = tmp;
297// } catch (...) {
298// deallocate(tmp, new_capacity);
299// throw;
300// }
301// }
302// }
303//
304// private:
305// value_type *_begin;
306// value_type *_end;
307// value_type *_bound;
308//
309// [[nodiscard]] constexpr bool full() const noexcept
310// {
311// return _end == _bound;
312// }
313//
314// /** Increase the capacity.
315// *
316// * This function will use a growth factor of 1.5 for increasing
317// * the capacity if the @a count element will not fit the current allocation.
318// *
319// * Growth when pushing back a single element each time:
320// * - 0, 1, 2, 3, 4, 6, 9, 13, ...
321// */
322// constexpr void grow(size_t count) const noexcept
323// {
324// if (_end + count <= _bound) {
325// return;
326// }
327//
328// hilet minimum_new_capacity = size() + count;
329//
330// // Growth factor 1.5, slightly lower than the ideal golden ratio.
331// auto new_capacity = capacity();
332// new_capacity += new_capacity >> 1;
333//
334// if (new_capacity < minimum_new_capacity) {
335// reserve(minimum_new_capacity);
336// } else {
337// reserve(new_capacity);
338// }
339// }
340//
341// template<typename... Args>
342// constexpr void _resize(size_t new_size, Args const &... args)
343// {
344// reserve(new_size);
345//
346// hilet new_end = _begin + new_size;
347//
348// if (new_end > _end) {
349// // Construct the new values.
350// construct(_end, new_end, args...);
351//
352// } else (new_end < _end) {
353// // Destroy the old values.
354// secure_destroy(new_end, _end);
355// }
356// _end = new_end;
357// }
358// };
359//
360// namespace pmr {
361//
362// template<class T>
363// using secure_vector = hi::secure_vector<T,std::pmr::polymorphic_allocator<T>>;
364// }
365//
366// }
367