13#include <unordered_map>
17namespace hi::inline v1 {
19[[nodiscard]]
bool equal_ptr(
auto *p1,
auto *p2)
noexcept
21 return static_cast<void *
>(p1) ==
static_cast<void *
>(p2);
24template<
typename T,
typename U>
25void memswap(T& dst, U& src)
27 static_assert(
sizeof(T) ==
sizeof(U),
"memswap requires both objects of equal size");
28 std::byte tmp[
sizeof(T)];
29 memcpy(tmp, &src,
sizeof(T));
30 memcpy(&src, &dst,
sizeof(U));
31 memcpy(&dst, tmp,
sizeof(T));
44template<
typename InputIt,
typename T>
45T *placement_copy(InputIt src, T *dst)
47 hi_axiom(dst !=
nullptr);
48 return new (dst) T(*src);
55template<
typename InputIt,
typename T>
56void placement_copy(InputIt src_first, InputIt src_last, T *dst_first)
58 hi_axiom(src_first != dst_first);
59 hi_axiom(src_last >= src_first);
63 while (src != src_last) {
64 placement_copy(src++, dst++);
82T *placement_move(T *src, T *dst)
84 hi_axiom(src !=
nullptr);
85 hi_axiom(dst !=
nullptr);
102void placement_move_within_array(T *src_first, T *src_last, T *dst_first)
104 hi_axiom(src_last >= src_first);
106 if (src_first < dst_first) {
107 auto dst_last = dst_first + (src_last - src_first);
111 while (src != src_first) {
112 placement_move(--src, --dst);
115 }
else if (src_first > dst_first) {
116 auto src = src_first;
117 auto dst = dst_first;
118 while (src != src_last) {
119 placement_move(src++, dst++);
136void placement_move(T *src, T *src_last, T *dst)
138 hi_axiom(src_last >= src);
140 while (src != src_last) {
141 placement_move(src++, dst++);
147template<
typename It,
typename... Args>
148void construct(It first, It last, Args
const&...args)
150 for (
auto it = first; it != last; ++it) {
158constexpr bool is_aligned(T *p)
168template<std::
unsigned_
integral T>
169constexpr T
floor(T value, T alignment)
noexcept
171 return (value / alignment) * alignment;
179template<std::
unsigned_
integral T>
180constexpr T
ceil(T value, T alignment)
noexcept
182 return floor(value + (alignment - 1), alignment);
188 hilet aligned_byte_offset =
ceil(
reinterpret_cast<uintptr_t
>(ptr),
static_cast<uintptr_t
>(alignment));
189 return reinterpret_cast<T *
>(aligned_byte_offset);
195 hilet aligned_byte_offset =
floor(
reinterpret_cast<uintptr_t
>(ptr),
static_cast<uintptr_t
>(alignment));
196 return reinterpret_cast<T *
>(aligned_byte_offset);
203 while (i != v.end()) {
212template<
typename K,
typename T>
216 while (i != v.end()) {
217 if (i->second.expired()) {
225template<
typename K,
typename T>
229 while (i != v.end()) {
230 cleanupWeakPointers(i->second);
231 if (i->second.size() == 0) {
239template<
typename Value,
typename Map,
typename Key,
typename... Args>
244 hilet i = map.find(key);
245 if (i == map.end()) {
246 value = std::make_shared<Value>(std::forward<Args>(args)...);
247 map.insert_or_assign(key, value);
264inline uint64_t ptr_to_uint48(
auto *ptr)
noexcept
266 hi_axiom(
static_cast<uint64_t
>(ptr) % 16 == 0);
268 if constexpr (processor::current == processor::x64) {
271 (
static_cast<uint64_t
>(ptr) & 0xffff'8000'0000'0000) == 0 ||
272 (
static_cast<uint64_t
>(ptr) & 0xffff'8000'0000'0000) == 0xffff'8000'0000'0000);
273 return (
static_cast<uint64_t
>(ptr) << 16) >> 16;
275 }
else if constexpr (processor::current == processor::arm) {
278 (
static_cast<uint64_t
>(ptr) & 0x00ff'8000'0000'0000) == 0 ||
279 (
static_cast<uint64_t
>(ptr) & 0x00ff'8000'0000'0000) == 0x00ff'8000'0000'0000);
282 auto u64 = (
static_cast<uint64_t
>(ptr) << 12) >> 16;
285 auto key = (
static_cast<uint64_t
>(ptr) >> 56) << 44;
291 hi_static_no_default();
306T *uint48_to_ptr(uint64_t x)
noexcept
308 hi_axiom((x >> 48) == 0);
310 if constexpr (processor::current == processor::x64) {
312 auto i64 = (
static_cast<int64_t
>(x) << 16) >> 16;
313 return reinterpret_cast<T *
>(i64);
315 }
else if constexpr (processor::current == processor::arm) {
317 auto key = (
static_cast<uint64_t
>(x) >> 44) << 56;
320 auto i64 = (
static_cast<int64_t
>(x) << 20) >> 16;
323 return reinterpret_cast<T *
>(key ^
static_cast<uint64_t
>(i64));
326 hi_static_no_default();
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23