Sources Pipelines Documentation

Allocators  
alignment.ipp
1 // Copyright (c) 2016 Lukasz Laszko
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 #pragma once
6 
7 #include "alignment.hpp"
8 
9 
10 namespace boost { namespace memory {
11 
12 static constexpr bool is_power_of_2(std::size_t x) noexcept
13 {
14  while (((x & 1) == 0) && x > 1)
15  x >>= 1;
16  return (x == 1);
17 }
18 
19 template <>
20 inline constexpr std::uint8_t* align_forward<1>(std::uint8_t* address) noexcept
21 {
22  return address;
23 }
24 
25 template <std::size_t alignment>
26 inline constexpr std::uint8_t* align_forward(std::uint8_t* address) noexcept
27 {
28  static_assert(is_power_of_2(alignment), "alignment must be a power of 2");
29 
30  auto address_ptr = reinterpret_cast<std::uintptr_t>(address);
31  return address_ptr % alignment == 0
32  ? address
33  : reinterpret_cast<std::uint8_t*>(address_ptr + (alignment - (address_ptr % alignment)));
34 }
35 
36 template <>
37 inline constexpr std::uint8_t* align_backward<1>(std::uint8_t* address) noexcept
38 {
39  return address;
40 }
41 
42 template <std::size_t alignment>
43 inline constexpr std::uint8_t* align_backward(std::uint8_t* address) noexcept
44 {
45  static_assert(is_power_of_2(alignment), "alignment must be a power of 2");
46 
47  auto address_ptr = reinterpret_cast<std::uintptr_t>(address);
48  return address_ptr % alignment == 0
49  ? address
50  : reinterpret_cast<std::uint8_t*>(address_ptr - (address_ptr % alignment));
51 }
52 
53 template <>
54 inline constexpr std::size_t align_size<1>(std::size_t size) noexcept
55 {
56  return size;
57 }
58 
59 template <std::size_t alignment>
60 inline constexpr std::size_t align_size(std::size_t size) noexcept
61 {
62  static_assert(is_power_of_2(alignment), "alignment must be a power of 2");
63 
64  return size % alignment == 0
65  ? size
66  : size + (alignment - (size % alignment));
67 }
68 
69 } }
70