File: align.hpp

package info (click to toggle)
foonathan-memory 0.7.4-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,644 kB
  • sloc: cpp: 12,425; xml: 139; sh: 48; makefile: 25
file content (58 lines) | stat: -rw-r--r-- 2,284 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// Copyright (C) 2015-2025 Jonathan Müller and foonathan/memory contributors
// SPDX-License-Identifier: Zlib

#ifndef FOONATHAN_MEMORY_DETAIL_ALIGN_HPP_INCLUDED
#define FOONATHAN_MEMORY_DETAIL_ALIGN_HPP_INCLUDED

#include <cstdint>

#include "../config.hpp"
#include "assert.hpp"

namespace foonathan
{
    namespace memory
    {
        namespace detail
        {
            // whether or not an alignment is valid, i.e. a power of two not zero
            constexpr bool is_valid_alignment(std::size_t alignment) noexcept
            {
                return alignment && (alignment & (alignment - 1)) == 0u;
            }

            constexpr std::size_t round_up_to_multiple_of_alignment(std::size_t size,
                                                                    std::size_t alignment) noexcept
            {
                FOONATHAN_MEMORY_ASSERT(is_valid_alignment(alignment));
                return (size + alignment - 1) & ~(alignment - 1);
            }

            // returns the offset needed to align ptr for given alignment
            // alignment must be valid
            inline std::size_t align_offset(std::uintptr_t address, std::size_t alignment) noexcept
            {
                FOONATHAN_MEMORY_ASSERT(is_valid_alignment(alignment));
                auto misaligned = address & (alignment - 1);
                return misaligned != 0 ? (alignment - misaligned) : 0;
            }
            inline std::size_t align_offset(void* ptr, std::size_t alignment) noexcept
            {
                return align_offset(reinterpret_cast<std::uintptr_t>(ptr), alignment);
            }

            // whether or not the pointer is aligned for given alignment
            // alignment must be valid
            bool is_aligned(void* ptr, std::size_t alignment) noexcept;

            // maximum alignment value
            constexpr std::size_t max_alignment = alignof(std::max_align_t);
            static_assert(is_valid_alignment(max_alignment), "ehm..?");

            // returns the minimum alignment required for a node of given size
            std::size_t alignment_for(std::size_t size) noexcept;
        } // namespace detail
    } // namespace memory
} // namespace foonathan

#endif // FOONATHAN_MEMORY_DETAIL_ALIGN_HPP_INCLUDED