[libcxx] adds `std::incrementable_traits` to <iterator>

Implements parts of:
    - P0896R4 The One Ranges Proposal

Depends on D99041

Differential Revision: https://reviews.llvm.org/D99141

GitOrigin-RevId: fe31f11cc82135a9f612300a66fd6b80cc3245c3
diff --git a/include/iterator b/include/iterator
index 54ea2aa..c45a1e5 100644
--- a/include/iterator
+++ b/include/iterator
@@ -13,8 +13,11 @@
 /*
     iterator synopsis
 
+#include <concepts>
+
 namespace std
 {
+template<class> struct incrementable_traits; // since C++20
 
 template<class Iterator>
 struct iterator_traits
@@ -425,6 +428,7 @@
 #include <__memory/base.h>
 #include <__memory/pointer_traits.h>
 #include <version>
+#include <concepts>
 
 #include <__debug>
 
@@ -433,6 +437,43 @@
 #endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+// [incrementable.traits]
+template<class> struct incrementable_traits {};
+
+template<class _Tp>
+requires is_object_v<_Tp>
+struct incrementable_traits<_Tp*> {
+  using difference_type = ptrdiff_t;
+};
+
+template<class _Ip>
+struct incrementable_traits<const _Ip> : incrementable_traits<_Ip> {};
+
+template<class _Tp>
+concept __has_member_difference_type = requires { typename _Tp::difference_type; };
+
+template<__has_member_difference_type _Tp>
+struct incrementable_traits<_Tp> {
+  using difference_type = typename _Tp::difference_type;
+};
+
+template<class _Tp>
+concept __has_integral_minus =
+  !__has_member_difference_type<_Tp> &&
+  requires(const _Tp& __x, const _Tp& __y) {
+    { __x - __y } -> integral;
+  };
+
+template<__has_integral_minus _Tp>
+struct incrementable_traits<_Tp> {
+  using difference_type = make_signed_t<decltype(declval<_Tp>() - declval<_Tp>())>;
+};
+
+// TODO(cjdb): add iter_difference_t once iterator_traits is cleaned up.
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
 template <class _Iter>
 struct _LIBCPP_TEMPLATE_VIS iterator_traits;