windows-nt/Source/XPSP1/NT/com/rpc/runtime/mtrt/align.h
2020-09-26 16:20:57 +08:00

234 lines
6.5 KiB
C

/*++
Copyright (C) Microsoft Corporation, 1995 - 1999
Module Name:
Align.h
Abstract:
Defines a macro for aligning an integer value or pointer
to 0 mod 2^n for any n.
Author:
Mario Goertzel [MarioGo]
Revision History:
MarioGo 12-22-95 Bits 'n pieces
MarioGo 02-19-96 Made type safe for C++.
--*/
#ifndef _ALIGN_H
#define _ALIGN_H
#ifdef __cplusplus
//
// The C++ interface looks like
//
// val = Align(val, 8) // returns val aligned to 0 mod 8
// val = Align16(val); // returns val aligned to 0 mod 16
//
// Boths forms on the interface are equally efficient.
//
// Returns the argument aligned up to the nearest "0 mod factor" boundary. Has
// no affect on values which are already aligned to 0 mod factor. The argument
// maybe any integer or void pointer type.
//
//
#define DECL_ALIGN_N(type) inline type Align( type value, int poft) \
{ \
return (type)( ((unsigned long)(value) + ((poft)-1)) & ~(poft - 1) ); \
}
#define DECL_ALIGN(poft, type) inline type Align##poft ( type value ) \
{ \
return Align(value, poft); \
}
#define DECL_PAD_N(type) inline unsigned int Pad( type value, int poft ) \
{ \
return (-(long)value) & (poft - 1); \
}
#define DECL_PAD(poft, type) inline unsigned int Pad##poft (type value) \
{ \
return Pad(value, poft); \
}
// same padding, but on pointer type size of argument
#define DECL_ALIGN_PTR_N(type) inline type AlignPtr( type value, int poft) \
{ \
return (type)( ((ULONG_PTR)(value) + ((poft)-1)) & ~(poft - 1) ); \
}
#define DECL_ALIGN_PTR(poft, type) inline type AlignPtr##poft ( type value ) \
{ \
return AlignPtr(value, poft); \
}
#define DECL_PAD_PTR_N(type) inline unsigned int PadPtr( type value, int poft ) \
{ \
return (unsigned int)((-(LONG_PTR)value) & (poft - 1)); \
}
#define DECL_PAD_PTR(poft, type) inline unsigned int PadPtr##poft (type value) \
{ \
return PadPtr(value, poft); \
}
#define DECL_ALL_ALIGN(type) \
DECL_ALIGN_N(type) \
DECL_ALIGN(2, type) \
DECL_ALIGN(4, type) \
DECL_ALIGN(8, type) \
DECL_ALIGN(16, type) \
DECL_ALIGN(32, type)
#define DECL_ALL_PAD(type) \
DECL_PAD_N(type) \
DECL_PAD(2, type) \
DECL_PAD(4, type) \
DECL_PAD(8, type) \
DECL_PAD(16, type) \
DECL_PAD(32, type)
#define DECL_ALL_ALIGN_PTR(type) \
DECL_ALIGN_PTR_N(type) \
DECL_ALIGN_PTR(2, type) \
DECL_ALIGN_PTR(4, type) \
DECL_ALIGN_PTR(8, type) \
DECL_ALIGN_PTR(16, type) \
DECL_ALIGN_PTR(32, type)
#define DECL_ALL_PAD_PTR(type) \
DECL_PAD_PTR_N(type) \
DECL_PAD_PTR(2, type) \
DECL_PAD_PTR(4, type) \
DECL_PAD_PTR(8, type) \
DECL_PAD_PTR(16, type) \
DECL_PAD_PTR(32, type)
#define DECL_ALL_ALIGN_AND_PAD(type) \
DECL_ALL_PAD(type) \
DECL_ALL_ALIGN(type)
#define DECL_ALL_ALIGN_AND_PAD_PTR(type) \
DECL_ALL_PAD_PTR(type) \
DECL_ALL_ALIGN_PTR(type)
DECL_ALL_ALIGN_AND_PAD(short)
DECL_ALL_ALIGN_AND_PAD(unsigned short)
DECL_ALL_ALIGN_AND_PAD(long)
DECL_ALL_ALIGN_AND_PAD(unsigned long)
DECL_ALL_ALIGN_AND_PAD(int)
DECL_ALL_ALIGN_AND_PAD(unsigned int)
DECL_ALL_ALIGN_AND_PAD_PTR(void __RPC_FAR *)
#ifdef _WIN64
DECL_ALL_ALIGN_AND_PAD(unsigned __int64)
#endif
inline BOOL IsBufferAligned(PVOID p)
{
#if defined(_WIN64)
return (((ULONG_PTR)p % 16) == 0);
#else
return (((ULONG_PTR)p % 8) == 0);
#endif
}
inline BOOL IsBufferSizeAligned(size_t s)
{
#if defined(_WIN64)
return ((s % 16) == 0);
#else
return ((s % 8) == 0);
#endif
}
inline unsigned int PadToNaturalBoundary (unsigned int Value)
{
#if defined(_WIN64)
return Pad16(Value);
#else
return Pad8(Value);
#endif
}
inline PVOID AlignOnNaturalBoundary (PVOID Value)
{
#if defined(_WIN64)
return AlignPtr16(Value);
#else
return AlignPtr8(Value);
#endif
}
// required for global constant expressions
#define ConstPadN(p, poft) ( (-(long)p) & (poft - 1) )
#if defined(_WIN64)
#define RPCRT_DEFAULT_STRUCT_ALIGNMENT 8
#else
#define RPCRT_DEFAULT_STRUCT_ALIGNMENT 4
#endif
#define SIZE_OF_OBJECT_AND_PADDING(ObjectType) \
(sizeof(ObjectType) + ConstPadN(sizeof(ObjectType), RPCRT_DEFAULT_STRUCT_ALIGNMENT))
#else
// C interface.
#define AlignN(p, poft) ( ((unsigned long)(p) + ((poft)-1)) & ~(poft - 1) )
#define PadN(p, poft) ( (-(long)p) & (poft - 1) )
#ifdef DOS
#define AlignPtrN(value, poft) (void __far *)AlignN(value, poft)
#define AlignNearPtrN(value, poft) (void __near *)AlignN(value, poft)
#else
#define AlignPtrN(value, poft) (void *)AlignN(value, poft)
#define AlignNearPtrN(value, poft) (void *)AlignN(value, poft)
#endif
// For aligning integer values
#define Align2(p) AlignN((p), 2)
#define Align4(p) AlignN((p), 4)
#define Align8(p) AlignN((p), 8)
#define Align16(p) AlignN((p), 16)
#define Align32(p) AlignN((p), 32)
// For aligning pointers
#define AlignPtr2(p) AlignPtrN((p), 2)
#define AlignPtr4(p) AlignPtrN((p), 4)
#define AlignPtr8(p) AlignPtrN((p), 8)
#define AlignPtr16(p) AlignPtrN((p), 16)
#define AlignPtr32(p) AlignPtrN((p), 32)
// For near pointers
#define AlignNearPtr2(p) AlignNearPtrN((p), 2)
#define AlignNearPtr4(p) AlignNearPtrN((p), 4)
#define AlignNearPtr8(p) AlignNearPtrN((p), 8)
#define AlignNearPtr16(p) AlignNearPtrN((p), 16)
#define AlignNearPtr32(p) AlignNearPtrN((p), 32)
// For everything
#define Pad2(p) PadN((p), 2)
#define Pad4(p) PadN((p), 4)
#define Pad8(p) PadN((p), 8)
#define Pad16(p) PadN((p), 16)
#define Pad32(p) PadN((p), 32)
#endif // __cplusplus
#endif // _ALIGN_H