// -*- 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___ITERATOR_BOUNDED_ITER_H #define _LIBCPP___ITERATOR_BOUNDED_ITER_H #include <__assert> #include <__compare/ordering.h> #include <__compare/three_way_comparable.h> #include <__config> #include <__iterator/iterator_traits.h> #include <__memory/pointer_traits.h> #include <__type_traits/enable_if.h> #include <__type_traits/integral_constant.h> #include <__type_traits/is_convertible.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif _LIBCPP_PUSH_MACROS #include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD // Iterator wrapper that carries the valid range it is allowed to access. // // This is a simple iterator wrapper for contiguous iterators that points // within a [begin, end] range and carries these bounds with it. The iterator // ensures that it is pointing within [begin, end) range when it is // dereferenced. It also ensures that it is never iterated outside of // [begin, end]. This is important for two reasons: // // 1. It allows `operator*` and `operator++` bounds checks to be `iter != end`. // This is both less for the optimizer to prove, and aligns with how callers // typically use iterators. // // 2. Advancing an iterator out of bounds is undefined behavior (see the table // in [input.iterators]). In particular, when the underlying iterator is a // pointer, it is undefined at the language level (see [expr.add]). If // bounded iterators exhibited this undefined behavior, we risk compiler // optimizations deleting non-redundant bounds checks. template <class _Iterator, class = __enable_if_t< __libcpp_is_contiguous_iterator<_Iterator>::value > > struct __bounded_iter { … }; template <class _It> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It __it, _It __begin, _It __end) { … } #if _LIBCPP_STD_VER <= 17 template <class _Iterator> struct __libcpp_is_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {}; #endif pointer_traits<__bounded_iter<_Iterator>>; _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS #endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H