File indexing completed on 2024-12-01 10:29:53

0001 /*
0002     SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef OSM_INTERNAL_H
0008 #define OSM_INTERNAL_H
0009 
0010 #include <cstdint>
0011 
0012 namespace OSM {
0013 
0014 namespace Internal {
0015 /** Pointer with the lower bits used for compact flag storage. */
0016 template <typename T> class TaggedPointer
0017 {
0018 public:
0019     explicit inline constexpr TaggedPointer() = default;
0020     explicit inline constexpr TaggedPointer(T *ptr, uint8_t tag)
0021         : m_data(reinterpret_cast<std::uintptr_t>(ptr) | (tag & TagMask))
0022     {}
0023 
0024     constexpr inline T* get() const { return reinterpret_cast<T*>(m_data & ~TagMask); }
0025     constexpr inline void set(T *data) { m_data = (m_data & TagMask) | (reinterpret_cast<std::uintptr_t>(data) & ~TagMask); }
0026     constexpr inline uint8_t tag() const { return m_data & TagMask; }
0027     constexpr inline void setTag(uint8_t tag) { m_data = (tag & TagMask) | (m_data & ~TagMask); }
0028     constexpr inline operator bool() const { return (m_data & ~TagMask); }
0029     constexpr inline bool operator==(TaggedPointer<T> other) const { return m_data == other.m_data; }
0030     constexpr inline bool operator!=(TaggedPointer<T> other) const { return m_data != other.m_data; }
0031     constexpr inline bool operator<(TaggedPointer<T> other) const { return m_data < other.m_data; }
0032 
0033 private:
0034     enum { TagMask = 0x3 };
0035     std::uintptr_t m_data = 0;
0036 };
0037 
0038 }
0039 }
0040 
0041 #endif