PtrInt data structure (Pointer Integer pair inside one pointer location). Part of T150
Summary: PtrInt data structure (Pointer Integer pair inside one pointer location). Part of T150 Test Plan: manual Reviewers: sale Subscribers: buda, sale Differential Revision: https://memgraph.phacility.com/D11
This commit is contained in:
parent
a621370270
commit
6355dd4f4d
54
include/data_structures/ptr_int.hpp
Normal file
54
include/data_structures/ptr_int.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include "utils/numerics/log2.hpp"
|
||||
|
||||
template <typename PtrT>
|
||||
struct PointerPackTraits
|
||||
{
|
||||
// here is a place to embed something like platform specific things
|
||||
// TODO: cover more cases
|
||||
constexpr static int free_bits = utils::log2(alignof(PtrT));
|
||||
|
||||
static auto get_ptr(uintptr_t value) { return (PtrT)(value); }
|
||||
};
|
||||
|
||||
template <typename PtrT, int IntBits, typename IntT = unsigned,
|
||||
typename PtrTraits = PointerPackTraits<PtrT>>
|
||||
class PtrInt
|
||||
{
|
||||
private:
|
||||
constexpr static int int_shift = PtrTraits::free_bits - IntBits;
|
||||
constexpr static uintptr_t ptr_mask =
|
||||
~(uintptr_t)(((intptr_t)1 << PtrTraits::free_bits) - 1);
|
||||
constexpr static uintptr_t int_mask =
|
||||
(uintptr_t)(((intptr_t)1 << IntBits) - 1);
|
||||
|
||||
uintptr_t value {0};
|
||||
|
||||
public:
|
||||
PtrInt(PtrT pointer, IntT integer)
|
||||
{
|
||||
set_ptr(pointer);
|
||||
set_int(integer);
|
||||
}
|
||||
|
||||
auto set_ptr(PtrT pointer)
|
||||
{
|
||||
auto integer = static_cast<uintptr_t>(get_int());
|
||||
auto ptr = reinterpret_cast<uintptr_t>(pointer);
|
||||
value = (ptr_mask & ptr) | (integer << int_shift);
|
||||
}
|
||||
|
||||
auto set_int(IntT integer)
|
||||
{
|
||||
auto ptr = reinterpret_cast<uintptr_t>(get_ptr());
|
||||
auto int_shifted = static_cast<uintptr_t>(integer << int_shift);
|
||||
value = (int_mask & int_shifted) | ptr;
|
||||
}
|
||||
|
||||
auto get_ptr() const { return PtrTraits::get_ptr(value & ptr_mask); }
|
||||
|
||||
auto get_int() const { return (IntT)((value >> int_shift) & int_mask); }
|
||||
};
|
10
include/utils/numerics/log2.hpp
Normal file
10
include/utils/numerics/log2.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
|
||||
constexpr size_t log2(size_t n) { return ((n < 2) ? 0 : 1 + log2(n >> 1)); }
|
||||
|
||||
}
|
20
tests/unit/ptr_int.cpp
Normal file
20
tests/unit/ptr_int.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "data_structures/ptr_int.hpp"
|
||||
|
||||
TEST_CASE("Construct and read pointer integer pair type")
|
||||
{
|
||||
auto ptr1 = std::make_unique<int>(2);
|
||||
PtrInt<int *, 2, int> pack1(ptr1.get(), 1);
|
||||
|
||||
REQUIRE(pack1.get_int() == 1);
|
||||
REQUIRE(pack1.get_ptr() == ptr1.get());
|
||||
|
||||
|
||||
auto ptr2 = std::make_unique<int>(2);
|
||||
PtrInt<int *, 3, int> pack2(ptr2.get(), 2);
|
||||
|
||||
REQUIRE(pack2.get_int() == 2);
|
||||
REQUIRE(pack2.get_ptr() == ptr2.get());
|
||||
}
|
Loading…
Reference in New Issue
Block a user