# EAAlignment

## Introduction

EAAlignment provides a number of utilities for working with variable alignment. These include:

> Entity | Description
> EAAlignOf(type) | Macro which returns the alignment of the given type as a constant expression.
> AlignOf<T> | Template which returns the alignment of the given type.
> AlignAddressUp AlignAddressDown | Function which aligns an arbitrary address up or down to the next user-supplied power of two.
> AlignObjectUp AlignObjectDown | Function which aligns an arbitrary object up or down to the next user-supplied power of two.
> GetAlignment IsAddressAligned IsObjectAligned<T> IsAligned<T> | Gets information about alignment.
> AlignedType | Template which portably allows the re-typing of a class to have a specific alignment.
> AlignedArray | Template which implements an array of an arbitrary class with a given alignment.
> AlignedObject | Template which implements an instance of an arbitrary class with a given alignment.
> ReadMisalignedUint16 ReadMisalignedUint32 ReadMisalignedUint64 | Function which safely and portably reads potentially misaligned memory.
> WriteMisalignedUint16 WriteMisalignedUint32 WriteMisalignedUint64 | Function which safely and portably writes potentially misaligned memory.

We'll discuss some of these briefly.

## EAAlignOf

EAAlignOf is your basic macro for retrieving the alignment of an object by its type. Recent versions of EABase define EA_ALIGN_OF, so EAAlignOf is currently a duplication of the EABase functionality.

Example usage:

    printf("Alignment of type 'int' is %u.\n", (unsigned)EAAlignOf(int));

## AlignedType

This class makes an aligned typedef for a given class based on a user-supplied class and alignment. This class exists because of a weakness in VC++ whereby it can only accept __declspec(align) and thus EA_PREFIX_ALIGN usage via an integer literal (e.g. "16") and not an otherwise equivalent constant integral expression (e.g. sizeof Foo).

Example usage:

    const size_t kAlignment = 32; // Note that in this case the alignment is defined elsewhere as a non-literal.

    AlignedType<Widget, kAlignment>::Type widgetAlign128;

    widgetAlign128.DoSomething();

## ReadMisaligned16/32/64

ReadMisaligned reads an unsigned integer from a possibly non-aligned address. The MIPS processor on the PS2, for example, cannot read a 32-bit value from an unaligned address. This function can be used to make reading such misaligned data portable..

Example usage:

    void DoSomeReading(const char* pData)
    {
        uint16_t x = ReadMisalignedUint16(pData);
        pData += sizeof(uint16_t);

        uint32_t y = ReadMisalignedUint32(pData);
        pData += sizeof(uint32_t);

        uint64_t z = ReadMisalignedUint64(pData);
        pData += sizeof(uint64_t);

        ...
    }