[libcxx-commits] [libcxx] [libcxx][string] Allow fancy pointers in basic_string (PR #199264)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Oct 5 02:30:36 PDT 2026
================
@@ -878,16 +880,91 @@ private:
static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
- union __rep {
+ template <typename _LongT, typename = void>
+ union __rep_t {
__short __s;
- __long __l;
+ _LongT __l;
- __rep() = default;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__short __r) : __s(__r) {}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__long __r) : __l(__r) {}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__uninitialized_tag) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_long_lifetime() {}
+
+ __rep_t() = default;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep_t(__short __r) : __s(__r) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep_t(_LongT __r) : __l(__r) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep_t(__uninitialized_tag) {}
};
+ template <typename _LongT>
+ union __rep_t<_LongT,
+ typename std::enable_if<!is_trivially_constructible<_LongT>::value ||
+ !is_trivially_copy_assignable<_LongT>::value ||
+ !is_trivially_destructible<_LongT>::value >::type> {
+ __short __s;
+ _LongT __l;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_long() const _NOEXCEPT {
+ if (__libcpp_is_constant_evaluated() && __builtin_constant_p(__l.__is_long_)) {
+ return __l.__is_long_;
+ }
+ return __s.__is_long_;
+ }
+
+ // If __long is not trivially constructible (this occurs if the pointer type inside __long is not trivially
+ // constructible) then the lifetime of __l must be explicitly started with std::__construct_at before it can be
+ // assigned to. If __long is trivially constructible, then the lifetime of __l can be implicitly started with a
+ // simple assignment and therefore does not need to be explicitly initialised here.
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_long_lifetime() {
+ if _LIBCPP_CONSTEXPR (!__is_trivially_constructible(_LongT)) {
+ std::__construct_at(std::addressof(__l));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep_t() : __s() {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep_t(__short __r) : __s(__r) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep_t(_LongT __r) : __l(__r) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep_t(__uninitialized_tag) : __s() {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep_t(const __rep_t& __other) {
----------------
frederick-vs-ja wrote:
Do we want make these special member functions non-`noexcept`?
https://github.com/llvm/llvm-project/pull/199264
More information about the libcxx-commits
mailing list