[libcxx-commits] [libcxx] [libc++] Refactor the creation of the global and classic locales (PR #72581)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Nov 16 14:42:30 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Louis Dionne (ldionne)
<details>
<summary>Changes</summary>
The creation of the global and the classic locales was pretty twisty. This patch refactors how this is done to reduce the amount of indirections and prepare the terrain for a future where GCC implements the no_destroy attribute.
---
Full diff: https://github.com/llvm/llvm-project/pull/72581.diff
2 Files Affected:
- (modified) libcxx/include/__locale (+3)
- (modified) libcxx/src/locale.cpp (+23-30)
``````````diff
diff --git a/libcxx/include/__locale b/libcxx/include/__locale
index b1502dd71edadf6..0b0b94c99393b61 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -127,6 +127,9 @@ private:
class __imp;
__imp* __locale_;
+ template <class> friend struct no_destroy;
+ _LIBCPP_HIDE_FROM_ABI explicit locale(__imp* __loc) : __locale_(__loc) {}
+
void __install_ctor(const locale&, facet*, long);
static locale& __global();
bool has_facet(id&) const;
diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index c37e091dcc4671b..6b1e5a6e4b494c4 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -6,7 +6,6 @@
//
//===----------------------------------------------------------------------===//
-#include <__utility/unreachable.h>
#include <algorithm>
#include <clocale>
#include <codecvt>
@@ -15,9 +14,11 @@
#include <cstdlib>
#include <cstring>
#include <locale>
+#include <new>
#include <string>
#include <type_traits>
#include <typeinfo>
+#include <utility>
#include <vector>
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -154,8 +155,6 @@ class _LIBCPP_HIDDEN locale::__imp
{return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
const locale::facet* use_facet(long id) const;
- static const locale& make_classic();
- static locale& make_global();
private:
void install(facet* f, long id);
template <class F> void install(F* f) {install(f, f->id.__get());}
@@ -538,37 +537,31 @@ locale::__imp::use_facet(long id) const
// locale
-const locale&
-locale::__imp::make_classic()
-{
- // only one thread can get in here and it only gets in once
- alignas(locale) static std::byte buf[sizeof(locale)];
- locale* c = reinterpret_cast<locale*>(&buf);
- c->__locale_ = &make<__imp>(1u);
- return *c;
-}
+// This class basically implements __attribute__((no_destroy)), which isn't supported
+// by GCC as of writing this.
+template <class T>
+struct no_destroy {
+ template <class... Args>
+ explicit no_destroy(Args&&... args) {
+ T* obj = reinterpret_cast<T*>(&buf);
+ new (obj) T(std::forward<Args>(args)...);
+ }
-const locale&
-locale::classic()
-{
- static const locale& c = __imp::make_classic();
- return c;
-}
+ T& get() { return *reinterpret_cast<T*>(&buf); }
+ T const& get() const { return *reinterpret_cast<T const*>(&buf); }
-locale&
-locale::__imp::make_global()
-{
- // only one thread can get in here and it only gets in once
- alignas(locale) static std::byte buf[sizeof(locale)];
- auto *obj = ::new (&buf) locale(locale::classic());
- return *obj;
+ private:
+ alignas(T) byte buf[sizeof(T)];
+};
+
+const locale& locale::classic() {
+ static const no_destroy<locale> c(&make<__imp>(1u));
+ return c.get();
}
-locale&
-locale::__global()
-{
- static locale& g = __imp::make_global();
- return g;
+locale& locale::__global() {
+ static no_destroy<locale> g(locale::classic());
+ return g.get();
}
locale::locale() noexcept
``````````
</details>
https://github.com/llvm/llvm-project/pull/72581
More information about the libcxx-commits
mailing list