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