Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libcxx/docs/ABIGuarantees.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ This flag adds ``[[clang::trivial_abi]]`` to ``unique_ptr``, which makes it triv
---------------------------------------------
This flag adds ``[[clang::trivial_abi]]`` to ``shared_ptr``, which makes it trivial for the purpose of calls.

``_LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR``
-----------------------------------------------
This flag makes ``__bit_iterator`` (a.k.a. ``vector<bool>::iterator``) trivially copyable as well as trivial for the
purpose of calls, since the copy constructor is made trivial.

Types that public aliases reference
===================================
Expand Down
11 changes: 10 additions & 1 deletion libcxx/include/__bit_reference
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,15 @@ public:
// When _IsConst=true, this is a converting constructor;
// the copy and move constructors are implicitly generated
// and trivial.
#ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
template <bool _IsConstDep = _IsConst, __enable_if_t<_IsConstDep, int> = 0>
#endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
: __seg_(__it.__seg_),
__ctz_(__it.__ctz_) {}
__ctz_(__it.__ctz_) {
}

#ifndef _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
// When _IsConst=false, we have a user-provided copy constructor,
// so we must also provide a copy assignment operator because
// the implicit generation of a defaulted one is deprecated.
Expand All @@ -329,6 +334,10 @@ public:
__ctz_ = __it.__ctz_;
return *this;
}
#else
_LIBCPP_HIDE_FROM_ABI __bit_iterator(const __bit_iterator&) = default;
_LIBCPP_HIDE_FROM_ABI __bit_iterator& operator=(const __bit_iterator&) = default;
#endif // _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__ctz_ < __bits_per_word, "Dereferencing an invalid __bit_iterator.");
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__configuration/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
# define _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR

#elif _LIBCPP_ABI_VERSION == 1
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,13 @@ using IsTrivialForCall = std::integral_constant<
// Ignore the all-deleted case, it shouldn't occur here.
>;

void test_const_iterator() {
using It = std::vector<bool>::const_iterator;
static_assert(IsTrivialForCall<It>::value, "");
}

void test_non_const_iterator() {
using It = std::vector<bool>::iterator;
static_assert(!IsTrivialForCall<It>::value, "");
}

int main(int, char**) {
test_const_iterator();
test_non_const_iterator();

return 0;
}
static_assert(IsTrivialForCall<std::vector<bool>::const_iterator>::value, "");
static_assert(std::is_trivially_copyable<std::vector<bool>::const_iterator>::value, "");

#ifndef _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
static_assert(!IsTrivialForCall<std::vector<bool>::iterator>::value, "");
static_assert(!std::is_trivially_copyable<std::vector<bool>::iterator>::value, "");
#else
static_assert(IsTrivialForCall<std::vector<bool>::iterator>::value, "");
static_assert(std::is_trivially_copyable<std::vector<bool>::iterator>::value, "");
#endif
Loading