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