diff --git a/doc/align.qbk b/doc/align.qbk index de3a0d7..ff394e1 100644 --- a/doc/align.qbk +++ b/doc/align.qbk @@ -31,6 +31,9 @@ verify pointer value alignment. [ [`align`] [Pointer alignment function] ] + [ [`align_up`, `align_down`] + [Pointer and integral alignment functions] + ] [ [`aligned_alloc`, `aligned_free`] [Aligned allocation and deallocation functions] ] @@ -50,7 +53,7 @@ verify pointer value alignment. [Macro for static pointer alignment hint] ] [ [`is_aligned`] - [Pointer alignment verification function] + [Pointer and integral alignment checking] ] ] @@ -546,6 +549,76 @@ void* align(std::size_t alignment, std::size_t size, void*& ptr, [endsect] +[section:align_up aligned_up and align_down] + +The directional alignment functions can be used with pointers or +integral values to align up or down. This functionality is not yet +provided by the C++ standard. + +[heading:synopsis Header ] + +`` +namespace boost { + namespace alignment { + constexpr std::size_t align_up(std::size_t value, std::size_t + alignment) noexcept; + + void* align_up(void* ptr, std::size_t alignment) noexcept; + } +} +`` + +[heading:synopsis Header ] + +`` +namespace boost { + namespace alignment { + constexpr std::size_t align_down(std::size_t value, std::size_t + alignment) noexcept; + + void* align_down(void* ptr, std::size_t alignment) noexcept; + } +} +`` + +[heading:align_up Function align_up] + +`` +void* align_up(void* ptr, std::size_t alignment) noexcept; +`` + +[: + [*Requires:] + [itemized_list + [`ptr` shall point to contiguous storage with sufficient space + for alignment] + [`alignment` shall be a power of two] + ] + + [*Returns:] A pointer value at or after `ptr` that is at least + `alignment` bytes aligned. +] + +[heading:align_down Function align_down] + +`` +void* align_down(void* ptr, std::size_t alignment) noexcept; +`` + +[: + [*Requires:] + [itemized_list + [`ptr` shall point to contiguous storage with sufficient space + for alignment] + [`alignment` shall be a power of two] + ] + + [*Returns:] A pointer value at or before `ptr` that is at least + `alignment` bytes aligned. +] + +[endsect] + [section:aligned_alloc aligned_alloc and aligned_free] The aligned allocation function is a replacement for @@ -1155,7 +1228,10 @@ is not yet provided by the C++ standard. `` namespace boost { namespace alignment { - bool is_aligned(std::size_t alignment, const void* ptr) noexcept; + constexpr bool is_aligned(std::size_t value, std::size_t + alignment) noexcept; + + bool is_aligned(const void* ptr, std::size_t alignment) noexcept; } } `` @@ -1163,7 +1239,7 @@ namespace boost { [heading:is_aligned Function is_aligned] `` -bool is_aligned(std::size_t alignment, const void* ptr) noexcept; +bool is_aligned(const void* ptr, std::size_t alignment) noexcept; `` [: @@ -1321,16 +1397,27 @@ examples, tests, or documentation. * Michael Spencer * Paul A. Bristow -[heading Review Manager] - Thank you to Ahmed Charles who served as review manager for the formal review of the library. +[heading Contributions] + +Thank you to Joel Falcou and Charly Chevalier for your contribution and +patience. + [endsect] [section History] -[heading Version 1.0] +[heading Boost 1.61] + +* Added pointer and integral functions for aligning up and down. + +[heading Boost 1.59] + +* Joel Falcou contributed the alignment hint macros. + +[heading Boost 1.56] * Glen Fernandes implemented the Boost.Align library. diff --git a/include/boost/align/detail/align_down.hpp b/include/boost/align/detail/align_down.hpp index 04604d5..29a2238 100644 --- a/include/boost/align/detail/align_down.hpp +++ b/include/boost/align/detail/align_down.hpp @@ -17,17 +17,17 @@ http://boost.org/LICENSE_1_0.txt namespace boost { namespace alignment { -BOOST_CONSTEXPR inline std::size_t align_down(std::size_t alignment, - std::size_t value) BOOST_NOEXCEPT +BOOST_CONSTEXPR inline std::size_t align_down(std::size_t value, + std::size_t alignment) BOOST_NOEXCEPT { return value & ~(alignment - 1); } -inline void* align_down(std::size_t alignment, void* ptr) BOOST_NOEXCEPT +inline void* align_down(void* ptr, std::size_t alignment) BOOST_NOEXCEPT { BOOST_ASSERT(detail::is_alignment(alignment)); - return reinterpret_cast(align_down(alignment, - reinterpret_cast(ptr))); + return reinterpret_cast(align_down(reinterpret_cast(ptr), alignment)); } } /* .alignment */ diff --git a/include/boost/align/detail/align_up.hpp b/include/boost/align/detail/align_up.hpp index 98b4b59..c0545ee 100644 --- a/include/boost/align/detail/align_up.hpp +++ b/include/boost/align/detail/align_up.hpp @@ -17,17 +17,17 @@ http://boost.org/LICENSE_1_0.txt namespace boost { namespace alignment { -BOOST_CONSTEXPR inline std::size_t align_up(std::size_t alignment, - std::size_t value) BOOST_NOEXCEPT +BOOST_CONSTEXPR inline std::size_t align_up(std::size_t value, + std::size_t alignment) BOOST_NOEXCEPT { return (value + alignment - 1) & ~(alignment - 1); } -inline void* align_up(std::size_t alignment, void* ptr) BOOST_NOEXCEPT +inline void* align_up(void* ptr, std::size_t alignment) BOOST_NOEXCEPT { BOOST_ASSERT(detail::is_alignment(alignment)); - return reinterpret_cast(align_up(alignment, - reinterpret_cast(ptr))); + return reinterpret_cast(align_up(reinterpret_cast(ptr), alignment)); } } /* .alignment */ diff --git a/include/boost/align/detail/is_aligned.hpp b/include/boost/align/detail/is_aligned.hpp index f3e850e..709ae3b 100644 --- a/include/boost/align/detail/is_aligned.hpp +++ b/include/boost/align/detail/is_aligned.hpp @@ -17,17 +17,24 @@ http://boost.org/LICENSE_1_0.txt namespace boost { namespace alignment { -BOOST_CONSTEXPR inline bool is_aligned(std::size_t alignment, - std::size_t value) BOOST_NOEXCEPT +BOOST_CONSTEXPR inline bool is_aligned(std::size_t value, + std::size_t alignment) BOOST_NOEXCEPT { return (value & (alignment - 1)) == 0; } +inline bool is_aligned(const void* ptr, std::size_t alignment) + BOOST_NOEXCEPT +{ + BOOST_ASSERT(detail::is_alignment(alignment)); + return is_aligned(reinterpret_cast(ptr), alignment); +} + inline bool is_aligned(std::size_t alignment, const void* ptr) BOOST_NOEXCEPT { BOOST_ASSERT(detail::is_alignment(alignment)); - return is_aligned(alignment, reinterpret_cast(ptr)); + return is_aligned(reinterpret_cast(ptr), alignment); } } /* .alignment */ diff --git a/test/align_down_test.cpp b/test/align_down_test.cpp index bbb16ec..136e998 100644 --- a/test/align_down_test.cpp +++ b/test/align_down_test.cpp @@ -16,17 +16,17 @@ void test() { char s[Alignment << 1]; char* b = s; - while (!boost::alignment::is_aligned(Alignment, b)) { + while (!boost::alignment::is_aligned(b, Alignment)) { b++; } { void* p = &b[Alignment]; - BOOST_TEST(boost::alignment::align_down(Alignment, p) == p); + BOOST_TEST(boost::alignment::align_down(p, Alignment) == p); } { void* p = &b[Alignment - 1]; void* q = b; - BOOST_TEST(boost::alignment::align_down(Alignment, p) == q); + BOOST_TEST(boost::alignment::align_down(p, Alignment) == q); } } diff --git a/test/align_test.cpp b/test/align_test.cpp index 2996eea..ee6cccb 100644 --- a/test/align_test.cpp +++ b/test/align_test.cpp @@ -16,7 +16,7 @@ void test() { char s[Alignment << 1]; char* b = s; - while (!boost::alignment::is_aligned(Alignment, b)) { + while (!boost::alignment::is_aligned(b, Alignment)) { b++; } { @@ -25,7 +25,7 @@ void test() void* q = boost::alignment::align(Alignment, 1, p, n); BOOST_TEST(q == p); BOOST_TEST(q == b); - BOOST_TEST(boost::alignment::is_aligned(Alignment, q)); + BOOST_TEST(boost::alignment::is_aligned(q, Alignment)); BOOST_TEST(n == Alignment); } { @@ -42,7 +42,7 @@ void test() void* q = boost::alignment::align(Alignment, 1, p, n); BOOST_TEST(q == p); BOOST_TEST(p == &b[Alignment]); - BOOST_TEST(boost::alignment::is_aligned(Alignment, q)); + BOOST_TEST(boost::alignment::is_aligned(q, Alignment)); BOOST_TEST(n == 1); } } diff --git a/test/align_up_test.cpp b/test/align_up_test.cpp index b4ca7c6..8e7995e 100644 --- a/test/align_up_test.cpp +++ b/test/align_up_test.cpp @@ -16,17 +16,17 @@ void test() { char s[Alignment << 1]; char* b = s; - while (!boost::alignment::is_aligned(Alignment, b)) { + while (!boost::alignment::is_aligned(b, Alignment)) { b++; } { void* p = b; - BOOST_TEST(boost::alignment::align_up(Alignment, p) == p); + BOOST_TEST(boost::alignment::align_up(p, Alignment) == p); } { void* p = &b[Alignment]; void* q = &b[1]; - BOOST_TEST(boost::alignment::align_up(Alignment, q) == p); + BOOST_TEST(boost::alignment::align_up(q, Alignment) == p); } } diff --git a/test/aligned_alloc_test.cpp b/test/aligned_alloc_test.cpp index a75ba0e..aea9242 100644 --- a/test/aligned_alloc_test.cpp +++ b/test/aligned_alloc_test.cpp @@ -18,7 +18,7 @@ void test(std::size_t alignment) void* p = boost::alignment::aligned_alloc(alignment, alignment); BOOST_TEST(p != 0); - BOOST_TEST(boost::alignment::is_aligned(alignment, p)); + BOOST_TEST(boost::alignment::is_aligned(p, alignment)); std::memset(p, 0, 1); boost::alignment::aligned_free(p); } @@ -26,7 +26,7 @@ void test(std::size_t alignment) void* p = boost::alignment::aligned_alloc(alignment, alignment + 1); BOOST_TEST(p != 0); - BOOST_TEST(boost::alignment::is_aligned(alignment, p)); + BOOST_TEST(boost::alignment::is_aligned(p, alignment)); std::memset(p, 0, 1); boost::alignment::aligned_free(p); } @@ -34,7 +34,7 @@ void test(std::size_t alignment) void* p = boost::alignment::aligned_alloc(alignment, alignment - 1); BOOST_TEST(p != 0); - BOOST_TEST(boost::alignment::is_aligned(alignment, p)); + BOOST_TEST(boost::alignment::is_aligned(p, alignment)); std::memset(p, 0, 1); boost::alignment::aligned_free(p); } else { diff --git a/test/aligned_allocator_adaptor_test.cpp b/test/aligned_allocator_adaptor_test.cpp index 375c7d2..ab56cc7 100644 --- a/test/aligned_allocator_adaptor_test.cpp +++ b/test/aligned_allocator_adaptor_test.cpp @@ -84,7 +84,7 @@ void test_allocate() Alignment> a(5); int* p = a.allocate(1); BOOST_TEST(p != 0); - BOOST_TEST(boost::alignment::is_aligned(Alignment, p)); + BOOST_TEST(boost::alignment::is_aligned(p, Alignment)); std::memset(p, 0, 1); a.deallocate(p, 1); } @@ -94,7 +94,7 @@ void test_allocate() int* p1 = a.allocate(1); int* p2 = a.allocate(1, p1); BOOST_TEST(p2 != 0); - BOOST_TEST(boost::alignment::is_aligned(Alignment, p2)); + BOOST_TEST(boost::alignment::is_aligned(p2, Alignment)); std::memset(p2, 0, 1); a.deallocate(p2, 1); a.deallocate(p1, 1); diff --git a/test/aligned_allocator_test.cpp b/test/aligned_allocator_test.cpp index f0e7fb0..022579f 100644 --- a/test/aligned_allocator_test.cpp +++ b/test/aligned_allocator_test.cpp @@ -19,7 +19,7 @@ void test_allocate() boost::alignment::aligned_allocator a; int* p = a.allocate(1); BOOST_TEST(p != 0); - BOOST_TEST(boost::alignment::is_aligned(Alignment, p)); + BOOST_TEST(boost::alignment::is_aligned(p, Alignment)); std::memset(p, 0, 1); a.deallocate(p, 1); } diff --git a/test/assume_aligned_test.cpp b/test/assume_aligned_test.cpp index 3c94f28..b4db1d9 100644 --- a/test/assume_aligned_test.cpp +++ b/test/assume_aligned_test.cpp @@ -14,7 +14,7 @@ void test() { char s[128]; char* p = s; - while (!boost::alignment::is_aligned(128, p)) { + while (!boost::alignment::is_aligned(p, 128)) { p++; } void* q = p; diff --git a/test/is_aligned_test.cpp b/test/is_aligned_test.cpp index eb38c3e..b8739fb 100644 --- a/test/is_aligned_test.cpp +++ b/test/is_aligned_test.cpp @@ -15,17 +15,17 @@ void test() { char s[Alignment << 1]; char* b = s; - while (!boost::alignment::is_aligned(Alignment, b)) { + while (!boost::alignment::is_aligned(b, Alignment)) { b++; } std::size_t n = Alignment; { void* p = &b[n]; - BOOST_TEST(boost::alignment::is_aligned(n, p)); + BOOST_TEST(boost::alignment::is_aligned(p, n)); } if (n > 1) { void* p = &b[1]; - BOOST_TEST(!boost::alignment::is_aligned(n, p)); + BOOST_TEST(!boost::alignment::is_aligned(p, n)); } }