Skip to content

Commit 3a42a08

Browse files
committed
[libc++] Add an ABI flag to make __bit_iterator trivially copyable
1 parent 3ed5c19 commit 3a42a08

File tree

4 files changed

+25
-17
lines changed

4 files changed

+25
-17
lines changed

libcxx/docs/ABIGuarantees.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ This flag adds ``[[clang::trivial_abi]]`` to ``unique_ptr``, which makes it triv
157157
---------------------------------------------
158158
This flag adds ``[[clang::trivial_abi]]`` to ``shared_ptr``, which makes it trivial for the purpose of calls.
159159

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

161165
Types that public aliases reference
162166
===================================

libcxx/include/__bit_reference

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,15 @@ public:
314314
// When _IsConst=true, this is a converting constructor;
315315
// the copy and move constructors are implicitly generated
316316
// and trivial.
317+
#ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
318+
template <bool _IsConstDep = _IsConst, __enable_if_t<_IsConstDep, int> = 0>
319+
#endif
317320
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
318321
: __seg_(__it.__seg_),
319-
__ctz_(__it.__ctz_) {}
322+
__ctz_(__it.__ctz_) {
323+
}
320324

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

333342
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
334343
_LIBCPP_ASSERT_INTERNAL(__ctz_ < __bits_per_word, "Dereferencing an invalid __bit_iterator.");

libcxx/include/__configuration/abi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
8585
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
8686
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
87+
# define _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
8788

8889
#elif _LIBCPP_ABI_VERSION == 1
8990
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))

libcxx/test/libcxx/containers/sequences/vector.bool/trivial_for_purposes_of_call.pass.cpp renamed to libcxx/test/libcxx/containers/sequences/vector.bool/trivialty.compile.pass.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,13 @@ using IsTrivialForCall = std::integral_constant<
3838
// Ignore the all-deleted case, it shouldn't occur here.
3939
>;
4040

41-
void test_const_iterator() {
42-
using It = std::vector<bool>::const_iterator;
43-
static_assert(IsTrivialForCall<It>::value, "");
44-
}
45-
46-
void test_non_const_iterator() {
47-
using It = std::vector<bool>::iterator;
48-
static_assert(!IsTrivialForCall<It>::value, "");
49-
}
50-
51-
int main(int, char**) {
52-
test_const_iterator();
53-
test_non_const_iterator();
54-
55-
return 0;
56-
}
41+
static_assert(IsTrivialForCall<std::vector<bool>::const_iterator>::value, "");
42+
static_assert(std::is_trivially_copyable<std::vector<bool>::const_iterator>::value, "");
43+
44+
#ifndef _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
45+
static_assert(!IsTrivialForCall<std::vector<bool>::iterator>::value, "");
46+
static_assert(!std::is_trivially_copyable<std::vector<bool>::iterator>::value, "");
47+
#else
48+
static_assert(IsTrivialForCall<std::vector<bool>::iterator>::value, "");
49+
static_assert(std::is_trivially_copyable<std::vector<bool>::iterator>::value, "");
50+
#endif

0 commit comments

Comments
 (0)