dosbox-x/include/ptrop.h
2021-08-22 15:47:10 +09:00

97 lines
3.4 KiB
C++

#include <stdint.h>
namespace ptrop {
/* return the misalignment in bytes of 'p' in the context of a data type of size 'A',
* 'A' must be a power of 2, or else this code will not work. */
static inline constexpr uintptr_t misalignment(const uintptr_t p,const uintptr_t A) {
return p & (A - (uintptr_t)1u);
}
template <const uintptr_t A> static inline constexpr uintptr_t misalignment(const uintptr_t p) { // DEFER
return misalignment(p,A);
}
template <typename A> static inline constexpr uintptr_t misalignment(const uintptr_t p) { // DEFER
return misalignment<(uintptr_t)sizeof(A)>(p);
}
template <typename T=unsigned char,typename A=T> static inline constexpr uintptr_t misalignment(T* const p) { // DEFER
return misalignment<A>((uintptr_t)((unsigned char*)p));
}
template <typename T=unsigned char,const uintptr_t A> static inline constexpr uintptr_t misalignment(T* const p) { // DEFER
return misalignment<A>((uintptr_t)((unsigned char*)p));
}
/* indicate whether pointer 'p' is aligned to type of size 'A' */
static inline constexpr bool isaligned(const uintptr_t p,const uintptr_t A) {
return misalignment(p,A) == (uintptr_t)0;
}
template <const uintptr_t A> static inline constexpr bool isaligned(const uintptr_t p) { // DEFER
return isaligned(p,A);
}
template <typename A> static inline constexpr bool isaligned(const uintptr_t p) { // DEFER
return isaligned<(uintptr_t)sizeof(A)>(p);
}
template <typename T=unsigned char,typename A=T> static inline constexpr bool isaligned(T* const p) { // DEFER
return isaligned<A>((uintptr_t)((unsigned char*)p));
}
template <typename T=unsigned char,const uintptr_t A> static inline constexpr bool isaligned(T* const p) { // DEFER
return isaligned<A>((uintptr_t)((unsigned char*)p));
}
/* take pointer 'p' and align downward to type of size 'A' */
static inline constexpr uintptr_t aligndown(const uintptr_t p,const uintptr_t A) {
return p - misalignment(p,A);
}
template <const uintptr_t A> static inline constexpr uintptr_t aligndown(const uintptr_t p) { // DEFER
return aligndown(p,A);
}
template <typename A> static inline constexpr uintptr_t aligndown(const uintptr_t p) { // DEFER
return aligndown<(uintptr_t)sizeof(A)>(p);
}
template <typename T=unsigned char,typename A=T> static inline constexpr T* aligndown(T* const p) { // DEFER
return (T*)aligndown<A>((uintptr_t)((unsigned char*)p));
}
template <typename T=unsigned char,const uintptr_t A> static inline constexpr T* aligndown(T* const p) { // DEFER
return (T*)aligndown<A>((uintptr_t)((unsigned char*)p));
}
/* take pointer 'p' and align upward to type of size 'A' */
static inline constexpr uintptr_t alignup(const uintptr_t p,const uintptr_t A) {
return aligndown(p + (uintptr_t)A - (uintptr_t)1u,A);
}
template <const uintptr_t A> static inline constexpr uintptr_t alignup(const uintptr_t p) { // DEFER
return alignup(p,A);
}
template <typename A> static inline constexpr uintptr_t alignup(const uintptr_t p) { // DEFER
return alignup<(uintptr_t)sizeof(A)>(p);
}
template <typename T=unsigned char,typename A=T> static inline constexpr T* alignup(T* const p) { // DEFER
return (T*)alignup<A>((uintptr_t)((unsigned char*)p));
}
template <typename T=unsigned char,const uintptr_t A> static inline constexpr T* alignup(T* const p) { // DEFER
return (T*)alignup<A>((uintptr_t)((unsigned char*)p));
}
void self_test(void);
}