pstore2
aligned.hpp
Go to the documentation of this file.
1 //===- include/pstore/support/aligned.hpp -----------------*- mode: C++ -*-===//
2 //* _ _ _ *
3 //* __ _| (_) __ _ _ __ ___ __| | *
4 //* / _` | | |/ _` | '_ \ / _ \/ _` | *
5 //* | (_| | | | (_| | | | | __/ (_| | *
6 //* \__,_|_|_|\__, |_| |_|\___|\__,_| *
7 //* |___/ *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
18 
19 #ifndef PSTORE_SUPPORT_ALIGNED_HPP
20 #define PSTORE_SUPPORT_ALIGNED_HPP
21 
22 #include <cstdint>
23 #include <type_traits>
24 
26 
27 namespace pstore {
28 
30  template <typename Ty, typename = typename std::enable_if<std::is_unsigned<Ty>::value>>
31  constexpr bool is_power_of_two (Ty const n) noexcept {
32  // if a number n is a power of 2 then bitwise & of n and n-1 will be zero.
33  return n > 0U && !(n & (n - 1U));
34  }
35 
40  template <typename IntType, typename AlignType>
41  constexpr IntType aligned (IntType const v, AlignType const align) noexcept {
42  static_assert (std::is_unsigned<IntType>::value, "aligned() IntType must be unsigned");
43  static_assert (std::is_unsigned<AlignType>::value, "aligned() AlignType must be unsigned");
44  PSTORE_ASSERT (is_power_of_two (align));
45 
46  return (v + align - 1U) & static_cast<IntType> (~(align - 1U));
47  }
48 
52  template <typename AlignType, typename IntType,
53  typename = std::enable_if<std::is_integral<IntType>::value>>
54  constexpr IntType aligned (IntType const v) noexcept {
55  return aligned (v, alignof (AlignType));
56  }
57 
58  template <typename PointeeType>
59  constexpr PointeeType const * aligned (void const * const p) noexcept {
60  return reinterpret_cast<PointeeType const *> (
61  aligned (reinterpret_cast<std::uintptr_t> (p), alignof (PointeeType)));
62  }
63  template <typename PointeeType>
64  constexpr PointeeType * aligned (void * const p) noexcept {
65  return reinterpret_cast<PointeeType *> (
66  aligned (reinterpret_cast<std::uintptr_t> (p), alignof (PointeeType)));
67  }
68 
69  template <typename DestPointeeType, typename SrcPointeeType = DestPointeeType>
70  constexpr DestPointeeType const * aligned_ptr (SrcPointeeType const * const p) noexcept {
71  return aligned<DestPointeeType> (reinterpret_cast<void const *> (p));
72  }
73  template <typename DestPointeeType, typename SrcPointeeType = DestPointeeType>
74  constexpr DestPointeeType * aligned_ptr (SrcPointeeType * const p) noexcept {
75  return aligned<DestPointeeType> (reinterpret_cast<void *> (p));
76  }
77 
85  template <typename Ty>
86  constexpr Ty calc_alignment (Ty const v, std::size_t const align) noexcept {
87  PSTORE_ASSERT (is_power_of_two (align));
88  return (align == 0U) ? 0U : ((v + align - 1U) & ~(align - 1U)) - v;
89  }
90 
97  template <typename Ty>
98  constexpr Ty calc_alignment (Ty const v) noexcept {
99  return calc_alignment (v, alignof (Ty));
100  }
101 
102 } // end namespace pstore
103 
104 #endif // PSTORE_SUPPORT_ALIGNED_HPP
constexpr Ty calc_alignment(Ty const v, std::size_t const align) noexcept
Calculate the value that must be added to p v in order that it has the alignment given by align...
Definition: aligned.hpp:86
Definition: nonpod2.cpp:40
An implementation of the standard assert() macro with the exception that it will, on failure...
constexpr IntType aligned(IntType const v, AlignType const align) noexcept
Definition: aligned.hpp:41
constexpr bool is_power_of_two(Ty const n) noexcept
Definition: aligned.hpp:31