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 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) if (ptr + bytes > m_end)
throw std::bad_alloc (); throw std::bad_alloc ();

View File

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

View File

@ -6,10 +6,7 @@
* Copyright 2011-2017 Danny Robson <danny@nerdcruft.net> * Copyright 2011-2017 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef CRUFT_UTIL_POINTER_HPP #pragma once
#define CRUFT_UTIL_POINTER_HPP
#include "view.hpp"
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
@ -18,51 +15,28 @@
namespace cruft { namespace cruft {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/// round the pointer upwards to satisfy the provided alignment /// 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 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 // we perform this as two steps to avoid unnecessarily incrementing when
// remainder is zero. // remainder is zero.
if (ptr % alignment) if (auto mod = ptr % alignment; mod)
ptr += alignment - ptr % alignment; ptr += alignment - mod;
return ptr; 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> template <typename T>
constexpr auto constexpr T*
align (T *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 /// round the pointer upwards to the nearest valid alignment for T
template <typename T> template <typename T>
constexpr auto 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 // ensure we have an base pointer that's off-by-one to a likely natural
// system alignment // system alignment
std::byte* base = cruft::align ( std::byte* base = cruft::align_up (
std::data (buffer), std::data (buffer),
alignof (std::max_align_t) alignof (std::max_align_t)
) + increment; ) + increment;