20 Memory management library [mem]

20.3 Pointer tagging [ptrtag]

20.3.2 Class template pointer_tag_pair [ptrtag.pair]

20.3.2.1 General [ptrtag.pair.general]

The class template pointer_tag_pair provides a type to store an object pointer together with a tag value.
namespace std { template<class U, class PtrT, unsigned BitsRequested, size_t Alignment = alignof(U)> concept tagging-compatible-pointee = // exposition only convertible_to<U*, PtrT> && pointer_bits_available(Alignment) >= BitsRequested && (is_void_v<element-of<PtrT>> || is_scalar_v<element-of<PtrT>> || is_union_v<element-of<PtrT>> || is_pointer_interconvertible_base_of_v<element-of<PtrT>, U>); template<class TagT> constexpr unsigned tag-bit-width(TagT value) noexcept; // exposition only template<class Ptr, unsigned BitsRequested = bits-available<element-of<Ptr>>, class TagT = unsigned> class pointer_tag_pair { // freestanding public: using pointer_type = Ptr; using element_type = pointer_traits<Ptr>::element_type; using tagged_pointer_type = see below; using tag_type = TagT; static constexpr unsigned bits_requested = BitsRequested; // [ptrtag.pair.cons], constructors constexpr pointer_tag_pair() noexcept; template<tagging-compatible-pointee<pointer_type, bits_requested> U> constexpr pointer_tag_pair(U* p, tag_type t); constexpr pointer_tag_pair(nullptr_t p, tag_type t); // [ptrtag.pair.overalign], support for overaligned pointers template<size_t PromisedAlignment, tagging-compatible-pointee<pointer_type, bits_requested, PromisedAlignment> U> static constexpr pointer_tag_pair from_overaligned(U* p, tag_type t); // [ptrtag.pair.tagops], tagged pointer operations tagged_pointer_type tagged_pointer() const noexcept; static pointer_tag_pair from_tagged(tagged_pointer_type p) noexcept; // [ptrtag.pair.accessors], accessors constexpr pointer_type pointer() const noexcept; constexpr tag_type tag() const noexcept; // [ptrtag.pair.swap], swap constexpr void swap(pointer_tag_pair& o) noexcept; // [ptrtag.pair.comp], comparisons friend constexpr see below operator<=>(pointer_tag_pair lhs, pointer_tag_pair rhs) noexcept requires three_way_comparable<tag_type>; friend constexpr bool operator==(pointer_tag_pair, pointer_tag_pair) noexcept requires equality_comparable<tag_type>; }; template<class Ptr> pointer_tag_pair(Ptr*) -> pointer_tag_pair<Ptr*>; template<class Ptr, class TagT> pointer_tag_pair(Ptr*, TagT tag) -> pointer_tag_pair<Ptr*, bits-available<element-of<Ptr>>, TagT>; }
An object of class pointer_tag_pair<Ptr, BitsRequested, TagT> represents a pair of pointer value of type Ptr and tag value of type TagT.
Each specialization PT of pointer_tag_pair is a trivially copyable type that models copyable such that sizeof(PT) is equal to sizeof(Ptr) and alignof(PT) is equal to alignof(Ptr).
Mandates:
  • is_same_v<remove_cvref_t<Ptr>, Ptr> is true.
  • is_same_v<remove_cvref_t<TagT>, TagT> is true.
  • is_pointer_v<Ptr> && !is_function_v<remove_pointer_t<Ptr>> is true.
  • is_unsigned_v<UT> is true, where UT is underlying_type_t<TagT> if TagT is an enumeration type, and TagT otherwise.
  • sizeof(TagT) <= sizeof(void*) is true.
  • BitsRequested <= max_pointer_bits_available is true.
template<class T> constexpr unsigned tag-bit-width(T v) noexcept;
Returns: static_cast<unsigned>(bit_width(to_underlying(v))) if is_enum_v<T> is true, otherwise static_cast<unsigned>(bit_width(v)).