[libcxx-commits] [libcxx] [libc++] Ensure that `std::expected` has no tail padding (PR #69673)
Jan Kokemüller via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 18 21:09:48 PST 2024
================
@@ -955,101 +1310,99 @@ class expected<_Tp, _Err> {
_LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) noexcept(
is_nothrow_copy_constructible_v<_Err>) // strengthened
requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>)
- : __union_(__rhs.__has_val_, __rhs.__union_), __has_val_(__rhs.__has_val_) {}
+ : __base(__rhs.__has_val(), __rhs.__union()) {}
_LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
= default;
_LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) noexcept(is_nothrow_move_constructible_v<_Err>)
requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>)
- : __union_(__rhs.__has_val_, std::move(__rhs.__union_)), __has_val_(__rhs.__has_val_) {}
+ : __base(__rhs.__has_val(), std::move(__rhs.__union())) {}
template <class _Up, class _OtherErr>
requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
expected(const expected<_Up, _OtherErr>& __rhs) noexcept(
is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
- : __union_(__rhs.__has_val_, __rhs.__union_), __has_val_(__rhs.__has_val_) {}
+ : __base(__rhs.__has_val(), __rhs.__union()) {}
template <class _Up, class _OtherErr>
requires __can_convert<_Up, _OtherErr, _OtherErr>::value
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
expected(expected<_Up, _OtherErr>&& __rhs) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
- : __union_(__rhs.__has_val_, std::move(__rhs.__union_)), __has_val_(__rhs.__has_val_) {}
+ : __base(__rhs.__has_val(), std::move(__rhs.__union())) {}
template <class _OtherErr>
requires is_constructible_v<_Err, const _OtherErr&>
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) expected(
const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
- : __union_(std::unexpect, __unex.error()), __has_val_(false) {}
+ : __base(unexpect, __unex.error()) {}
template <class _OtherErr>
requires is_constructible_v<_Err, _OtherErr>
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
- : __union_(std::unexpect, std::move(__unex.error())), __has_val_(false) {}
+ : __base(unexpect, std::move(__unex.error())) {}
- _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {}
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __base(in_place) {}
template <class... _Args>
requires is_constructible_v<_Err, _Args...>
_LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept(
is_nothrow_constructible_v<_Err, _Args...>) // strengthened
- : __union_(std::unexpect, std::forward<_Args>(__args)...), __has_val_(false) {}
+ : __base(unexpect, std::forward<_Args>(__args)...) {}
template <class _Up, class... _Args>
requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
_LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept(
is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
- : __union_(std::unexpect, __il, std::forward<_Args>(__args)...), __has_val_(false) {}
+ : __base(unexpect, __il, std::forward<_Args>(__args)...) {}
private:
- template <class _Func>
- _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(__expected_construct_in_place_from_invoke_tag, _Func&& __f)
- : __has_val_(true) {
- std::invoke(std::forward<_Func>(__f));
- }
-
template <class _Func, class... _Args>
_LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
- : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {}
+ : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {}
public:
// [expected.void.dtor], destructor
- _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
- requires is_trivially_destructible_v<_Err>
- = default;
+ _LIBCPP_HIDE_FROM_ABI constexpr ~expected() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
- requires(!is_trivially_destructible_v<_Err>)
- {
- if (!__has_val_) {
- std::destroy_at(std::addressof(__union_.__unex_));
- }
+private:
+ // precondition: has_value()
----------------
jiixyj wrote:
done!
https://github.com/llvm/llvm-project/pull/69673
More information about the libcxx-commits
mailing list