mirror of
https://github.com/matrix-construct/construct
synced 2024-11-18 16:00:57 +01:00
160 lines
3.9 KiB
C++
160 lines
3.9 KiB
C++
// Matrix Construct
|
|
//
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
// Copyright (C) 2016-2022 Jason Volk <jason@zemos.net>
|
|
//
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
// copyright notice and this permission notice is present in all copies. The
|
|
// full license for this software is available in the LICENSE file.
|
|
|
|
#pragma once
|
|
#define HAVE_IRCD_UTIL_ALIGN_H
|
|
|
|
namespace ircd {
|
|
inline namespace util
|
|
{
|
|
// Alignment constant expressions
|
|
constexpr bool padded(const size_t, size_t alignment);
|
|
constexpr bool aligned(const uintptr_t, size_t alignment);
|
|
constexpr size_t padding(const size_t size, size_t alignment);
|
|
constexpr size_t pad_to(const size_t size, const size_t alignment);
|
|
constexpr uintptr_t align(uintptr_t, size_t alignment);
|
|
constexpr uintptr_t align_up(uintptr_t, size_t alignment);
|
|
constexpr ulong alignment(const uintptr_t);
|
|
|
|
// Alignment inline tools
|
|
bool aligned(const void *const &, const size_t &alignment);
|
|
bool aligned(const volatile void *const &, const size_t &alignment);
|
|
template<class T = char> const T *align(const void *const &, const size_t &alignment);
|
|
template<class T = char> T *align(void *const &, const size_t &alignment);
|
|
template<class T = char> const T *align_up(const void *const &, const size_t &alignment);
|
|
template<class T = char> T *align_up(void *const &, const size_t &alignment);
|
|
ulong alignment(const void *const &);
|
|
}}
|
|
|
|
[[gnu::always_inline]]
|
|
inline ulong
|
|
ircd::util::alignment(const void *const &ptr)
|
|
{
|
|
return alignment(uintptr_t(ptr));
|
|
}
|
|
|
|
template<class T>
|
|
[[gnu::always_inline]]
|
|
inline T *
|
|
ircd::util::align(void *const &ptr,
|
|
const size_t &alignment)
|
|
{
|
|
return reinterpret_cast<T *>
|
|
(
|
|
align(uintptr_t(ptr), alignment)
|
|
);
|
|
}
|
|
|
|
template<class T>
|
|
[[gnu::always_inline]]
|
|
inline const T *
|
|
ircd::util::align(const void *const &ptr,
|
|
const size_t &alignment)
|
|
{
|
|
return reinterpret_cast<const T *>
|
|
(
|
|
align(uintptr_t(ptr), alignment)
|
|
);
|
|
}
|
|
|
|
template<class T>
|
|
[[gnu::always_inline]]
|
|
inline T *
|
|
ircd::util::align_up(void *const &ptr,
|
|
const size_t &alignment)
|
|
{
|
|
return reinterpret_cast<T *>
|
|
(
|
|
align_up(uintptr_t(ptr), alignment)
|
|
);
|
|
}
|
|
|
|
template<class T>
|
|
[[gnu::always_inline]]
|
|
inline const T *
|
|
ircd::util::align_up(const void *const &ptr,
|
|
const size_t &alignment)
|
|
{
|
|
return reinterpret_cast<const T *>
|
|
(
|
|
align_up(uintptr_t(ptr), alignment)
|
|
);
|
|
}
|
|
|
|
[[gnu::always_inline]]
|
|
inline bool
|
|
ircd::util::aligned(const void *const &ptr,
|
|
const size_t &alignment)
|
|
{
|
|
return aligned(uintptr_t(ptr), alignment);
|
|
}
|
|
|
|
[[gnu::always_inline]]
|
|
inline bool
|
|
ircd::util::aligned(const volatile void *const &ptr,
|
|
const size_t &alignment)
|
|
{
|
|
return aligned(uintptr_t(ptr), alignment);
|
|
}
|
|
|
|
constexpr ulong
|
|
ircd::util::alignment(const uintptr_t ptr)
|
|
{
|
|
return 1UL << __builtin_ctzl(ptr);
|
|
}
|
|
|
|
constexpr uintptr_t
|
|
ircd::util::align_up(uintptr_t ptr,
|
|
size_t alignment)
|
|
{
|
|
alignment = std::max(alignment, 1UL);
|
|
ptr += (alignment - (ptr % alignment)) % alignment;
|
|
return ptr;
|
|
}
|
|
|
|
constexpr uintptr_t
|
|
ircd::util::align(uintptr_t ptr,
|
|
size_t alignment)
|
|
{
|
|
alignment = std::max(alignment, 1UL);
|
|
ptr -= (ptr % alignment);
|
|
return ptr;
|
|
}
|
|
|
|
constexpr size_t
|
|
ircd::util::pad_to(const size_t size,
|
|
const size_t alignment)
|
|
{
|
|
return size + padding(size, alignment);
|
|
}
|
|
|
|
constexpr size_t
|
|
ircd::util::padding(const size_t size,
|
|
size_t alignment)
|
|
{
|
|
alignment = std::max(alignment, 1UL);
|
|
return (alignment - (size % alignment)) % alignment;
|
|
}
|
|
|
|
constexpr bool
|
|
ircd::util::aligned(const uintptr_t ptr,
|
|
size_t alignment)
|
|
{
|
|
alignment = std::max(alignment, 1UL);
|
|
return ptr % alignment == 0;
|
|
}
|
|
|
|
constexpr bool
|
|
ircd::util::padded(const size_t size,
|
|
size_t alignment)
|
|
{
|
|
alignment = std::max(alignment, 1UL);
|
|
return size % alignment == 0;
|
|
}
|