Async++ unknown
Async (co_await/co_return) code for C++
Loading...
Searching...
No Matches
ptr_tag.h
1#pragma once
2#include <algorithm>
3#include <cassert>
4#include <cstddef>
5#include <cstdint>
6#include <type_traits>
7#include <utility>
8
9namespace asyncpp {
10
18 template<size_t ID, typename T>
19 void* ptr_tag(T* ptr) noexcept
20 requires(alignof(T) > ID)
21 {
22 assert((reinterpret_cast<uintptr_t>(ptr) & (alignof(T) - 1)) == 0);
23 //NOLINTNEXTLINE(performance-no-int-to-ptr)
24 return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) | ID);
25 }
26
34 template<auto ID, typename T>
35 void* ptr_tag(T* ptr) noexcept
36 requires(std::is_enum_v<decltype(ID)>)
37 {
38 return ptr_tag<static_cast<size_t>(ID), T>(ptr);
39 }
40
48 template<size_t ID, typename T>
49 const void* ptr_tag(const T* ptr) noexcept
50 requires(alignof(T) > ID)
51 {
52 assert((reinterpret_cast<uintptr_t>(ptr) & (alignof(T) - 1)) == 0);
53 //NOLINTNEXTLINE(performance-no-int-to-ptr)
54 return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(ptr) | ID);
55 }
56
64 template<auto ID, typename T>
65 const void* ptr_tag(const T* ptr) noexcept
66 requires(std::is_enum_v<decltype(ID)>)
67 {
68 return ptr_tag<static_cast<size_t>(ID), T>(ptr);
69 }
70
77 template<typename T>
78 std::pair<T*, size_t> ptr_untag(void* ptr) noexcept {
79 const auto align_mask = static_cast<uintptr_t>(alignof(T) - 1);
80 auto uptr = reinterpret_cast<uintptr_t>(ptr);
81 return {reinterpret_cast<T*>(uptr & ~align_mask), uptr & align_mask};
82 }
83
91 template<typename T, typename TTag>
92 std::pair<T*, TTag> ptr_untag(void* vptr) noexcept {
93 auto [ptr, tag] = ptr_untag<T>(vptr);
94 return {ptr, static_cast<TTag>(tag)};
95 }
96
103 template<typename T>
104 std::pair<const T*, size_t> ptr_untag(const void* vptr) noexcept {
105 const auto align_mask = static_cast<uintptr_t>(alignof(T) - 1);
106 auto uptr = reinterpret_cast<uintptr_t>(vptr);
107 return {reinterpret_cast<const T*>(uptr & ~align_mask), uptr & align_mask};
108 }
109
117 template<typename T, typename TTag>
118 std::pair<const T*, TTag> ptr_untag(const void* vptr) noexcept {
119 auto [ptr, tag] = ptr_untag<T>(vptr);
120 return {ptr, static_cast<TTag>(tag)};
121 }
122
127 template<typename T1, typename... TExtra>
128 constexpr size_t min_alignof() noexcept {
129 if constexpr (sizeof...(TExtra) > 0)
130 return (std::min)(alignof(T1), min_alignof<TExtra...>());
131 else
132 return alignof(T1);
133 }
134
141 template<typename... T>
142 size_t ptr_get_tag(const void* vptr) noexcept {
143 constexpr auto align_mask = static_cast<uintptr_t>(min_alignof<T...>() - 1);
144 return reinterpret_cast<uintptr_t>(vptr) & align_mask;
145 }
146
147} // namespace asyncpp