tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
pointer_int_pair_info.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch
3
4#ifndef TETL_MEMORY_POINTER_INT_PAIR_INFO_HPP
5#define TETL_MEMORY_POINTER_INT_PAIR_INFO_HPP
6
7#include <etl/_bit/bit_cast.hpp>
8#include <etl/_cstdint/intptr_t.hpp>
9#include <etl/_cstdint/uintptr_t.hpp>
10#include <etl/_limits/numeric_limits.hpp>
11#include <etl/_memory/pointer_traits.hpp>
12
13namespace etl {
14
15template <typename PointerT, unsigned IntBits, typename PtrTraits>
17 // clang-format off
18 static_assert(PtrTraits::free_bits < numeric_limits<etl::uintptr_t>::digits, "cannot use a pointer type that has all bits free");
19 static_assert(IntBits <= PtrTraits::free_bits, "pointer_int_pair with integer size too large for pointer");
20 // clang-format on
21
22 using pointer_type = PointerT;
23 using pointer_traits = PtrTraits;
24 static constexpr auto int_bits = IntBits;
25 static constexpr auto free_bits = pointer_traits::free_bits;
26
27 /// \brief The bits that come from the pointer.
28 static constexpr auto ptr_mask = ~static_cast<etl::uintptr_t>((static_cast<etl::intptr_t>(1) << free_bits) - 1);
29
30 /// \brief The number of low bits that we reserve for other uses; and keep
31 /// zero.
32 static constexpr auto int_shift = static_cast<etl::uintptr_t>(pointer_traits::free_bits - int_bits);
33
34 /// \brief This is the unshifted mask for valid bits of the int
35 /// type.
36 static constexpr auto int_mask = static_cast<etl::uintptr_t>((static_cast<etl::intptr_t>(1) << int_bits) - 1);
37
38 /// \brief This is the bits for the integer shifted in place.
39 static constexpr auto shifted_int_mask = static_cast<etl::uintptr_t>(int_mask << int_shift);
40
41 [[nodiscard]] static auto get_pointer(etl::intptr_t value) -> pointer_type
42 {
43 return pointer_traits::get_from_void_pointer(
44 etl::bit_cast<void*>(static_cast<etl::uintptr_t>(value) & ptr_mask)
45 );
46 }
47
48 [[nodiscard]] static auto get_int(etl::intptr_t value) -> etl::intptr_t
49 {
50 return (static_cast<etl::uintptr_t>(value) >> int_shift) & int_mask;
51 }
52
53 [[nodiscard]] static auto update_ptr(etl::intptr_t value, pointer_type ptr) -> etl::intptr_t
54 {
55 // Preserve all low bits, just update the pointer.
56 auto* voidPtr = pointer_traits::get_as_void_pointer(ptr);
57 auto ptrWord = etl::bit_cast<etl::uintptr_t>(voidPtr);
58 return static_cast<etl::intptr_t>(ptrWord | (static_cast<etl::uintptr_t>(value) & ~ptr_mask));
59 }
60
61 [[nodiscard]] static auto update_int(etl::intptr_t value, etl::intptr_t integer) -> etl::intptr_t
62 {
63 // Preserve all bits other than the ones we are updating.
64 auto const uinteger = static_cast<etl::uintptr_t>(integer);
65 return static_cast<etl::intptr_t>(
66 (static_cast<etl::uintptr_t>(value) & ~shifted_int_mask) | uinteger << int_shift
67 );
68 }
69};
70
71} // namespace etl
72
73#endif // TETL_MEMORY_POINTER_INT_PAIR_INFO_HPP
constexpr auto bit_cast(From const &src) noexcept -> To
Obtain a value of type To by reinterpreting the object representation of from. Every bit in the value...
Definition bit_cast.hpp:39
Definition adjacent_find.hpp:9
static constexpr int digits
Definition numeric_limits.hpp:829
Definition numeric_limits.hpp:18
Definition pointer_int_pair_info.hpp:16
static constexpr auto int_mask
This is the unshifted mask for valid bits of the int type.
Definition pointer_int_pair_info.hpp:36
static constexpr auto int_bits
Definition pointer_int_pair_info.hpp:24
static constexpr auto free_bits
Definition pointer_int_pair_info.hpp:25
static auto update_ptr(etl::intptr_t value, pointer_type ptr) -> etl::intptr_t
Definition pointer_int_pair_info.hpp:53
static constexpr auto ptr_mask
The bits that come from the pointer.
Definition pointer_int_pair_info.hpp:28
static auto update_int(etl::intptr_t value, etl::intptr_t integer) -> etl::intptr_t
Definition pointer_int_pair_info.hpp:61
static constexpr auto int_shift
The number of low bits that we reserve for other uses; and keep zero.
Definition pointer_int_pair_info.hpp:32
static constexpr auto shifted_int_mask
This is the bits for the integer shifted in place.
Definition pointer_int_pair_info.hpp:39
static auto get_int(etl::intptr_t value) -> etl::intptr_t
Definition pointer_int_pair_info.hpp:48
static auto get_pointer(etl::intptr_t value) -> pointer_type
Definition pointer_int_pair_info.hpp:41