diff --git a/base/containers/checked_iterators.h b/base/containers/checked_iterators.h index 5c8292bd68a2a4..b67a2db4bfa3be 100644 --- a/base/containers/checked_iterators.h +++ b/base/containers/checked_iterators.h @@ -24,6 +24,9 @@ class CheckedContiguousIterator { using pointer = T*; using reference = T&; using iterator_category = std::random_access_iterator_tag; +#if __cplusplus >= 202002L + using iterator_concept = std::contiguous_iterator_tag; +#endif // Required for converting constructor below. template @@ -239,14 +242,34 @@ using CheckedContiguousConstIterator = CheckedContiguousIterator; // [1] https://wg21.link/iterator.concept.contiguous // [2] https://wg21.link/std.iterator.tags // [3] https://wg21.link/pointer.traits.optmem -namespace std { #if defined(_LIBCPP_VERSION) + +// TODO(crbug.com/1284275): Remove when C++20 is on by default, as the use +// of `iterator_concept` above should suffice. +_LIBCPP_BEGIN_NAMESPACE_STD + +// TODO(crbug.com/1449299): https://reviews.llvm.org/D150801 renamed this from +// `__is_cpp17_contiguous_iterator` to `__libcpp_is_contiguous_iterator`. Clean +// up the old spelling after libc++ rolls. +template +struct __is_cpp17_contiguous_iterator; template struct __is_cpp17_contiguous_iterator<::base::CheckedContiguousIterator> : true_type {}; + +template +struct __libcpp_is_contiguous_iterator; +template +struct __libcpp_is_contiguous_iterator<::base::CheckedContiguousIterator> + : true_type {}; + +_LIBCPP_END_NAMESPACE_STD + #endif +namespace std { + template struct pointer_traits<::base::CheckedContiguousIterator> { using pointer = ::base::CheckedContiguousIterator; diff --git a/base/containers/checked_iterators_unittest.cc b/base/containers/checked_iterators_unittest.cc index 4d7cffa1630314..07e628a10bafbd 100644 --- a/base/containers/checked_iterators_unittest.cc +++ b/base/containers/checked_iterators_unittest.cc @@ -85,11 +85,8 @@ TEST(CheckedContiguousIterator, ConvertingComparisonOperators) { } // namespace base -// ChromeOS does not use the in-tree libc++, but rather a shared library that -// lags a bit behind. -// TODO(crbug.com/1166360): Enable this test on ChromeOS once the shared libc++ -// is sufficiently modern. -#if defined(_LIBCPP_VERSION) && !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_CHROMEOS) +#if defined(_LIBCPP_VERSION) + namespace { // Helper template that wraps an iterator and disables its dereference and @@ -101,6 +98,8 @@ namespace { template struct DisableDerefAndIncr : Iterator { using Iterator::Iterator; + + // NOLINTNEXTLINE(google-explicit-constructor) constexpr DisableDerefAndIncr(const Iterator& iter) : Iterator(iter) {} constexpr typename Iterator::reference operator*() { @@ -121,16 +120,28 @@ struct DisableDerefAndIncr : Iterator { } // namespace -// Inherit `__is_cpp17_contiguous_iterator` and `pointer_traits` specializations -// from the base class. -namespace std { +// Inherit `__libcpp_is_contiguous_iterator` and `pointer_traits` +// specializations from the base class. + +// TODO(crbug.com/1284275): Remove when C++20 is on by default, as the use +// of `iterator_concept` should suffice. +_LIBCPP_BEGIN_NAMESPACE_STD + +// TODO(crbug.com/1449299): https://reviews.llvm.org/D150801 renamed this from +// `__is_cpp17_contiguous_iterator` to `__libcpp_is_contiguous_iterator`. Clean +// up the old spelling after libc++ rolls. template struct __is_cpp17_contiguous_iterator> : __is_cpp17_contiguous_iterator {}; +template +struct __libcpp_is_contiguous_iterator> + : __libcpp_is_contiguous_iterator {}; + template struct pointer_traits> : pointer_traits {}; -} // namespace std + +_LIBCPP_END_NAMESPACE_STD namespace base {