6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
9
- #include < __utility/no_destroy.h>
10
9
#include < algorithm>
11
10
#include < clocale>
12
11
#include < codecvt>
@@ -82,8 +81,9 @@ locale_t __cloc() {
82
81
83
82
namespace {
84
83
85
- struct releaser {
86
- void operator ()(locale::facet* p) { p->__release_shared (); }
84
+ struct release
85
+ {
86
+ void operator ()(locale::facet* p) {p->__release_shared ();}
87
87
};
88
88
89
89
template <class T , class ...Args>
@@ -155,11 +155,7 @@ class _LIBCPP_HIDDEN locale::__imp
155
155
{return static_cast <size_t >(id) < facets_.size () && facets_[static_cast <size_t >(id)];}
156
156
const locale::facet* use_facet (long id) const ;
157
157
158
- void acquire ();
159
- void release ();
160
- static __no_destroy<__imp> classic_locale_imp_;
161
-
162
- private:
158
+ private:
163
159
void install (facet* f, long id);
164
160
template <class F > void install (F* f) {install (f, f->id .__get ());}
165
161
template <class F > void install_from (const __imp& other);
@@ -504,7 +500,7 @@ locale::__imp::__imp(const __imp& other, facet* f, long id)
504
500
name_ (" *" )
505
501
{
506
502
f->__add_shared ();
507
- unique_ptr<facet, releaser > hold (f);
503
+ unique_ptr<facet, release > hold (f);
508
504
facets_ = other.facets_ ;
509
505
for (unsigned i = 0 ; i < other.facets_ .size (); ++i)
510
506
if (facets_[i])
523
519
locale::__imp::install (facet* f, long id)
524
520
{
525
521
f->__add_shared ();
526
- unique_ptr<facet, releaser > hold (f);
522
+ unique_ptr<facet, release > hold (f);
527
523
if (static_cast <size_t >(id) >= facets_.size ())
528
524
facets_.resize (static_cast <size_t >(id+1 ));
529
525
if (facets_[static_cast <size_t >(id)])
@@ -541,78 +537,89 @@ locale::__imp::use_facet(long id) const
541
537
542
538
// locale
543
539
544
- // We don't do reference counting on the classic locale.
545
- // It's never destroyed anyway, but atomic reference counting may be very
546
- // expensive in parallel applications. The classic locale is used by default
547
- // in all streams. Note: if a new global locale is installed, then we lose
548
- // the benefit of no reference counting.
549
- __no_destroy<locale::__imp> locale::__imp::classic_locale_imp_ (__uninitialized_tag{}); // initialized below in classic()
540
+ // This class basically implements __attribute__((no_destroy)), which isn't supported
541
+ // by GCC as of writing this.
542
+ template <class T >
543
+ struct __no_destroy {
544
+ template <class ... Args>
545
+ explicit __no_destroy (Args&&... args) {
546
+ T* obj = reinterpret_cast <T*>(&buf);
547
+ new (obj) T (std::forward<Args>(args)...);
548
+ }
549
+
550
+ T& get () { return *reinterpret_cast <T*>(&buf); }
551
+ T const & get () const { return *reinterpret_cast <T const *>(&buf); }
552
+
553
+ private:
554
+ alignas (T) byte buf[sizeof (T)];
555
+ };
550
556
551
557
const locale& locale::classic () {
552
- static const __no_destroy<locale> classic_locale (__private_tag{}, [] {
553
- // executed exactly once on first initialization of `classic_locale`
554
- locale::__imp::classic_locale_imp_.__emplace (1u );
555
- return &locale::__imp::classic_locale_imp_.__get ();
556
- }());
557
- return classic_locale.__get ();
558
+ static const __no_destroy<locale> c (__private_tag{}, &make<__imp>(1u ));
559
+ return c.get ();
558
560
}
559
561
560
562
locale& locale::__global () {
561
- static __no_destroy<locale> g (locale::classic ());
562
- return g.__get ();
563
+ static __no_destroy<locale> g (locale::classic ());
564
+ return g.get ();
563
565
}
564
566
565
- void locale::__imp::acquire () {
566
- if (this != &locale::__imp::classic_locale_imp_.__get ())
567
- __add_shared ();
567
+ locale::locale () noexcept
568
+ : __locale_ (__global ().__locale_ )
569
+ {
570
+ __locale_->__add_shared ();
568
571
}
569
572
570
- void locale::__imp::release () {
571
- if (this != &locale::__imp::classic_locale_imp_.__get ())
572
- __release_shared ();
573
+ locale::locale (const locale& l) noexcept
574
+ : __locale_ (l.__locale_ )
575
+ {
576
+ __locale_->__add_shared ();
573
577
}
574
578
575
- locale::locale () noexcept : __locale_ (__global ().__locale_ ) { __locale_->acquire (); }
576
-
577
- locale::locale (const locale& l) noexcept : __locale_ (l.__locale_ ) { __locale_->acquire (); }
578
-
579
- locale::~locale () { __locale_->release (); }
579
+ locale::~locale ()
580
+ {
581
+ __locale_->__release_shared ();
582
+ }
580
583
581
584
const locale&
582
585
locale::operator =(const locale& other) noexcept
583
586
{
584
- other.__locale_ ->acquire ();
585
- __locale_->release ();
586
- __locale_ = other.__locale_ ;
587
- return *this ;
587
+ other.__locale_ ->__add_shared ();
588
+ __locale_->__release_shared ();
589
+ __locale_ = other.__locale_ ;
590
+ return *this ;
588
591
}
589
592
590
593
locale::locale (const char * name)
591
594
: __locale_ (name ? new __imp (name)
592
595
: (__throw_runtime_error (" locale constructed with null" ), nullptr ))
593
596
{
594
- __locale_->acquire ();
597
+ __locale_->__add_shared ();
595
598
}
596
599
597
- locale::locale (const string& name) : __locale_ (new __imp (name)) { __locale_->acquire (); }
600
+ locale::locale (const string& name)
601
+ : __locale_ (new __imp (name))
602
+ {
603
+ __locale_->__add_shared ();
604
+ }
598
605
599
606
locale::locale (const locale& other, const char * name, category c)
600
607
: __locale_ (name ? new __imp (*other.__locale_ , name, c)
601
608
: (__throw_runtime_error (" locale constructed with null" ), nullptr ))
602
609
{
603
- __locale_->acquire ();
610
+ __locale_->__add_shared ();
604
611
}
605
612
606
613
locale::locale (const locale& other, const string& name, category c)
607
614
: __locale_ (new __imp (*other.__locale_ , name, c))
608
615
{
609
- __locale_->acquire ();
616
+ __locale_->__add_shared ();
610
617
}
611
618
612
619
locale::locale (const locale& other, const locale& one, category c)
613
620
: __locale_ (new __imp (*other.__locale_ , *one.__locale_ , c))
614
621
{
615
- __locale_->acquire ();
622
+ __locale_->__add_shared ();
616
623
}
617
624
618
625
string
@@ -628,7 +635,7 @@ locale::__install_ctor(const locale& other, facet* f, long id)
628
635
__locale_ = new __imp (*other.__locale_ , f, id);
629
636
else
630
637
__locale_ = other.__locale_ ;
631
- __locale_->acquire ();
638
+ __locale_->__add_shared ();
632
639
}
633
640
634
641
locale
0 commit comments