Warning: This file is not a C or C++ file. It does not have highlighting.

1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ITERATOR_ALIASING_ITERATOR_H
10#define _LIBCPP___ITERATOR_ALIASING_ITERATOR_H
11
12#include <__config>
13#include <__cstddef/ptrdiff_t.h>
14#include <__iterator/iterator_traits.h>
15#include <__memory/addressof.h>
16#include <__memory/pointer_traits.h>
17#include <__type_traits/is_trivially_constructible.h>
18#include <__type_traits/is_trivially_copyable.h>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21# pragma GCC system_header
22#endif
23
24// This iterator wrapper is used to type-pun an iterator to return a different type. This is done without UB by not
25// actually punning the type, but instead inspecting the object representation of the base type and copying that into
26// an instance of the alias type. For that reason the alias type has to be trivial. The alias is returned as a prvalue
27// when derferencing the iterator, since it is temporary storage. This wrapper is used to vectorize some algorithms.
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <class _BaseIter, class _Alias>
32struct __aliasing_iterator_wrapper {
33 class __iterator {
34 _BaseIter __base_ = nullptr;
35
36 using __iter_traits _LIBCPP_NODEBUG = iterator_traits<_BaseIter>;
37 using __base_value_type _LIBCPP_NODEBUG = typename __iter_traits::value_type;
38
39 static_assert(__has_random_access_iterator_category<_BaseIter>::value,
40 "The base iterator has to be a random access iterator!");
41
42 public:
43 using iterator_category = random_access_iterator_tag;
44 using value_type = _Alias;
45 using difference_type = ptrdiff_t;
46 using reference = value_type&;
47 using pointer = value_type*;
48
49 static_assert(is_trivially_default_constructible<value_type>::value);
50 static_assert(is_trivially_copyable<value_type>::value);
51 static_assert(sizeof(__base_value_type) == sizeof(value_type));
52
53 _LIBCPP_HIDE_FROM_ABI __iterator() = default;
54 _LIBCPP_HIDE_FROM_ABI __iterator(_BaseIter __base) _NOEXCEPT : __base_(__base) {}
55
56 _LIBCPP_HIDE_FROM_ABI __iterator& operator++() _NOEXCEPT {
57 ++__base_;
58 return *this;
59 }
60
61 _LIBCPP_HIDE_FROM_ABI __iterator operator++(int) _NOEXCEPT {
62 __iterator __tmp(*this);
63 ++__base_;
64 return __tmp;
65 }
66
67 _LIBCPP_HIDE_FROM_ABI __iterator& operator--() _NOEXCEPT {
68 --__base_;
69 return *this;
70 }
71
72 _LIBCPP_HIDE_FROM_ABI __iterator operator--(int) _NOEXCEPT {
73 __iterator __tmp(*this);
74 --__base_;
75 return __tmp;
76 }
77
78 _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(__iterator __iter, difference_type __n) _NOEXCEPT {
79 return __iterator(__iter.__base_ + __n);
80 }
81
82 _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(difference_type __n, __iterator __iter) _NOEXCEPT {
83 return __iterator(__n + __iter.__base_);
84 }
85
86 _LIBCPP_HIDE_FROM_ABI __iterator& operator+=(difference_type __n) _NOEXCEPT {
87 __base_ += __n;
88 return *this;
89 }
90
91 _LIBCPP_HIDE_FROM_ABI friend __iterator operator-(__iterator __iter, difference_type __n) _NOEXCEPT {
92 return __iterator(__iter.__base_ - __n);
93 }
94
95 _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(__iterator __lhs, __iterator __rhs) _NOEXCEPT {
96 return __lhs.__base_ - __rhs.__base_;
97 }
98
99 _LIBCPP_HIDE_FROM_ABI __iterator& operator-=(difference_type __n) _NOEXCEPT {
100 __base_ -= __n;
101 return *this;
102 }
103
104 _LIBCPP_HIDE_FROM_ABI _BaseIter __base() const _NOEXCEPT { return __base_; }
105
106 _LIBCPP_HIDE_FROM_ABI _Alias operator*() const _NOEXCEPT {
107 _Alias __val;
108 __builtin_memcpy(std::addressof(__val), std::__to_address(__base_), sizeof(value_type));
109 return __val;
110 }
111
112 _LIBCPP_HIDE_FROM_ABI value_type operator[](difference_type __n) const _NOEXCEPT { return *(*this + __n); }
113
114 _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __iterator& __lhs, const __iterator& __rhs) _NOEXCEPT {
115 return __lhs.__base_ == __rhs.__base_;
116 }
117
118 _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __iterator& __lhs, const __iterator& __rhs) _NOEXCEPT {
119 return __lhs.__base_ != __rhs.__base_;
120 }
121 };
122};
123
124// This is required to avoid ADL instantiations on _BaseT
125template <class _BaseT, class _Alias>
126using __aliasing_iterator _LIBCPP_NODEBUG = typename __aliasing_iterator_wrapper<_BaseT, _Alias>::__iterator;
127
128_LIBCPP_END_NAMESPACE_STD
129
130#endif // _LIBCPP___ITERATOR_ALIASING_ITERATOR_H
131

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of libcxx/include/__iterator/aliasing_iterator.h