HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
memory.hpp
1// Copyright 2019 Pokitec
2// All rights reserved.
3
4#pragma once
5
6#include "TTauri/Foundation/required.hpp"
7#include <memory>
8#include <vector>
9#include <map>
10#include <unordered_map>
11
12namespace tt {
13
14template<typename T, typename U>
15tt_force_inline void memswap(T &dst, U &src) {
16 static_assert(sizeof(T) == sizeof(U), "memswap requires both objects of equal size");
17 std::byte tmp[sizeof(T)];
18 memcpy(tmp, &src, sizeof(T));
19 memcpy(&src, &dst, sizeof(U));
20 memcpy(&dst, tmp, sizeof(T));
21}
22
23template<typename T>
24tt_force_inline bool is_aligned(T* p){
25 return (reinterpret_cast<ptrdiff_t>(p) % std::alignment_of<T>::value) == 0;
26}
27
28template<typename R, typename T>
29gsl_suppress3(type.1,26487,lifetime.4)
30 inline R align(T ptr, size_t alignment) noexcept
31{
32 ttlet byteOffset = reinterpret_cast<ptrdiff_t>(ptr);
33 ttlet alignedByteOffset = ((byteOffset + alignment - 1) / alignment) * alignment;
34
35 return reinterpret_cast<R>(alignedByteOffset);
36}
37
41template<typename R, typename T>
42gsl_suppress5(f.23,bounds.3,type.1,26487,lifetime.4)
43 inline R align_end(T ptr, size_t alignment) noexcept
44{
45 ttlet byteOffset = reinterpret_cast<ptrdiff_t>(ptr);
46 ttlet alignedByteOffset = (byteOffset / alignment) * alignment;
47
48 return reinterpret_cast<R>(alignedByteOffset);
49}
50
51// this implementation requires that To is trivially default constructible
52template<typename To, typename From>
53std::enable_if_t<(sizeof(To) == sizeof(From)) && std::is_trivially_copyable_v<From> && std::is_trivial_v<To>,To>
54bit_cast(From const &src) noexcept
55{
56 To dst;
57 std::memcpy(&dst, &src, sizeof(To));
58 return dst;
59}
60
61template<typename T>
62inline void cleanupWeakPointers(std::vector<std::weak_ptr<T>> &v) noexcept
63{
64 auto i = v.begin();
65 while (i != v.end()) {
66 if (i->expired()) {
67 i = v.erase(i);
68 } else {
69 i++;
70 }
71 }
72}
73
74template<typename K, typename T>
75inline void cleanupWeakPointers(std::unordered_map<K,std::weak_ptr<T>> &v) noexcept
76{
77 auto i = v.begin();
78 while (i != v.end()) {
79 if (i->second.expired()) {
80 i = v.erase(i);
81 } else {
82 i++;
83 }
84 }
85}
86
87template<typename K, typename T>
88inline void cleanupWeakPointers(std::unordered_map<K,std::vector<std::weak_ptr<T>>> &v) noexcept
89{
90 auto i = v.begin();
91 while (i != v.end()) {
92 cleanupWeakPointers(i->second);
93 if (i->second.size() == 0) {
94 i = v.erase(i);
95 } else {
96 i++;
97 }
98 }
99}
100
101template<typename Value, typename Map, typename Key, typename... Args>
102inline std::shared_ptr<Value> try_make_shared(Map &map, Key key, Args... args) {
104
105 ttlet i = map.find(key);
106 if (i == map.end()) {
107 value = std::make_shared<Value>(std::forward<Args>(args)...);
108 map.insert_or_assign(key, value);
109 }
110 else {
111 value = i->second;
112 }
113 return value;
114}
115
116}
T memcpy(T... args)