TRLC Platform Library  1.0.0
Header-only C++ library for compile-time platform detection and abstraction
features.hpp
Go to the documentation of this file.
1 #pragma once
2 
15 #include <cstdint>
16 
17 // Include intrinsics headers for CPU feature detection
18 #if defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)
19  #if defined(_MSC_VER)
20  #include <intrin.h>
21  #elif defined(__GNUC__) || defined(__clang__)
22  #include <cpuid.h>
23  #include <immintrin.h>
24  #endif
25  #define TRLC_HAS_X86_INTRINSICS 1
26 #else
27  #define TRLC_HAS_X86_INTRINSICS 0
28 #endif
29 
30 #if defined(__ARM_NEON) || defined(__aarch64__)
31  #if defined(__GNUC__) || defined(__clang__)
32  #include <arm_neon.h>
33  #endif
34  #define TRLC_HAS_ARM_INTRINSICS 1
35 #else
36  #define TRLC_HAS_ARM_INTRINSICS 0
37 #endif
38 
39 namespace trlc {
40 namespace platform {
41 
49 enum class LanguageFeature : int {
50  exceptions = 0,
51  rtti,
52  threads,
61 };
62 
70 enum class RuntimeFeature : int {
71  sse = 0,
72  sse2,
73  sse3,
74  sse4_1,
75  sse4_2,
76  avx,
77  avx2,
78  avx512f,
79  neon,
80  hardware_aes,
82 };
83 
91 struct FeatureSet {
92  // Language features (compile-time determined)
94  bool has_rtti;
95  bool has_threads;
96  bool has_atomic;
104 
105  // Runtime features (may require runtime detection)
106  bool has_sse;
107  bool has_sse2;
108  bool has_sse3;
109  bool has_sse4_1;
110  bool has_sse4_2;
111  bool has_avx;
112  bool has_avx2;
113  bool has_avx512f;
114  bool has_neon;
117 
123  constexpr bool hasLanguageFeature(LanguageFeature feature) const noexcept {
124  switch (feature) {
126  return has_exceptions;
128  return has_rtti;
130  return has_threads;
132  return has_atomic;
134  return has_inline_asm;
136  return has_vector_intrinsics;
138  return has_stack_protection;
140  return has_address_sanitizer;
142  return has_thread_sanitizer;
144  return has_memory_sanitizer;
147  default:
148  return false;
149  }
150  }
151 
158  bool hasRuntimeFeature(RuntimeFeature feature) const noexcept {
159  switch (feature) {
160  case RuntimeFeature::sse:
161  return has_sse;
163  return has_sse2;
165  return has_sse3;
167  return has_sse4_1;
169  return has_sse4_2;
170  case RuntimeFeature::avx:
171  return has_avx;
173  return has_avx2;
175  return has_avx512f;
177  return has_neon;
179  return has_hardware_aes;
181  return has_hardware_random;
182  default:
183  return false;
184  }
185  }
186 };
187 
188 //
189 // Language feature detection functions
190 //
191 
196 constexpr bool hasExceptions() noexcept {
197 #ifdef __cpp_exceptions
198  return true;
199 #elif defined(__EXCEPTIONS) || defined(_CPPUNWIND)
200  return true;
201 #else
202  return false;
203 #endif
204 }
205 
210 constexpr bool hasRtti() noexcept {
211 #ifdef __cpp_rtti
212  return true;
213 #elif defined(__GXX_RTTI) || defined(_CPPRTTI)
214  return true;
215 #elif defined(__has_feature)
216  #if __has_feature(cxx_rtti)
217  return true;
218  #else
219  return false;
220  #endif
221 #else
222  return true; // Assume available by default
223 #endif
224 }
225 
230 constexpr bool hasThreads() noexcept {
231 #ifdef __STDCPP_THREADS__
232  return __STDCPP_THREADS__ == 1;
233 #elif defined(_REENTRANT) || defined(_MT)
234  return true;
235 #else
236  return false;
237 #endif
238 }
239 
244 constexpr bool hasAtomicOperations() noexcept {
245 #ifdef __cpp_lib_atomic_shared_ptr
246  return true;
247 #elif defined(__ATOMIC_RELAXED)
248  return true;
249 #elif defined(_MSC_VER)
250  return true; // MSVC has atomic support
251 #else
252  return true; // Assume available in C++17+
253 #endif
254 }
255 
260 constexpr bool hasInlineAssembly() noexcept {
261 #if defined(__GNUC__) || defined(__clang__)
262  return true;
263 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
264  return true;
265 #else
266  return false;
267 #endif
268 }
269 
274 constexpr bool hasVectorIntrinsics() noexcept {
276 }
277 
282 constexpr bool hasStackProtection() noexcept {
283 #ifdef __STACK_CHK_FAIL
284  return true;
285 #elif defined(__SSP__) || defined(__SSP_ALL__)
286  return true;
287 #elif defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
288  return true;
289 #else
290  return false;
291 #endif
292 }
293 
298 constexpr bool hasAddressSanitizer() noexcept {
299 #ifdef __has_feature
300  #if __has_feature(address_sanitizer)
301  return true;
302  #endif
303 #endif
304 #ifdef __SANITIZE_ADDRESS__
305  return true;
306 #else
307  return false;
308 #endif
309 }
310 
315 constexpr bool hasThreadSanitizer() noexcept {
316 #ifdef __has_feature
317  #if __has_feature(thread_sanitizer)
318  return true;
319  #endif
320 #endif
321 #ifdef __SANITIZE_THREAD__
322  return true;
323 #else
324  return false;
325 #endif
326 }
327 
332 constexpr bool hasMemorySanitizer() noexcept {
333 #ifdef __has_feature
334  #if __has_feature(memory_sanitizer)
335  return true;
336  #endif
337 #endif
338 #ifdef __SANITIZE_MEMORY__
339  return true;
340 #else
341  return false;
342 #endif
343 }
344 
349 constexpr bool hasUndefinedBehaviorSanitizer() noexcept {
350 #ifdef __has_feature
351  #if __has_feature(undefined_behavior_sanitizer)
352  return true;
353  #endif
354 #endif
355 #ifdef __SANITIZE_UNDEFINED__
356  return true;
357 #else
358  return false;
359 #endif
360 }
361 
362 //
363 // Runtime feature detection functions
364 //
365 
366 #if TRLC_HAS_X86_INTRINSICS
367 
368 namespace detail {
369 
376 inline void cpuid(uint32_t leaf, uint32_t subleaf, uint32_t regs[4]) noexcept {
377  #if defined(_MSC_VER)
378  __cpuidex(reinterpret_cast<int*>(regs), static_cast<int>(leaf), static_cast<int>(subleaf));
379  #elif defined(__GNUC__) || defined(__clang__)
380  __cpuid_count(leaf, subleaf, regs[0], regs[1], regs[2], regs[3]);
381  #else
382  regs[0] = regs[1] = regs[2] = regs[3] = 0;
383  #endif
384 }
385 
394 inline bool checkCpuFeature(uint32_t leaf, uint32_t subleaf, int reg, int bit) noexcept {
395  uint32_t regs[4];
396  cpuid(leaf, subleaf, regs);
397  return (regs[reg] & (1u << bit)) != 0;
398 }
399 
400 } // namespace detail
401 
402 #endif // TRLC_HAS_X86_INTRINSICS
403 
408 inline bool hasSseSupport() noexcept {
409 #if TRLC_HAS_X86_INTRINSICS
410  return detail::checkCpuFeature(1, 0, 3, 25); // EDX bit 25
411 #else
412  return false;
413 #endif
414 }
415 
420 inline bool hasSse2Support() noexcept {
421 #if TRLC_HAS_X86_INTRINSICS
422  return detail::checkCpuFeature(1, 0, 3, 26); // EDX bit 26
423 #else
424  return false;
425 #endif
426 }
427 
432 inline bool hasSse3Support() noexcept {
433 #if TRLC_HAS_X86_INTRINSICS
434  return detail::checkCpuFeature(1, 0, 2, 0); // ECX bit 0
435 #else
436  return false;
437 #endif
438 }
439 
444 inline bool hasSse41Support() noexcept {
445 #if TRLC_HAS_X86_INTRINSICS
446  return detail::checkCpuFeature(1, 0, 2, 19); // ECX bit 19
447 #else
448  return false;
449 #endif
450 }
451 
456 inline bool hasSse42Support() noexcept {
457 #if TRLC_HAS_X86_INTRINSICS
458  return detail::checkCpuFeature(1, 0, 2, 20); // ECX bit 20
459 #else
460  return false;
461 #endif
462 }
463 
468 inline bool hasAvxSupport() noexcept {
469 #if TRLC_HAS_X86_INTRINSICS
470  return detail::checkCpuFeature(1, 0, 2, 28); // ECX bit 28
471 #else
472  return false;
473 #endif
474 }
475 
480 inline bool hasAvx2Support() noexcept {
481 #if TRLC_HAS_X86_INTRINSICS
482  return detail::checkCpuFeature(7, 0, 1, 5); // EBX bit 5
483 #else
484  return false;
485 #endif
486 }
487 
492 inline bool hasAvx512fSupport() noexcept {
493 #if TRLC_HAS_X86_INTRINSICS
494  return detail::checkCpuFeature(7, 0, 1, 16); // EBX bit 16
495 #else
496  return false;
497 #endif
498 }
499 
504 inline bool hasNeonSupport() noexcept {
505 #if TRLC_HAS_ARM_INTRINSICS
506  #ifdef __ARM_NEON
507  return true;
508  #elif defined(__aarch64__)
509  return true; // NEON is mandatory on AArch64
510  #else
511  return false;
512  #endif
513 #else
514  return false;
515 #endif
516 }
517 
522 inline bool hasHardwareAes() noexcept {
523 #if TRLC_HAS_X86_INTRINSICS
524  return detail::checkCpuFeature(1, 0, 2, 25); // ECX bit 25
525 #elif TRLC_HAS_ARM_INTRINSICS && defined(__ARM_FEATURE_AES)
526  return true;
527 #else
528  return false;
529 #endif
530 }
531 
536 inline bool hasHardwareRandom() noexcept {
537 #if TRLC_HAS_X86_INTRINSICS
538  return detail::checkCpuFeature(1, 0, 2, 30); // ECX bit 30 (RDRAND)
539 #else
540  return false;
541 #endif
542 }
543 
544 //
545 // Unified feature detection functions
546 //
547 
553 constexpr FeatureSet getFeatureSet() noexcept {
554  return FeatureSet{
555  // Language features (compile-time) - must match order in struct
556  hasExceptions(),
557  hasRtti(),
558  hasThreads(),
567 
568  // Runtime features (initialized to false, require runtime detection)
569  false, // has_sse
570  false, // has_sse2
571  false, // has_sse3
572  false, // has_sse4_1
573  false, // has_sse4_2
574  false, // has_avx
575  false, // has_avx2
576  false, // has_avx512f
577  false, // has_neon
578  false, // has_hardware_aes
579  false // has_hardware_random
580  };
581 }
582 
588 constexpr bool hasLanguageFeature(LanguageFeature feature) noexcept {
589  switch (feature) {
591  return hasExceptions();
593  return hasRtti();
595  return hasThreads();
597  return hasAtomicOperations();
599  return hasInlineAssembly();
601  return hasVectorIntrinsics();
603  return hasStackProtection();
605  return hasAddressSanitizer();
607  return hasThreadSanitizer();
609  return hasMemorySanitizer();
612  default:
613  return false;
614  }
615 }
616 
623 inline bool hasRuntimeFeature(RuntimeFeature feature) noexcept {
624  switch (feature) {
625  case RuntimeFeature::sse:
626  return hasSseSupport();
628  return hasSse2Support();
630  return hasSse3Support();
632  return hasSse41Support();
634  return hasSse42Support();
635  case RuntimeFeature::avx:
636  return hasAvxSupport();
638  return hasAvx2Support();
640  return hasAvx512fSupport();
642  return hasNeonSupport();
644  return hasHardwareAes();
646  return hasHardwareRandom();
647  default:
648  return false;
649  }
650 }
651 
658 template <LanguageFeature TFeature>
659 constexpr bool hasFeature() noexcept {
660  return hasLanguageFeature(TFeature);
661 }
662 
663 } // namespace platform
664 } // namespace trlc
665 
666 //
667 // Convenience macros for compile-time features
668 //
669 
671 #define TRLC_HAS_EXCEPTIONS (trlc::platform::hasExceptions())
672 
674 #define TRLC_HAS_RTTI (trlc::platform::hasRtti())
675 
677 #define TRLC_HAS_THREADS (trlc::platform::hasThreads())
678 
680 #define TRLC_HAS_ATOMIC (trlc::platform::hasAtomicOperations())
681 
683 #define TRLC_HAS_INLINE_ASM (trlc::platform::hasInlineAssembly())
684 
686 #define TRLC_HAS_VECTOR_INTRINSICS (trlc::platform::hasVectorIntrinsics())
687 
689 #define TRLC_HAS_STACK_PROTECTION (trlc::platform::hasStackProtection())
690 
692 #define TRLC_HAS_ADDRESS_SANITIZER (trlc::platform::hasAddressSanitizer())
693 
695 #define TRLC_HAS_THREAD_SANITIZER (trlc::platform::hasThreadSanitizer())
696 
698 #define TRLC_HAS_MEMORY_SANITIZER (trlc::platform::hasMemorySanitizer())
699 
701 #define TRLC_HAS_UNDEFINED_BEHAVIOR_SANITIZER (trlc::platform::hasUndefinedBehaviorSanitizer())
702 
704 #define TRLC_HAS_FEATURE(X) (trlc::platform::hasFeature<trlc::platform::LanguageFeature::X>())
705 
706 //
707 // Runtime feature macros (non-constexpr)
708 //
709 
711 #define TRLC_HAS_SSE_RUNTIME() (trlc::platform::hasSseSupport())
712 
714 #define TRLC_HAS_SSE2_RUNTIME() (trlc::platform::hasSse2Support())
715 
717 #define TRLC_HAS_SSE3_RUNTIME() (trlc::platform::hasSse3Support())
718 
720 #define TRLC_HAS_SSE41_RUNTIME() (trlc::platform::hasSse41Support())
721 
723 #define TRLC_HAS_SSE42_RUNTIME() (trlc::platform::hasSse42Support())
724 
726 #define TRLC_HAS_AVX_RUNTIME() (trlc::platform::hasAvxSupport())
727 
729 #define TRLC_HAS_AVX2_RUNTIME() (trlc::platform::hasAvx2Support())
730 
732 #define TRLC_HAS_AVX512F_RUNTIME() (trlc::platform::hasAvx512fSupport())
733 
735 #define TRLC_HAS_NEON_RUNTIME() (trlc::platform::hasNeonSupport())
736 
738 #define TRLC_HAS_HARDWARE_AES_RUNTIME() (trlc::platform::hasHardwareAes())
739 
741 #define TRLC_HAS_HARDWARE_RANDOM_RUNTIME() (trlc::platform::hasHardwareRandom())
742 
743 //
744 // Conditional compilation helpers
745 //
746 
748 #ifdef __cpp_exceptions
749  #define TRLC_IF_EXCEPTIONS(code) code
750 #elif defined(__EXCEPTIONS) || defined(_CPPUNWIND)
751  #define TRLC_IF_EXCEPTIONS(code) code
752 #else
753  #define TRLC_IF_EXCEPTIONS(code) ((void)0)
754 #endif
755 
757 #ifdef __cpp_rtti
758  #define TRLC_IF_RTTI(code) code
759 #elif defined(__GXX_RTTI) || defined(_CPPRTTI)
760  #define TRLC_IF_RTTI(code) code
761 #else
762  #define TRLC_IF_RTTI(code) ((void)0)
763 #endif
764 
766 #ifdef __STDCPP_THREADS__
767  #if __STDCPP_THREADS__ == 1
768  #define TRLC_IF_THREADS(code) code
769  #else
770  #define TRLC_IF_THREADS(code) ((void)0)
771  #endif
772 #elif defined(_REENTRANT) || defined(_MT)
773  #define TRLC_IF_THREADS(code) code
774 #else
775  #define TRLC_IF_THREADS(code) ((void)0)
776 #endif
#define TRLC_HAS_ARM_INTRINSICS
Definition: features.hpp:36
#define TRLC_HAS_X86_INTRINSICS
Definition: features.hpp:27
bool hasSseSupport()
Detects SSE support at runtime.
Definition: features.hpp:408
static bool hasUndefinedBehaviorSanitizer()
Detects if UndefinedBehaviorSanitizer is enabled.
Definition: features.hpp:349
bool hasAvx512fSupport()
Detects AVX-512F support at runtime.
Definition: features.hpp:492
static bool hasVectorIntrinsics()
Detects if vector intrinsics are available.
Definition: features.hpp:274
static bool hasAddressSanitizer()
Detects if AddressSanitizer is enabled.
Definition: features.hpp:298
static bool hasRtti()
Detects if RTTI (Runtime Type Information) is enabled.
Definition: features.hpp:210
static bool hasThreads()
Detects if threading support is available.
Definition: features.hpp:230
static bool hasInlineAssembly()
Detects if inline assembly is supported.
Definition: features.hpp:260
bool hasSse2Support()
Detects SSE2 support at runtime.
Definition: features.hpp:420
static bool hasExceptions()
Detects if C++ exceptions are enabled.
Definition: features.hpp:196
bool hasAvx2Support()
Detects AVX2 support at runtime.
Definition: features.hpp:480
bool hasSse3Support()
Detects SSE3 support at runtime.
Definition: features.hpp:432
LanguageFeature
Language feature enumeration.
Definition: features.hpp:49
@ threads
Threading support (std::thread)
@ exceptions
C++ exception handling support.
@ undefined_behavior_sanitizer
UndefinedBehaviorSanitizer support.
@ atomic_operations
Atomic operations support.
@ rtti
Runtime Type Information support.
@ inline_assembly
Inline assembly support.
@ memory_sanitizer
MemorySanitizer support.
@ stack_protection
Stack protection features.
@ address_sanitizer
AddressSanitizer support.
@ thread_sanitizer
ThreadSanitizer support.
@ vector_intrinsics
Vector/SIMD intrinsics support.
static bool hasStackProtection()
Detects if stack protection is enabled.
Definition: features.hpp:282
static FeatureSet getFeatureSet()
Gets a complete feature set with all detected features.
Definition: features.hpp:553
static bool hasLanguageFeature(LanguageFeature feature)
Checks if a specific language feature is available.
Definition: features.hpp:588
bool hasSse41Support()
Detects SSE4.1 support at runtime.
Definition: features.hpp:444
bool hasSse42Support()
Detects SSE4.2 support at runtime.
Definition: features.hpp:456
bool hasNeonSupport()
Detects ARM NEON support.
Definition: features.hpp:504
bool hasAvxSupport()
Detects AVX support at runtime.
Definition: features.hpp:468
static bool hasFeature()
Generic template function for feature testing.
Definition: features.hpp:659
static bool hasMemorySanitizer()
Detects if MemorySanitizer is enabled.
Definition: features.hpp:332
bool hasHardwareRandom()
Detects hardware random number generation support.
Definition: features.hpp:536
static bool hasThreadSanitizer()
Detects if ThreadSanitizer is enabled.
Definition: features.hpp:315
bool hasRuntimeFeature(RuntimeFeature feature)
Checks if a specific runtime feature is available.
Definition: features.hpp:623
bool hasHardwareAes()
Detects hardware AES support.
Definition: features.hpp:522
RuntimeFeature
Runtime feature enumeration.
Definition: features.hpp:70
@ avx512f
AVX-512 Foundation.
@ sse
SSE (Streaming SIMD Extensions)
@ sse4_1
SSE4.1 extensions.
@ avx
AVX (Advanced Vector Extensions)
@ neon
ARM NEON SIMD extensions.
@ hardware_aes
Hardware AES acceleration.
@ hardware_random
Hardware random number generation.
@ sse4_2
SSE4.2 extensions.
static bool hasAtomicOperations()
Detects if atomic operations are supported.
Definition: features.hpp:244
Feature detection structure.
Definition: features.hpp:91
bool has_hardware_aes
Hardware AES support.
Definition: features.hpp:115
bool has_vector_intrinsics
Vector intrinsics available.
Definition: features.hpp:98
bool has_sse2
SSE2 support.
Definition: features.hpp:107
bool has_inline_asm
Inline assembly available.
Definition: features.hpp:97
bool has_rtti
RTTI available.
Definition: features.hpp:94
bool has_exceptions
Exception handling available.
Definition: features.hpp:93
bool has_sse
SSE support.
Definition: features.hpp:106
bool has_avx2
AVX2 support.
Definition: features.hpp:112
bool has_avx512f
AVX-512F support.
Definition: features.hpp:113
bool has_hardware_random
Hardware RNG support.
Definition: features.hpp:116
bool has_neon
ARM NEON support.
Definition: features.hpp:114
bool has_memory_sanitizer
MemorySanitizer enabled.
Definition: features.hpp:102
bool has_sse3
SSE3 support.
Definition: features.hpp:108
bool has_threads
Threading support available.
Definition: features.hpp:95
bool has_avx
AVX support.
Definition: features.hpp:111
bool has_atomic
Atomic operations available.
Definition: features.hpp:96
bool has_undefined_behavior_sanitizer
UBSan enabled.
Definition: features.hpp:103
static bool hasLanguageFeature(LanguageFeature feature) const
Checks if a specific language feature is available.
Definition: features.hpp:123
bool has_stack_protection
Stack protection enabled.
Definition: features.hpp:99
bool has_sse4_1
SSE4.1 support.
Definition: features.hpp:109
bool hasRuntimeFeature(RuntimeFeature feature) const
Checks if a specific runtime feature is available.
Definition: features.hpp:158
bool has_address_sanitizer
AddressSanitizer enabled.
Definition: features.hpp:100
bool has_thread_sanitizer
ThreadSanitizer enabled.
Definition: features.hpp:101
bool has_sse4_2
SSE4.2 support.
Definition: features.hpp:110