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