13#include <unordered_map>
20hi_warning_ignore_msvc(26474);
23hi_warning_ignore_msvc(26472);
25namespace hi::inline
v1 {
27[[nodiscard]]
bool equal_ptr(
auto *p1,
auto *p2)
noexcept
29 return static_cast<void *
>(p1) ==
static_cast<void *
>(p2);
32template<
typename T,
typename U>
33void memswap(T& dst, U& src)
35 static_assert(
sizeof(T) ==
sizeof(U),
"memswap requires both objects of equal size");
36 std::byte tmp[
sizeof(T)];
37 memcpy(tmp, &src,
sizeof(T));
38 memcpy(&src, &dst,
sizeof(U));
39 memcpy(&dst, tmp,
sizeof(T));
52template<
typename InputIt,
typename T>
56 return new (dst) T(*src);
63template<
typename InputIt,
typename T>
71 while (src != src_last) {
114 if (src_first < dst_first) {
115 auto dst_last = dst_first + (src_last - src_first);
119 while (src != src_first) {
123 }
else if (src_first > dst_first) {
124 auto src = src_first;
125 auto dst = dst_first;
126 while (src != src_last) {
148 while (src != src_last) {
155template<
typename It,
typename... Args>
158 for (
auto it = first; it != last; ++it) {
172constexpr T *ceil(T *ptr,
std::size_t alignment)
noexcept
174 hilet aligned_byte_offset = ceil(
reinterpret_cast<uintptr_t
>(ptr), wide_cast<uintptr_t>(alignment));
175 return reinterpret_cast<T *
>(aligned_byte_offset);
181 hilet aligned_byte_offset =
floor(
reinterpret_cast<uintptr_t
>(ptr), wide_cast<uintptr_t>(alignment));
182 return reinterpret_cast<T *
>(aligned_byte_offset);
194 return static_cast<char *
>(ptr) + distance;
206 return static_cast<char const *
>(ptr) + distance;
213 while (i != v.end()) {
222template<
typename K,
typename T>
226 while (i != v.end()) {
227 if (i->second.expired()) {
235template<
typename K,
typename T>
239 while (i != v.end()) {
240 cleanupWeakPointers(i->second);
241 if (i->second.size() == 0) {
249template<
typename Value,
typename Map,
typename Key,
typename... Args>
254 hilet i = map.find(key);
255 if (i == map.end()) {
256 value = std::make_shared<Value>(std::forward<Args>(args)...);
257 map.insert_or_assign(key, value);
266template<numeric T,
byte_like B>
271 if (not std::is_constant_evaluated()) {
277 if constexpr (std::endian::native == std::endian::little) {
278 for (
auto i =
sizeof(T); i != 0; --i) {
279 if constexpr (
sizeof(r) > 1) {
282 r |=
static_cast<uint8_t
>(src[i - 1]);
285 for (
auto i = 0; i !=
sizeof(T); ++i) {
286 if constexpr (
sizeof(r) > 1) {
289 r |=
static_cast<uint8_t
>(src[i]);
296[[nodiscard]]
inline T unaligned_load(
void const *src)
noexcept
298 return unaligned_load<T>(
static_cast<std::byte
const *
>(src));
301template<numeric T,
byte_like B>
302[[nodiscard]]
constexpr void unaligned_store(T src, B *dst)
noexcept
304 using unsigned_type = std::make_unsigned_t<T>;
306 hilet src_ =
static_cast<unsigned_type
>(src);
308 if (not std::is_constant_evaluated()) {
313 if constexpr (std::endian::native == std::endian::little) {
314 for (
auto i = 0; i !=
sizeof(T); ++i) {
315 dst[i] =
static_cast<B
>(src_);
319 for (
auto i =
sizeof(T); i != 0; --i) {
320 dst[i - 1] =
static_cast<B
>(src_);
327[[nodiscard]]
inline void unaligned_store(T src,
void *dst)
noexcept
329 return unaligned_store(src,
reinterpret_cast<std::byte *
>(dst));
333[[nodiscard]] hi_force_inline
constexpr void store_or(T src, uint8_t *dst)
noexcept
337 using unsigned_type = std::make_unsigned_t<T>;
339 auto src_ = truncate<unsigned_type>(src);
341 if (not std::is_constant_evaluated()) {
348 if constexpr (std::endian::native == std::endian::little) {
349 for (
auto i = 0; i !=
sizeof(T); ++i) {
350 dst[i] |= truncate<uint8_t>(src_);
354 for (
auto i =
sizeof(T); i != 0; --i) {
355 dst[i] |= truncate<uint8_t>(src_);
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
#define hi_axiom_not_null(expression,...)
Assert if an expression is not nullptr.
Definition assert.hpp:257
Miscellaneous math functions.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
T * placement_copy(InputIt src, T *dst)
Copy an object to another memory locations.
Definition memory.hpp:53
void * advance_bytes(void *ptr, std::ptrdiff_t distance) noexcept
Advance a pointer by a number of bytes.
Definition memory.hpp:191
void construct(It first, It last, Args const &...args)
Construct a set of objects.
Definition memory.hpp:156
constexpr bool is_aligned(T *p)
Check if a pointer is properly aligned for the object it is pointing at.
Definition memory.hpp:166
void placement_move_within_array(T *src_first, T *src_last, T *dst_first)
Move an objects between two memory locations.
Definition memory.hpp:110
constexpr T unaligned_load(B const *src) noexcept
Make an unaligned load of an unsigned integer.
Definition memory.hpp:267
T * placement_move(T *src, T *dst)
Move an object between two memory locations.
Definition memory.hpp:90