DOSBox-X
|
00001 00002 #include <stdint.h> 00003 00004 namespace ptrop { 00005 00006 /* return the misalignment in bytes of 'p' in the context of a data type of size 'A', 00007 * 'A' must be a power of 2, or else this code will not work. */ 00008 static inline constexpr uintptr_t misalignment(const uintptr_t p,const uintptr_t A) { 00009 return p & (A - (uintptr_t)1u); 00010 } 00011 00012 template <const uintptr_t A> static inline constexpr uintptr_t misalignment(const uintptr_t p) { // DEFER 00013 return misalignment(p,A); 00014 } 00015 00016 template <typename A> static inline constexpr uintptr_t misalignment(const uintptr_t p) { // DEFER 00017 return misalignment<(uintptr_t)sizeof(A)>(p); 00018 } 00019 00020 template <typename T=unsigned char,typename A=T> static inline constexpr uintptr_t misalignment(T* const p) { // DEFER 00021 return misalignment<A>((uintptr_t)((unsigned char*)p)); 00022 } 00023 00024 template <typename T=unsigned char,const uintptr_t A> static inline constexpr uintptr_t misalignment(T* const p) { // DEFER 00025 return misalignment<A>((uintptr_t)((unsigned char*)p)); 00026 } 00027 00028 00029 /* indicate whether pointer 'p' is aligned to type of size 'A' */ 00030 static inline constexpr bool isaligned(const uintptr_t p,const uintptr_t A) { 00031 return misalignment(p,A) == (uintptr_t)0; 00032 } 00033 00034 template <const uintptr_t A> static inline constexpr bool isaligned(const uintptr_t p) { // DEFER 00035 return isaligned(p,A); 00036 } 00037 00038 template <typename A> static inline constexpr bool isaligned(const uintptr_t p) { // DEFER 00039 return isaligned<(uintptr_t)sizeof(A)>(p); 00040 } 00041 00042 template <typename T=unsigned char,typename A=T> static inline constexpr bool isaligned(T* const p) { // DEFER 00043 return isaligned<A>((uintptr_t)((unsigned char*)p)); 00044 } 00045 00046 template <typename T=unsigned char,const uintptr_t A> static inline constexpr bool isaligned(T* const p) { // DEFER 00047 return isaligned<A>((uintptr_t)((unsigned char*)p)); 00048 } 00049 00050 00051 /* take pointer 'p' and align downward to type of size 'A' */ 00052 static inline constexpr uintptr_t aligndown(const uintptr_t p,const uintptr_t A) { 00053 return p - misalignment(p,A); 00054 } 00055 00056 template <const uintptr_t A> static inline constexpr uintptr_t aligndown(const uintptr_t p) { // DEFER 00057 return aligndown(p,A); 00058 } 00059 00060 template <typename A> static inline constexpr uintptr_t aligndown(const uintptr_t p) { // DEFER 00061 return aligndown<(uintptr_t)sizeof(A)>(p); 00062 } 00063 00064 template <typename T=unsigned char,typename A=T> static inline constexpr T* aligndown(T* const p) { // DEFER 00065 return (T*)aligndown<A>((uintptr_t)((unsigned char*)p)); 00066 } 00067 00068 template <typename T=unsigned char,const uintptr_t A> static inline constexpr T* aligndown(T* const p) { // DEFER 00069 return (T*)aligndown<A>((uintptr_t)((unsigned char*)p)); 00070 } 00071 00072 00073 /* take pointer 'p' and align upward to type of size 'A' */ 00074 static inline constexpr uintptr_t alignup(const uintptr_t p,const uintptr_t A) { 00075 return aligndown(p + (uintptr_t)A - (uintptr_t)1u,A); 00076 } 00077 00078 template <const uintptr_t A> static inline constexpr uintptr_t alignup(const uintptr_t p) { // DEFER 00079 return alignup(p,A); 00080 } 00081 00082 template <typename A> static inline constexpr uintptr_t alignup(const uintptr_t p) { // DEFER 00083 return alignup<(uintptr_t)sizeof(A)>(p); 00084 } 00085 00086 template <typename T=unsigned char,typename A=T> static inline constexpr T* alignup(T* const p) { // DEFER 00087 return (T*)alignup<A>((uintptr_t)((unsigned char*)p)); 00088 } 00089 00090 template <typename T=unsigned char,const uintptr_t A> static inline constexpr T* alignup(T* const p) { // DEFER 00091 return (T*)alignup<A>((uintptr_t)((unsigned char*)p)); 00092 } 00093 00094 void self_test(void); 00095 00096 } 00097