tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
pointer_int_pair.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_HPP
5#define TETL_MEMORY_POINTER_INT_PAIR_HPP
6
7#include <etl/_bit/bit_cast.hpp>
8#include <etl/_cstdint/intptr_t.hpp>
9#include <etl/_memory/pointer_int_pair_info.hpp>
10#include <etl/_memory/pointer_like_traits.hpp>
11
12namespace etl {
13
14/// \brief This struct implements a pair of a pointer and small integer. It is
15/// designed to represent this in the space required by one pointer by
16/// bitmangling the integer into the low part of the pointer. This can only be
17/// done for small integers: typically up to 3 bits, but it depends on the
18/// number of bits available according to pointer_like_traits for the type.
19///
20/// \details Note that pointer_int_pair always puts the IntVal part in the
21/// highest bits possible. For example, pointer_int_pair<void*, 1, bool> will
22/// put the bit for the bool into bit #2, not bit #0, which allows the low two
23/// bits to be used for something else. For example, this allows:
24/// pointer_int_pair<pointer_int_pair<void*, 1, bool>, 1, bool>
25/// ... and the two bools will land in different bits.
26///
27/// \include memory.cpp
28template <
29 typename PointerT,
30 unsigned IntBits,
31 typename IntType = unsigned,
32 typename PtrTraits = pointer_like_traits<PointerT>,
33 typename Info = pointer_int_pair_info<PointerT, IntBits, PtrTraits>
34>
36 using pointer_type = PointerT;
37 using pointer_traits = PtrTraits;
38 using pointer_info = Info;
39 using int_type = IntType;
40 static constexpr auto int_bits = IntBits;
41
42 constexpr pointer_int_pair() = default;
43
44 pointer_int_pair(pointer_type pointerValue, int_type intValue)
45 {
46 set_ptr_and_int(pointerValue, intValue);
47 }
48
49 explicit pointer_int_pair(pointer_type pointerValue)
50 {
51 init_with_ptr(pointerValue);
52 }
53
54 void set_pointer(pointer_type pointerValue)
55 {
56 _value = pointer_info::update_ptr(_value, pointerValue);
57 }
58
59 void set_int(int_type intValue)
60 {
61 _value = pointer_info::update_int(_value, static_cast<intptr_t>(intValue));
62 }
63
64 [[nodiscard]] auto get_pointer() const -> pointer_type
65 {
66 return pointer_info::get_pointer(_value);
67 }
68
69 [[nodiscard]] auto get_int() const -> int_type
70 {
71 return static_cast<int_type>(pointer_info::get_int(_value));
72 }
73
74 void set_ptr_and_int(pointer_type pointerValue, int_type intValue)
75 {
76 _value = pointer_info::update_int(pointer_info::update_ptr(0, pointerValue), static_cast<intptr_t>(intValue));
77 }
78
79 [[nodiscard]] auto get_addr_of_pointer() const -> pointer_type const*
80 {
81 return const_cast<pointer_int_pair*>(this)->get_addr_of_pointer();
82 }
83
84 auto get_addr_of_pointer() -> pointer_type*
85 {
86 return bit_cast<pointer_type*>(&_value);
87 }
88
89 [[nodiscard]] auto get_opaque_value() const -> void*
90 {
91 return bit_cast<void*>(_value);
92 }
93
94 void set_from_opaque_value(void* val)
95 {
96 _value = bit_cast<intptr_t>(val);
97 }
98
100 {
102 p.set_from_opaque_value(v);
103 return p;
104 }
105
106 /// \brief Allow pointer_int_pairs to be created from const void * if and
107 /// only if the pointer type could be created from a const void *.
108 static auto get_from_opaque_value(void const* v) -> pointer_int_pair
109 {
110 (void)pointer_traits::get_from_void_pointer(v);
111 return get_from_opaque_value(const_cast<void*>(v));
112 }
113
114 [[nodiscard]] friend auto operator==(pointer_int_pair const& lhs, pointer_int_pair const& rhs) -> bool
115 {
116 return lhs._value == rhs._value;
117 }
118
119 [[nodiscard]] friend auto operator!=(pointer_int_pair const& lhs, pointer_int_pair const& rhs) -> bool
120 {
121 return lhs._value != rhs._value;
122 }
123
124 [[nodiscard]] friend auto operator<(pointer_int_pair const& lhs, pointer_int_pair const& rhs) -> bool
125 {
126 return lhs._value < rhs._value;
127 }
128
129 [[nodiscard]] friend auto operator>(pointer_int_pair const& lhs, pointer_int_pair const& rhs) -> bool
130 {
131 return lhs._value > rhs._value;
132 }
133
134 [[nodiscard]] friend auto operator<=(pointer_int_pair const& lhs, pointer_int_pair const& rhs) -> bool
135 {
136 return lhs._value <= rhs._value;
137 }
138
139 [[nodiscard]] friend auto operator>=(pointer_int_pair const& lhs, pointer_int_pair const& rhs) -> bool
140 {
141 return lhs._value >= rhs._value;
142 }
143
144private:
145 auto init_with_ptr(pointer_type pointerValue) -> void
146 {
147 _value = pointer_info::update_ptr(0, pointerValue);
148 }
149
150 intptr_t _value = 0;
151};
152
153template <typename PtrT, unsigned IntBits, typename IntT, typename PtrTraits>
154struct pointer_like_traits<pointer_int_pair<PtrT, IntBits, IntT, PtrTraits>> {
155 static auto get_as_void_pointer(pointer_int_pair<PtrT, IntBits, IntT> const& p) -> void*
156 {
157 return p.get_opaque_value();
158 }
159
160 static auto get_from_void_pointer(void* p) -> pointer_int_pair<PtrT, IntBits, IntT>
161 {
162 return pointer_int_pair<PtrT, IntBits, IntT>::get_from_opaque_value(p);
163 }
164
165 static auto get_from_void_pointer(void const* p) -> pointer_int_pair<PtrT, IntBits, IntT>
166 {
167 return pointer_int_pair<PtrT, IntBits, IntT>::get_from_opaque_value(p);
168 }
169
170 static constexpr size_t free_bits = PtrTraits::free_bits - IntBits;
171};
172
173} // namespace etl
174
175#endif // TETL_MEMORY_POINTER_INT_PAIR_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
Definition pointer_int_pair_info.hpp:16
This struct implements a pair of a pointer and small integer. It is designed to represent this in the...
Definition pointer_int_pair.hpp:35
void set_from_opaque_value(void *val)
Definition pointer_int_pair.hpp:94
friend auto operator>=(pointer_int_pair const &lhs, pointer_int_pair const &rhs) -> bool
Definition pointer_int_pair.hpp:139
void set_ptr_and_int(pointer_type pointerValue, int_type intValue)
Definition pointer_int_pair.hpp:74
static constexpr auto int_bits
Definition pointer_int_pair.hpp:40
pointer_int_pair(pointer_type pointerValue)
Definition pointer_int_pair.hpp:49
auto get_addr_of_pointer() -> pointer_type *
Definition pointer_int_pair.hpp:84
auto get_pointer() const -> pointer_type
Definition pointer_int_pair.hpp:64
friend auto operator<=(pointer_int_pair const &lhs, pointer_int_pair const &rhs) -> bool
Definition pointer_int_pair.hpp:134
auto get_addr_of_pointer() const -> pointer_type const *
Definition pointer_int_pair.hpp:79
void set_pointer(pointer_type pointerValue)
Definition pointer_int_pair.hpp:54
friend auto operator<(pointer_int_pair const &lhs, pointer_int_pair const &rhs) -> bool
Definition pointer_int_pair.hpp:124
auto get_int() const -> int_type
Definition pointer_int_pair.hpp:69
constexpr pointer_int_pair()=default
friend auto operator>(pointer_int_pair const &lhs, pointer_int_pair const &rhs) -> bool
Definition pointer_int_pair.hpp:129
static auto get_from_opaque_value(void const *v) -> pointer_int_pair
Allow pointer_int_pairs to be created from const void * if and only if the pointer type could be crea...
Definition pointer_int_pair.hpp:108
pointer_int_pair(pointer_type pointerValue, int_type intValue)
Definition pointer_int_pair.hpp:44
static auto get_from_opaque_value(void *v) -> pointer_int_pair
Definition pointer_int_pair.hpp:99
friend auto operator!=(pointer_int_pair const &lhs, pointer_int_pair const &rhs) -> bool
Definition pointer_int_pair.hpp:119
void set_int(int_type intValue)
Definition pointer_int_pair.hpp:59
friend auto operator==(pointer_int_pair const &lhs, pointer_int_pair const &rhs) -> bool
Definition pointer_int_pair.hpp:114
auto get_opaque_value() const -> void *
Definition pointer_int_pair.hpp:89
static auto get_as_void_pointer(pointer_int_pair< PtrT, IntBits, IntT > const &p) -> void *
Definition pointer_int_pair.hpp:155
static constexpr size_t free_bits
Definition pointer_int_pair.hpp:170
static auto get_from_void_pointer(void const *p) -> pointer_int_pair< PtrT, IntBits, IntT >
Definition pointer_int_pair.hpp:165
static auto get_from_void_pointer(void *p) -> pointer_int_pair< PtrT, IntBits, IntT >
Definition pointer_int_pair.hpp:160