[libcxx-commits] [PATCH] D132149: [String] Allow fancy pointer as pointer type of basic_string allocator

Brendan Emery via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Wed Dec 21 01:28:49 PST 2022


bemeryesr updated this revision to Diff 484497.
bemeryesr marked 3 inline comments as done.
bemeryesr added a comment.

Update clang formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D132149/new/

https://reviews.llvm.org/D132149

Files:
  libcxx/include/string


Index: libcxx/include/string
===================================================================
--- libcxx/include/string
+++ libcxx/include/string
@@ -770,7 +770,20 @@
 
     static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
 
+#ifdef _LIBCPP_CXX03_LANG
     union __ulx{__long __lx; __short __lxx;};
+#else
+    // Since C++03, unions can contain members with non-trivial special member functions (C++03 doesn't allow unions to
+    // contain members with non-trivial special member functions). In this case, the corresponding special member
+    // function in the union will be deleted and therefore must be explicitly defined. Therefore, to support fancy
+    // pointers with non-trivial constructors in __long, we must explicitly define a constructor in __ulx.
+    union __ulx {
+      _LIBCPP_CONSTEXPR_SINCE_CXX20 __ulx() _NOEXCEPT : __lx{} {}
+
+      __long __lx;
+      __short __lxx;
+    };
+#endif // _LIBCPP_CXX03_LANG
 
     enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
 
@@ -779,6 +792,7 @@
         size_type __words[__n_words];
     };
 
+#ifdef _LIBCPP_CXX03_LANG
     struct __rep
     {
         union
@@ -788,6 +802,60 @@
             __raw   __r;
         };
     };
+#else
+    // Since C++03, unions can contain members with non-trivial special member functions (C++03 doesn't allow unions to
+    // contain members with non-trivial special member functions). In this case, the corresponding special member
+    // function in the union will be deleted and therefore must be explicitly defined. Therefore, to support fancy
+    // pointers with non-trivial special member functions in __long, we must explicitly define a constructor, copy
+    // constructor and copy assignment operator in __rep.
+    struct __rep {
+      _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep() _NOEXCEPT : __l{} {}
+      _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__rep() _NOEXCEPT {}
+
+      _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_rep_long(const __rep& __str_rep) const _NOEXCEPT {
+        if (__libcpp_is_constant_evaluated())
+          return true;
+        return __str_rep.__l.__is_long_;
+      }
+
+      _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(const __rep& __other) _NOEXCEPT : __l{} {
+        // For certain fancy pointers such as offset pointers, the value of __l.__data_ will be different for 2 pointers
+        // pointing to the same object (because the offset is calculated with respect to the pointer itself). Therefore,
+        // the copy assignment operator of the underlying pointer needs to be explicitly called. For a short string, the
+        // memory should be directly copied.
+        if (__is_rep_long(__other)) {
+          __l.__is_long_ = __other.__l.__is_long_;
+          __l.__cap_     = __other.__l.__cap_;
+          __l.__size_    = __other.__l.__size_;
+          __l.__data_    = __other.__l.__data_;
+        } else {
+          for (unsigned __i = 0; __i < __n_words; ++__i)
+            __r.__words[__i] = __other.__r.__words[__i];
+        }
+      }
+
+      _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep& operator=(const __rep& __other) _NOEXCEPT {
+        if (this != &__other) {
+          if (__is_rep_long(__other)) {
+            __l.__is_long_ = __other.__l.__is_long_;
+            __l.__cap_     = __other.__l.__cap_;
+            __l.__size_    = __other.__l.__size_;
+            __l.__data_    = __other.__l.__data_;
+          } else {
+            for (unsigned __i = 0; __i < __n_words; ++__i)
+              __r.__words[__i] = __other.__r.__words[__i];
+          }
+        }
+        return *this;
+      }
+
+      union {
+        __long __l;
+        __short __s;
+        __raw __r;
+      };
+    };
+#endif // _LIBCPP_CXX03_LANG
 
     __compressed_pair<__rep, allocator_type> __r_;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D132149.484497.patch
Type: text/x-patch
Size: 3804 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20221221/36716728/attachment.bin>


More information about the libcxx-commits mailing list