[libcxx-commits] [libcxx] [libc++] Inline fast path for`exception_ptr` copy constructor & destructor (PR #165909)
Adrian Vogelsgesang via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Nov 11 01:49:21 PST 2025
================
@@ -82,17 +85,42 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
_LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
+// These symbols are still exported from the library to prevent ABI breakage.
+# ifdef _LIBCPP_BUILDING_LIBRARY
exception_ptr(const exception_ptr&) _NOEXCEPT;
+ exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
+ ~exception_ptr() _NOEXCEPT;
+# else // _LIBCPP_BUILDING_LIBRARY
+ _LIBCPP_HIDE_FROM_ABI exception_ptr(const exception_ptr&) _NOEXCEPT : __ptr_(__other.__ptr_) {
+ if (__ptr_)
+ __increment_refcount(__ptr_);
+ }
+ _LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(const exception_ptr&) _NOEXCEPT {
+ if (__ptr_ != __other.__ptr_) {
+ if (__other.__ptr_)
+ __increment_refcount(__other.__ptr_);
+ if (__ptr_)
+ __decrement_refcount(__ptr_);
+ __ptr_ = __other.__ptr_;
+ }
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI ~exception_ptr() _NOEXCEPT {
+ if (__ptr_)
+ __decrement_refcount(__ptr_);
+ }
+# endif // _LIBCPP_BUILDING_LIBRARY
+
_LIBCPP_HIDE_FROM_ABI exception_ptr(exception_ptr&& __other) _NOEXCEPT : __ptr_(__other.__ptr_) {
__other.__ptr_ = nullptr;
}
- exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(exception_ptr&& __other) _NOEXCEPT {
- exception_ptr __tmp(std::move(__other));
- std::swap(__tmp, *this);
+ if (__ptr_)
+ __decrement_refcount(__ptr_);
+ __ptr_ = __other.__ptr_;
+ __other.__ptr_ = nullptr;
----------------
vogelsgesang wrote:
Good point.
We have 3 choices:
1. implement both `swap` and the move operator, delegate move to swap (previous solution)
2. implement both `swap` and the move operator independently (currently in review)
3. implement only the move operator, and don't provide a specialization for `swap`
To me, (3) actually feels most natural. My gut feeling tells me that "move" assignments are more frequently used/specialized than `swap`, so it feels more natural to implement the more common function (move) and delegate the less frequently used (swap) to the other one
I updated the PR accordingly. Please let me know in case you prefer going into a different direction
https://github.com/llvm/llvm-project/pull/165909
More information about the libcxx-commits
mailing list