Skip to content

Commit b470795

Browse files
authored
Issue 252 : enforces static initialization order through static function variables (simdutf#253)
* Fix for issue 252 * adding icelake
1 parent 4a21261 commit b470795

1 file changed

Lines changed: 39 additions & 19 deletions

File tree

src/implementation.cpp

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,40 @@ namespace internal {
6666

6767

6868
#if SIMDUTF_IMPLEMENTATION_ICELAKE
69-
const icelake::implementation icelake_singleton{};
69+
static const icelake::implementation* get_icelake_singleton() {
70+
static const icelake::implementation icelake_singleton{};
71+
return &icelake_singleton;
72+
}
7073
#endif
7174
#if SIMDUTF_IMPLEMENTATION_HASWELL
72-
const haswell::implementation haswell_singleton{};
75+
static const haswell::implementation* get_haswell_singleton() {
76+
static const haswell::implementation haswell_singleton{};
77+
return &haswell_singleton;
78+
}
7379
#endif
7480
#if SIMDUTF_IMPLEMENTATION_WESTMERE
75-
const westmere::implementation westmere_singleton{};
81+
static const westmere::implementation* get_westmere_singleton() {
82+
static const westmere::implementation westmere_singleton{};
83+
return &westmere_singleton;
84+
}
7685
#endif
7786
#if SIMDUTF_IMPLEMENTATION_ARM64
78-
const arm64::implementation arm64_singleton{};
87+
static const arm64::implementation* get_arm64_singleton() {
88+
static const arm64::implementation arm64_singleton{};
89+
return &arm64_singleton;
90+
}
7991
#endif
8092
#if SIMDUTF_IMPLEMENTATION_PPC64
81-
const ppc64::implementation ppc64_singleton{};
93+
static const ppc64::implementation* get_ppc64_singleton() {
94+
static const ppc64::implementation ppc64_singleton{};
95+
return &ppc64_singleton;
96+
}
8297
#endif
8398
#if SIMDUTF_IMPLEMENTATION_FALLBACK
84-
const fallback::implementation fallback_singleton{};
99+
static const fallback::implementation* get_fallback_singleton() {
100+
static const fallback::implementation fallback_singleton{};
101+
return &fallback_singleton;
102+
}
85103
#endif
86104

87105
/**
@@ -311,27 +329,29 @@ class detect_best_supported_implementation_on_first_use final : public implement
311329
const implementation *set_best() const noexcept;
312330
};
313331

314-
315-
const std::initializer_list<const implementation *> available_implementation_pointers {
332+
static const std::initializer_list<const implementation *>& get_available_implementation_pointers() {
333+
static const std::initializer_list<const implementation *> available_implementation_pointers {
316334
#if SIMDUTF_IMPLEMENTATION_ICELAKE
317-
&icelake_singleton,
335+
get_icelake_singleton(),
318336
#endif
319337
#if SIMDUTF_IMPLEMENTATION_HASWELL
320-
&haswell_singleton,
338+
get_haswell_singleton(),
321339
#endif
322340
#if SIMDUTF_IMPLEMENTATION_WESTMERE
323-
&westmere_singleton,
341+
get_westmere_singleton(),
324342
#endif
325343
#if SIMDUTF_IMPLEMENTATION_ARM64
326-
&arm64_singleton,
344+
get_arm64_singleton(),
327345
#endif
328346
#if SIMDUTF_IMPLEMENTATION_PPC64
329-
&ppc64_singleton,
347+
get_ppc64_singleton(),
330348
#endif
331349
#if SIMDUTF_IMPLEMENTATION_FALLBACK
332-
&fallback_singleton,
350+
get_fallback_singleton(),
333351
#endif
334-
}; // available_implementation_pointers
352+
}; // available_implementation_pointers
353+
return available_implementation_pointers;
354+
}
335355

336356
// So we can return UNSUPPORTED_ARCHITECTURE from the parser when there is no support
337357
class unsupported_implementation final : public implementation {
@@ -561,18 +581,18 @@ class unsupported_implementation final : public implementation {
561581
const unsupported_implementation unsupported_singleton{};
562582

563583
size_t available_implementation_list::size() const noexcept {
564-
return internal::available_implementation_pointers.size();
584+
return internal::get_available_implementation_pointers().size();
565585
}
566586
const implementation * const *available_implementation_list::begin() const noexcept {
567-
return internal::available_implementation_pointers.begin();
587+
return internal::get_available_implementation_pointers().begin();
568588
}
569589
const implementation * const *available_implementation_list::end() const noexcept {
570-
return internal::available_implementation_pointers.end();
590+
return internal::get_available_implementation_pointers().end();
571591
}
572592
const implementation *available_implementation_list::detect_best_supported() const noexcept {
573593
// They are prelisted in priority order, so we just go down the list
574594
uint32_t supported_instruction_sets = internal::detect_supported_architectures();
575-
for (const implementation *impl : internal::available_implementation_pointers) {
595+
for (const implementation *impl : internal::get_available_implementation_pointers()) {
576596
uint32_t required_instruction_sets = impl->required_instruction_sets();
577597
if ((supported_instruction_sets & required_instruction_sets) == required_instruction_sets) { return impl; }
578598
}

0 commit comments

Comments
 (0)