// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_CONTAINERS_CONTIGUOUS_ITERATOR_H_ #define BASE_CONTAINERS_CONTIGUOUS_ITERATOR_H_ #include #include #include #include #include #include "base/containers/checked_iterators.h" #include "base/template_util.h" namespace base { namespace internal { template struct PointsToObject : std::is_object> {}; // A pointer is a contiguous iterator. // Reference: https://wg21.link/iterator.traits#5 template struct IsPointer : std::is_pointer {}; template >> struct IsStringIterImpl : disjunction, std::is_same> {}; // An iterator to std::basic_string is contiguous. // Reference: https://wg21.link/basic.string.general#2 // // Note: Requires indirection via `IsStringIterImpl` to avoid triggering a // `static_assert(is_trivial_v)` inside libc++'s std::basic_string. template struct IsStringIter : conjunction>, IsStringIterImpl> {}; // An iterator to std::array is contiguous. // Reference: https://wg21.link/array.overview#1 template , Num>> struct IsArrayIterImpl : disjunction, std::is_same> {}; template struct IsArrayIter : disjunction, IsArrayIterImpl, IsArrayIterImpl, IsArrayIterImpl, IsArrayIterImpl> {}; // An iterator to a non-bool std::vector is contiguous. // Reference: https://wg21.link/vector.overview#2 template >> struct IsVectorIter : conjunction, bool>>, disjunction, std::is_same>> {}; // The result of passing a std::valarray to std::begin is a contiguous iterator. // Note: Since all common standard library implementations (i.e. libc++, // stdlibc++ and MSVC's STL) just use a pointer here, we perform a similar // optimization. The corresponding unittest still ensures that this is working // as intended. // Reference: https://wg21.link/valarray.range#1 template struct IsValueArrayIter : std::is_pointer {}; // base's CheckedContiguousIterator is a contiguous iterator. template > struct IsCheckedContiguousIter : disjunction>, std::is_same>> {}; // Check that the iterator points to an actual object, and is one of the // iterator types mentioned above. template struct IsContiguousIteratorImpl : conjunction, disjunction, IsStringIter, IsArrayIter, IsVectorIter, IsValueArrayIter, IsCheckedContiguousIter>> {}; } // namespace internal // IsContiguousIterator is a type trait that determines whether a given type is // a contiguous iterator. It is similar to C++20's contiguous_iterator concept, // but due to a lack of the corresponding contiguous_iterator_tag relies on // explicitly instantiating the type with iterators that are supposed to be // contiguous iterators. // References: // - https://wg21.link/iterator.concept.contiguous // - https://wg21.link/std.iterator.tags#lib:contiguous_iterator_tag // - https://wg21.link/n4284 template struct IsContiguousIterator : internal::IsContiguousIteratorImpl> {}; } // namespace base #endif // BASE_CONTAINERS_CONTIGUOUS_ITERATOR_H_