Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:32

0001 //===----------------------------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef _LIBCPP___CXX03___ITERATOR_ALIASING_ITERATOR_H
0010 #define _LIBCPP___CXX03___ITERATOR_ALIASING_ITERATOR_H
0011 
0012 #include <__cxx03/__config>
0013 #include <__cxx03/__iterator/iterator_traits.h>
0014 #include <__cxx03/__memory/pointer_traits.h>
0015 #include <__cxx03/__type_traits/is_trivial.h>
0016 #include <__cxx03/cstddef>
0017 
0018 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0019 #  pragma GCC system_header
0020 #endif
0021 
0022 // This iterator wrapper is used to type-pun an iterator to return a different type. This is done without UB by not
0023 // actually punning the type, but instead inspecting the object representation of the base type and copying that into
0024 // an instance of the alias type. For that reason the alias type has to be trivial. The alias is returned as a prvalue
0025 // when derferencing the iterator, since it is temporary storage. This wrapper is used to vectorize some algorithms.
0026 
0027 _LIBCPP_BEGIN_NAMESPACE_STD
0028 
0029 template <class _BaseIter, class _Alias>
0030 struct __aliasing_iterator_wrapper {
0031   class __iterator {
0032     _BaseIter __base_ = nullptr;
0033 
0034     using __iter_traits     = iterator_traits<_BaseIter>;
0035     using __base_value_type = typename __iter_traits::value_type;
0036 
0037     static_assert(__has_random_access_iterator_category<_BaseIter>::value,
0038                   "The base iterator has to be a random access iterator!");
0039 
0040   public:
0041     using iterator_category = random_access_iterator_tag;
0042     using value_type        = _Alias;
0043     using difference_type   = ptrdiff_t;
0044     using reference         = value_type&;
0045     using pointer           = value_type*;
0046 
0047     static_assert(is_trivial<value_type>::value);
0048     static_assert(sizeof(__base_value_type) == sizeof(value_type));
0049 
0050     _LIBCPP_HIDE_FROM_ABI __iterator() = default;
0051     _LIBCPP_HIDE_FROM_ABI __iterator(_BaseIter __base) _NOEXCEPT : __base_(__base) {}
0052 
0053     _LIBCPP_HIDE_FROM_ABI __iterator& operator++() _NOEXCEPT {
0054       ++__base_;
0055       return *this;
0056     }
0057 
0058     _LIBCPP_HIDE_FROM_ABI __iterator operator++(int) _NOEXCEPT {
0059       __iterator __tmp(*this);
0060       ++__base_;
0061       return __tmp;
0062     }
0063 
0064     _LIBCPP_HIDE_FROM_ABI __iterator& operator--() _NOEXCEPT {
0065       --__base_;
0066       return *this;
0067     }
0068 
0069     _LIBCPP_HIDE_FROM_ABI __iterator operator--(int) _NOEXCEPT {
0070       __iterator __tmp(*this);
0071       --__base_;
0072       return __tmp;
0073     }
0074 
0075     _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(__iterator __iter, difference_type __n) _NOEXCEPT {
0076       return __iterator(__iter.__base_ + __n);
0077     }
0078 
0079     _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(difference_type __n, __iterator __iter) _NOEXCEPT {
0080       return __iterator(__n + __iter.__base_);
0081     }
0082 
0083     _LIBCPP_HIDE_FROM_ABI __iterator& operator+=(difference_type __n) _NOEXCEPT {
0084       __base_ += __n;
0085       return *this;
0086     }
0087 
0088     _LIBCPP_HIDE_FROM_ABI friend __iterator operator-(__iterator __iter, difference_type __n) _NOEXCEPT {
0089       return __iterator(__iter.__base_ - __n);
0090     }
0091 
0092     _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(__iterator __lhs, __iterator __rhs) _NOEXCEPT {
0093       return __lhs.__base_ - __rhs.__base_;
0094     }
0095 
0096     _LIBCPP_HIDE_FROM_ABI __iterator& operator-=(difference_type __n) _NOEXCEPT {
0097       __base_ -= __n;
0098       return *this;
0099     }
0100 
0101     _LIBCPP_HIDE_FROM_ABI _BaseIter __base() const _NOEXCEPT { return __base_; }
0102 
0103     _LIBCPP_HIDE_FROM_ABI _Alias operator*() const _NOEXCEPT {
0104       _Alias __val;
0105       __builtin_memcpy(&__val, std::__to_address(__base_), sizeof(value_type));
0106       return __val;
0107     }
0108 
0109     _LIBCPP_HIDE_FROM_ABI value_type operator[](difference_type __n) const _NOEXCEPT { return *(*this + __n); }
0110 
0111     _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __iterator& __lhs, const __iterator& __rhs) _NOEXCEPT {
0112       return __lhs.__base_ == __rhs.__base_;
0113     }
0114 
0115     _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __iterator& __lhs, const __iterator& __rhs) _NOEXCEPT {
0116       return __lhs.__base_ != __rhs.__base_;
0117     }
0118   };
0119 };
0120 
0121 // This is required to avoid ADL instantiations on _BaseT
0122 template <class _BaseT, class _Alias>
0123 using __aliasing_iterator = typename __aliasing_iterator_wrapper<_BaseT, _Alias>::__iterator;
0124 
0125 _LIBCPP_END_NAMESPACE_STD
0126 
0127 #endif // _LIBCPP___CXX03___ITERATOR_ALIASING_ITERATOR_H