summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits/stl_iterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/bits/stl_iterator.h')
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h126
1 files changed, 86 insertions, 40 deletions
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index 35266722f66..f2b315f30e4 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1908,6 +1908,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(_S_noexcept<const _It2&, const _Sent2&>())
: _M_valueless(), _M_index(__x._M_index)
{
+ __glibcxx_assert(__x._M_has_value());
if (_M_index == 0)
{
if constexpr (is_trivially_default_constructible_v<_It>)
@@ -1945,14 +1946,58 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
+ constexpr
+ common_iterator(common_iterator&& __x)
+ noexcept(_S_noexcept<_It, _Sent>())
+ : _M_valueless(), _M_index(__x._M_index)
+ {
+ if (_M_index == 0)
+ {
+ if constexpr (is_trivially_default_constructible_v<_It>)
+ _M_it = std::move(__x._M_it);
+ else
+ std::construct_at(std::__addressof(_M_it), std::move(__x._M_it));
+ }
+ else if (_M_index == 1)
+ {
+ if constexpr (is_trivially_default_constructible_v<_Sent>)
+ _M_sent = std::move(__x._M_sent);
+ else
+ std::construct_at(std::__addressof(_M_sent),
+ std::move(__x._M_sent));
+ }
+ }
+
+ constexpr common_iterator&
+ operator=(const common_iterator&) = default;
+
constexpr common_iterator&
operator=(const common_iterator& __x)
noexcept(is_nothrow_copy_assignable_v<_It>
&& is_nothrow_copy_assignable_v<_Sent>
&& is_nothrow_copy_constructible_v<_It>
&& is_nothrow_copy_constructible_v<_Sent>)
+ requires (!is_trivially_copy_assignable_v<_It>
+ || !is_trivially_copy_assignable_v<_Sent>)
{
- return this->operator=<_It, _Sent>(__x);
+ _M_assign(__x);
+ return *this;
+ }
+
+ constexpr common_iterator&
+ operator=(common_iterator&&) = default;
+
+ constexpr common_iterator&
+ operator=(common_iterator&& __x)
+ noexcept(is_nothrow_move_assignable_v<_It>
+ && is_nothrow_move_assignable_v<_Sent>
+ && is_nothrow_move_constructible_v<_It>
+ && is_nothrow_move_constructible_v<_Sent>)
+ requires (!is_trivially_move_assignable_v<_It>
+ || !is_trivially_move_assignable_v<_Sent>)
+ {
+ _M_assign(std::move(__x));
+ return *this;
}
template<typename _It2, typename _Sent2>
@@ -1967,49 +2012,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& is_nothrow_assignable_v<_It&, const _It2&>
&& is_nothrow_assignable_v<_Sent&, const _Sent2&>)
{
- switch(_M_index << 2 | __x._M_index)
- {
- case 0b0000:
- _M_it = __x._M_it;
- break;
- case 0b0101:
- _M_sent = __x._M_sent;
- break;
- case 0b0001:
- _M_it.~_It();
- _M_index = -1;
- [[fallthrough]];
- case 0b1001:
- std::construct_at(std::__addressof(_M_sent), _Sent(__x._M_sent));
- _M_index = 1;
- break;
- case 0b0100:
- _M_sent.~_Sent();
- _M_index = -1;
- [[fallthrough]];
- case 0b1000:
- std::construct_at(std::__addressof(_M_it), _It(__x._M_it));
- _M_index = 0;
- break;
- default:
- __glibcxx_assert(__x._M_has_value());
- __builtin_unreachable();
- }
+ __glibcxx_assert(__x._M_has_value());
+ _M_assign(__x);
return *this;
}
constexpr
~common_iterator()
{
- switch (_M_index)
- {
- case 0:
- _M_it.~_It();
- break;
- case 1:
- _M_sent.~_Sent();
- break;
- }
+ if (_M_index == 0)
+ _M_it.~_It();
+ else if (_M_index == 1)
+ _M_sent.~_Sent();
}
[[nodiscard]]
@@ -2167,7 +2181,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
requires (!same_as<_It2, _Sent2>) && copyable<_It2>
friend class common_iterator;
- constexpr bool _M_has_value() const noexcept { return _M_index < 2; }
+ constexpr bool
+ _M_has_value() const noexcept { return _M_index != _S_valueless; }
+
+ template<typename _CIt>
+ constexpr void
+ _M_assign(_CIt&& __x)
+ {
+ if (_M_index == __x._M_index)
+ {
+ if (_M_index == 0)
+ _M_it = std::forward<_CIt>(__x)._M_it;
+ else if (_M_index == 1)
+ _M_sent = std::forward<_CIt>(__x)._M_sent;
+ }
+ else
+ {
+ if (_M_index == 0)
+ _M_it.~_It();
+ else if (_M_index == 1)
+ _M_sent.~_Sent();
+ _M_index = _S_valueless;
+
+ if (__x._M_index == 0)
+ std::construct_at(std::__addressof(_M_it),
+ std::forward<_CIt>(__x)._M_it);
+ else if (__x._M_index == 1)
+ std::construct_at(std::__addressof(_M_sent),
+ std::forward<_CIt>(__x)._M_sent);
+ _M_index = __x._M_index;
+ }
+ }
union
{
@@ -2175,7 +2219,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Sent _M_sent;
unsigned char _M_valueless;
};
- unsigned char _M_index; // 0==_M_it, 1==_M_sent, 2==valueless
+ unsigned char _M_index; // 0 == _M_it, 1 == _M_sent, 2 == valueless
+
+ static constexpr unsigned char _S_valueless{2};
};
template<typename _It, typename _Sent>