[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