13#include <unordered_map>
18template<
typename T,
typename U>
19void memswap(T &dst, U &src)
21 static_assert(
sizeof(T) ==
sizeof(U),
"memswap requires both objects of equal size");
22 std::byte tmp[
sizeof(T)];
23 memcpy(tmp, &src,
sizeof(T));
24 memcpy(&src, &dst,
sizeof(U));
25 memcpy(&dst, tmp,
sizeof(T));
38template<
typename InputIt,
typename T>
39T *placement_copy(InputIt src, T *dst)
41 tt_axiom(dst !=
nullptr);
42 return new (dst) T(*src);
49template<
typename InputIt,
typename T>
50void placement_copy(InputIt src_first, InputIt src_last, T *dst_first)
52 tt_axiom(src_first != dst_first);
53 tt_axiom(src_last >= src_first);
57 while (src != src_last) {
58 placement_copy(src++, dst++);
76T *placement_move(T *src, T *dst)
78 tt_axiom(src !=
nullptr);
79 tt_axiom(dst !=
nullptr);
96void placement_move_within_array(T *src_first, T *src_last, T *dst_first)
98 tt_axiom(src_last >= src_first);
100 if (src_first < dst_first) {
101 auto dst_last = dst_first + (src_last - src_first);
105 while (src != src_first) {
106 placement_move(--src, --dst);
109 }
else if (src_first > dst_first) {
110 auto src = src_first;
111 auto dst = dst_first;
112 while (src != src_last) {
113 placement_move(src++, dst++);
130void placement_move(T *src, T *src_last, T *dst)
132 tt_axiom(src_last >= src);
134 while (src != src_last) {
135 placement_move(src++, dst++);
142constexpr bool is_aligned(T *p)
152template<std::
unsigned_
integral T>
153constexpr T
floor(T value, T alignment)
noexcept
163template<std::
unsigned_
integral T>
164constexpr T
ceil(T value, T alignment)
noexcept
166 return floor(value + (alignment - 1), alignment);
170constexpr T *
ceil(T *ptr,
size_t alignment)
noexcept
172 ttlet aligned_byte_offset =
ceil(
reinterpret_cast<uintptr_t
>(ptr),
static_cast<uintptr_t
>(alignment));
173 return reinterpret_cast<T *
>(aligned_byte_offset);
177constexpr T *
floor(T *ptr,
size_t alignment)
noexcept
179 ttlet aligned_byte_offset =
floor(
reinterpret_cast<uintptr_t
>(ptr),
static_cast<uintptr_t
>(alignment));
180 return reinterpret_cast<T *
>(aligned_byte_offset);
187 while (i != v.end()) {
196template<
typename K,
typename T>
200 while (i != v.end()) {
201 if (i->second.expired()) {
209template<
typename K,
typename T>
213 while (i != v.end()) {
214 cleanupWeakPointers(i->second);
215 if (i->second.size() == 0) {
223template<
typename Value,
typename Map,
typename Key,
typename... Args>
228 ttlet i = map.find(key);
229 if (i == map.end()) {
230 value = std::make_shared<Value>(std::forward<Args>(args)...);
231 map.insert_or_assign(key, value);
248inline uint64_t ptr_to_uint48(
auto *ptr)
noexcept
250 tt_axiom(
static_cast<uint64_t
>(ptr) % 16 == 0);
252 if constexpr (processor::current == processor::x64) {
255 (
static_cast<uint64_t
>(ptr) & 0xffff'8000'0000'0000) == 0 ||
256 (
static_cast<uint64_t
>(ptr) & 0xffff'8000'0000'0000) == 0xffff'8000'0000'0000);
257 return (
static_cast<uint64_t
>(ptr) << 16) >> 16;
259 }
else if constexpr (processor::current == processor::arm) {
262 (
static_cast<uint64_t
>(ptr) & 0x00ff'8000'0000'0000) == 0 ||
263 (
static_cast<uint64_t
>(ptr) & 0x00ff'8000'0000'0000) == 0x00ff'8000'0000'0000);
266 auto u64 = (
static_cast<uint64_t
>(ptr) << 12) >> 16;
269 auto key = (
static_cast<uint64_t
>(ptr) >> 56) << 44;
275 tt_static_no_default();
290T *uint48_to_ptr(uint64_t x)
noexcept
292 tt_axiom((x >> 48) == 0);
294 if constexpr (processor::current == processor::x64) {
296 auto i64 = (
static_cast<int64_t
>(x) << 16) >> 16;
297 return reinterpret_cast<T *
>(i64);
299 }
else if constexpr (processor::current == processor::arm) {
301 auto key = (
static_cast<uint64_t
>(x) >> 44) << 56;
304 auto i64 = (
static_cast<int64_t
>(x) << 20) >> 16;
307 return reinterpret_cast<T *
>(key ^
static_cast<uint64_t
>(i64));
310 tt_static_no_default();
alignment
Vertical and horizontal alignment.
Definition alignment.hpp:47