DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
include/ptrop.h
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