13#include <unordered_map>
20hi_warning_ignore_msvc(26474);
22namespace hi::inline v1 {
24[[nodiscard]]
bool equal_ptr(
auto *p1,
auto *p2)
noexcept
26 return static_cast<void *
>(p1) ==
static_cast<void *
>(p2);
29template<
typename T,
typename U>
30void memswap(T& dst, U& src)
32 static_assert(
sizeof(T) ==
sizeof(U),
"memswap requires both objects of equal size");
33 std::byte tmp[
sizeof(T)];
34 memcpy(tmp, &src,
sizeof(T));
35 memcpy(&src, &dst,
sizeof(U));
36 memcpy(&dst, tmp,
sizeof(T));
49template<
typename InputIt,
typename T>
50T *placement_copy(InputIt src, T *dst)
52 hi_axiom(dst !=
nullptr);
53 return new (dst) T(*src);
60template<
typename InputIt,
typename T>
61void placement_copy(InputIt src_first, InputIt src_last, T *dst_first)
63 hi_axiom(src_first != dst_first);
64 hi_axiom(src_last >= src_first);
68 while (src != src_last) {
69 placement_copy(src++, dst++);
87T *placement_move(T *src, T *dst)
89 hi_axiom(src !=
nullptr);
90 hi_axiom(dst !=
nullptr);
107void placement_move_within_array(T *src_first, T *src_last, T *dst_first)
109 hi_axiom(src_last >= src_first);
111 if (src_first < dst_first) {
112 auto dst_last = dst_first + (src_last - src_first);
116 while (src != src_first) {
117 placement_move(--src, --dst);
120 }
else if (src_first > dst_first) {
121 auto src = src_first;
122 auto dst = dst_first;
123 while (src != src_last) {
124 placement_move(src++, dst++);
141void placement_move(T *src, T *src_last, T *dst)
143 hi_axiom(src_last >= src);
145 while (src != src_last) {
146 placement_move(src++, dst++);
152template<
typename It,
typename... Args>
153void construct(It first, It last, Args
const&...args)
155 for (
auto it = first; it != last; ++it) {
163constexpr bool is_aligned(T *p)
173template<std::
unsigned_
integral T>
174constexpr T
floor(T value, T alignment)
noexcept
176 return (value / alignment) * alignment;
184template<std::
unsigned_
integral T>
185constexpr T
ceil(T value, T alignment)
noexcept
187 return floor(value + (alignment - 1), alignment);
193 hilet aligned_byte_offset =
ceil(
reinterpret_cast<uintptr_t
>(ptr),
static_cast<uintptr_t
>(alignment));
194 return reinterpret_cast<T *
>(aligned_byte_offset);
200 hilet aligned_byte_offset =
floor(
reinterpret_cast<uintptr_t
>(ptr),
static_cast<uintptr_t
>(alignment));
201 return reinterpret_cast<T *
>(aligned_byte_offset);
210inline void *advance_bytes(
void *ptr,
std::ptrdiff_t distance)
noexcept
212 hi_axiom(ptr !=
nullptr);
213 return static_cast<char *
>(ptr) + distance;
222inline void const *advance_bytes(
void const *ptr,
std::ptrdiff_t distance)
noexcept
224 hi_axiom(ptr !=
nullptr);
225 return static_cast<char const *
>(ptr) + distance;
232 while (i != v.end()) {
241template<
typename K,
typename T>
245 while (i != v.end()) {
246 if (i->second.expired()) {
254template<
typename K,
typename T>
258 while (i != v.end()) {
259 cleanupWeakPointers(i->second);
260 if (i->second.size() == 0) {
268template<
typename Value,
typename Map,
typename Key,
typename... Args>
273 hilet i = map.find(key);
274 if (i == map.end()) {
275 value = std::make_shared<Value>(std::forward<Args>(args)...);
276 map.insert_or_assign(key, value);
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23