[libcxx-commits] [libcxx] [String] Allow fancy pointer as pointer type of basic_string allocator (PR #191023)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Apr 11 02:48:36 PDT 2026
================
@@ -444,6 +445,235 @@ TEST_CONSTEXPR_CXX20 thread_unsafe_shared_ptr<T> make_thread_unsafe_shared(Args.
}
} // namespace detail
+template <class T>
+class fancy_pointer {
+public:
+ // For the std::pointer_traits interface.
+ using pointer = T*;
+ using element_type = T;
+ using difference_type = std::ptrdiff_t;
+
+ template <class U>
+ using rebind = fancy_pointer<U>;
+
+ // For the std::iterator_traits interface.
+ using value_type = typename std::remove_cv<T>::type;
+ using reference = typename std::add_lvalue_reference<T>::type;
+ using iterator_category = std::random_access_iterator_tag;
+
+ TEST_CONSTEXPR_CXX14 fancy_pointer() TEST_NOEXCEPT : ptr_(nullptr) {}
+ TEST_CONSTEXPR_CXX14 fancy_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
+
+ template <typename T2>
+ TEST_CONSTEXPR_CXX14 explicit fancy_pointer(const fancy_pointer<T2>& other) TEST_NOEXCEPT
+ : ptr_(static_cast<T*>(other.get())) {}
+
+ TEST_CONSTEXPR_CXX14 operator T*() const TEST_NOEXCEPT { return ptr_; }
+ TEST_CONSTEXPR_CXX14 fancy_pointer(fancy_pointer&&) TEST_NOEXCEPT = default;
+ TEST_CONSTEXPR_CXX14 fancy_pointer(const fancy_pointer&) TEST_NOEXCEPT = default;
+ TEST_CONSTEXPR_CXX14 fancy_pointer& operator=(fancy_pointer&&) TEST_NOEXCEPT = default;
+ TEST_CONSTEXPR_CXX14 fancy_pointer& operator=(const fancy_pointer&) TEST_NOEXCEPT = default;
+ TEST_CONSTEXPR_CXX20 ~fancy_pointer() TEST_NOEXCEPT = default;
+ TEST_CONSTEXPR_CXX14 operator fancy_pointer<const T>() const TEST_NOEXCEPT { return fancy_pointer<const T>(get()); }
+ TEST_CONSTEXPR_CXX14 T& operator*() const TEST_NOEXCEPT { return *ptr_; }
+ TEST_CONSTEXPR_CXX14 T* operator->() const TEST_NOEXCEPT { return ptr_; }
+ TEST_CONSTEXPR_CXX14 explicit operator bool() const TEST_NOEXCEPT { return ptr_; }
+ TEST_CONSTEXPR_CXX14 T* get() const TEST_NOEXCEPT { return ptr_; }
+
+ TEST_CONSTEXPR_CXX14 fancy_pointer& operator++() TEST_NOEXCEPT {
+ ++ptr_;
+ return *this;
+ }
+ TEST_CONSTEXPR_CXX14 fancy_pointer operator++(int) TEST_NOEXCEPT {
+ fancy_pointer tmp(*this);
+ ++ptr_;
+ return tmp;
+ }
+
+ TEST_CONSTEXPR_CXX14 fancy_pointer& operator--() TEST_NOEXCEPT {
+ --ptr_;
+ return *this;
+ }
+ TEST_CONSTEXPR_CXX14 fancy_pointer operator--(int) TEST_NOEXCEPT {
+ fancy_pointer tmp(*this);
+ --ptr_;
+ return tmp;
+ }
+
+ TEST_CONSTEXPR_CXX14 fancy_pointer& operator+=(difference_type n) TEST_NOEXCEPT {
+ ptr_ += n;
+ return *this;
+ }
+
+ TEST_CONSTEXPR_CXX14 fancy_pointer& operator-=(difference_type n) TEST_NOEXCEPT {
+ ptr_ -= n;
+ return *this;
+ }
+
+ TEST_CONSTEXPR_CXX14 fancy_pointer operator+(difference_type n) const TEST_NOEXCEPT {
+ fancy_pointer tmp(*this);
+ tmp += n;
+ return tmp;
+ }
+
+ TEST_CONSTEXPR_CXX14 fancy_pointer operator-(difference_type n) const TEST_NOEXCEPT {
+ fancy_pointer tmp(*this);
+ tmp -= n;
+ return tmp;
+ }
+
+ TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const TEST_NOEXCEPT { return ptr_[n]; }
+
+ friend TEST_CONSTEXPR_CXX14 fancy_pointer operator+(difference_type x, fancy_pointer y) TEST_NOEXCEPT {
+ return y + x;
+ }
+
+ friend TEST_CONSTEXPR_CXX14 bool operator<(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return x.ptr_ < y.ptr_; }
+ friend TEST_CONSTEXPR_CXX14 bool operator>(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return y < x; }
+ friend TEST_CONSTEXPR_CXX14 bool operator<=(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return !(y < x); }
+ friend TEST_CONSTEXPR_CXX14 bool operator>=(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return !(x < y); }
+
+ static TEST_CONSTEXPR_CXX14 fancy_pointer pointer_to(reference ref) TEST_NOEXCEPT { return fancy_pointer(&ref); }
+
+ T* ptr_;
+};
+
+template <>
+class fancy_pointer<void> {
+public:
+ using T = void;
+
+ // For the std::pointer_traits interface.
+ using pointer = T*;
+ using element_type = T;
+ using difference_type = std::ptrdiff_t;
+
+ template <class U>
+ using rebind = fancy_pointer<U>;
+
+ // For the std::iterator_traits interface.
+ using value_type = typename std::remove_cv<T>::type;
+ using reference = typename std::add_lvalue_reference<T>::type;
+ using iterator_category = std::random_access_iterator_tag;
+
+ TEST_CONSTEXPR_CXX14 fancy_pointer() TEST_NOEXCEPT : ptr_(nullptr) {}
+ TEST_CONSTEXPR_CXX14 fancy_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
+
+ template <typename T2>
+ TEST_CONSTEXPR_CXX14 explicit fancy_pointer(const fancy_pointer<T2>& other) TEST_NOEXCEPT : ptr_(other.get()) {}
+
+ TEST_CONSTEXPR_CXX14 operator T*() const TEST_NOEXCEPT { return ptr_; }
+ TEST_CONSTEXPR_CXX14 fancy_pointer(fancy_pointer&&) TEST_NOEXCEPT = default;
+ TEST_CONSTEXPR_CXX14 fancy_pointer(const fancy_pointer&) TEST_NOEXCEPT = default;
+ TEST_CONSTEXPR_CXX14 fancy_pointer& operator=(fancy_pointer&&) TEST_NOEXCEPT = default;
+ TEST_CONSTEXPR_CXX14 fancy_pointer& operator=(const fancy_pointer&) TEST_NOEXCEPT = default;
+ TEST_CONSTEXPR_CXX20 ~fancy_pointer() TEST_NOEXCEPT = default;
----------------
frederick-vs-ja wrote:
Ditto, `TEST_CONSTEXPR_CXX20` and non-trivial special member functions.
https://github.com/llvm/llvm-project/pull/191023
More information about the libcxx-commits
mailing list