pointer: rename align as align_up, and add align_down

This commit is contained in:
Danny Robson 2018-12-17 14:45:54 +11:00
parent 60bd71a57b
commit 043dd73677
4 changed files with 47 additions and 46 deletions

View File

@ -48,7 +48,7 @@ namespace cruft::alloc::raw {
{
auto const bytes = count * sizeof (T);
auto ptr = cruft::align (m_cursor, alignment);
auto ptr = cruft::align_up (m_cursor, alignment);
if (ptr + bytes > m_end)
throw std::bad_alloc ();

View File

@ -40,7 +40,7 @@ namespace cruft::alloc::raw {
// align the outgoing pointer if required
alignment = cruft::max (MIN_ALIGNMENT, alignment);
ptr = cruft::align (ptr, alignment);
ptr = cruft::align_up (ptr, alignment);
// ensure we haven't overrun our allocated segment
if (ptr + bytes > m_end)

View File

@ -6,10 +6,7 @@
* Copyright 2011-2017 Danny Robson <danny@nerdcruft.net>
*/
#ifndef CRUFT_UTIL_POINTER_HPP
#define CRUFT_UTIL_POINTER_HPP
#include "view.hpp"
#pragma once
#include <cstddef>
#include <cstdint>
@ -18,51 +15,28 @@
namespace cruft {
///////////////////////////////////////////////////////////////////////////
/// round the pointer upwards to satisfy the provided alignment
template <typename T>
constexpr T*
align (T *_ptr, size_t alignment)
{
// we perform this as two steps to avoid unnecessarily incrementing when
// remainder is zero.
auto ptr = reinterpret_cast<uintptr_t> (_ptr);
if (ptr % alignment)
ptr += alignment - ptr % alignment;
return reinterpret_cast<T*> (ptr);
}
///////////////////////////////////////////////////////////////////////////
template <typename ValueT>
constexpr cruft::view<ValueT*>
align (cruft::view<ValueT*> value, size_t alignment)
{
return {
align (value.begin (), alignment),
value.end ()
};
}
///------------------------------------------------------------------------
/// round the pointer upwards to satisfy the provided alignment
constexpr inline uintptr_t
align (uintptr_t ptr, size_t alignment)
align_up (uintptr_t ptr, size_t alignment)
{
// we perform this as two steps to avoid unnecessarily incrementing when
// remainder is zero.
if (ptr % alignment)
ptr += alignment - ptr % alignment;
if (auto mod = ptr % alignment; mod)
ptr += alignment - mod;
return ptr;
}
///------------------------------------------------------------------------
/// round the pointer upwards to the nearest valid alignment for T
///////////////////////////////////////////////////////////////////////////
/// round the pointer upwards to satisfy the provided alignment
template <typename T>
constexpr auto
align (T *t)
constexpr T*
align_up (T *_ptr, size_t alignment)
{
return align (t, alignof (T));
// we perform this as two steps to avoid unnecessarily incrementing when
// remainder is zero.
return reinterpret_cast<T*>(
align_up (reinterpret_cast<uintptr_t> (_ptr), alignment)
);
}
@ -70,10 +44,37 @@ namespace cruft {
/// round the pointer upwards to the nearest valid alignment for T
template <typename T>
constexpr auto
align (uintptr_t ptr)
align_up (T *t)
{
return align (ptr, alignof (T));
return align_up (t, alignof (T));
}
///------------------------------------------------------------------------
/// round the pointer upwards to the nearest valid alignment for T
template <typename T>
constexpr auto
align_up (uintptr_t ptr)
{
return align_up (ptr, alignof (T));
}
///////////////////////////////////////////////////////////////////////////
constexpr inline uintptr_t
align_down (uintptr_t ptr, size_t alignment)
{
return ptr - ptr % alignment;
}
//-------------------------------------------------------------------------
template <typename T>
constexpr T*
align_down (T *ptr, size_t alignment)
{
return reinterpret_cast<T*> (
align_down (reinterpret_cast<uintptr_t> (ptr), alignment)
);
}
}
#endif

View File

@ -12,7 +12,7 @@ main ()
// ensure we have an base pointer that's off-by-one to a likely natural
// system alignment
std::byte* base = cruft::align (
std::byte* base = cruft::align_up (
std::data (buffer),
alignof (std::max_align_t)
) + increment;