[libcxx-commits] [libcxx] [libc++] Add a compact, bounded iterator (PR #208271)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Thu Sep 10 05:12:03 PDT 2026


================
@@ -0,0 +1,247 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP__STATIC_PACKED_BOUNDED_ITER_H
+#define _LIBCPP__STATIC_PACKED_BOUNDED_ITER_H
+
+#include <__assert>
+#include <__bit/countr.h>
+#include <__compare/ordering.h>
+#include <__compare/three_way_comparable.h>
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__cstddef/size_t.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_pointer.h>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 26
+
+// static_packed_bounded_iter is a bounded, contiguous iterator that is aware of its container's (compile-time) maximum
+// capacity.
+//
+// It packs the bottom bits of the pointer with an offset that tracks the iterator's current position, while
+// also incrementing/decrementing the pointer. This is to minimize the amount of instructions required to retrieve the
+// pointer, at the cost of an additional add instruction when updating.
+//
+// To retrieve the current pointer, we mask off the bottom bits and return the correctly-aligned pointer.
+//
+// This iterator requires that its container's maximum range can fit inside the representable range of
+// the available bottom bits, so (2 ^ available_bits) - 1
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+consteval bool __range_fits_in_alignment(size_t __alignment, size_t __num_elems) {
+  size_t __bits = std::countr_zero(__alignment);
+
+  // Example: For alignof(T) == 4, we have two bits free, which has a range of 0-3. We need to
+  // reserve one for the end position, so __num_elems must be < 3.
+  size_t __allowed_range = (1 << __bits) - 1;
+  return __allowed_range > __num_elems;
+}
+
+template <class _Ptr, size_t _RangeCapacity>
+  requires(is_pointer_v<_Ptr> && std::__range_fits_in_alignment(alignof(iter_value_t<_Ptr>), _RangeCapacity))
+class __static_packed_bounded_iterator {
+public:
+  using iterator_category = iterator_traits<_Ptr>::iterator_category;
+  using iterator_concept  = contiguous_iterator_tag;
+  using difference_type   = iter_difference_t<_Ptr>;
+  using pointer           = iterator_traits<_Ptr>::pointer;
+  using reference         = iter_reference_t<_Ptr>;
+  using value_type        = iter_value_t<_Ptr>;
+
+private:
+  static constexpr uintptr_t __CountMask = (1 << std::countr_zero(alignof(value_type))) - 1;
+  static constexpr uintptr_t __PtrMask   = ~__CountMask;
+
+  union {
+    _Ptr __ptr_;
+    alignas(pointer) uintptr_t __data_;
----------------
philnik777 wrote:

IMO this should really be restricted to raw pointers, since we don't know the representation of fancy pointers. They could use the low bits for their own purposes for all we know.

https://github.com/llvm/llvm-project/pull/208271


More information about the libcxx-commits mailing list