TRLC Platform Library  1.0.0
Header-only C++ library for compile-time platform detection and abstraction
macros.hpp
Go to the documentation of this file.
1 #pragma once
2 
23 namespace trlc {
24 namespace platform {
25 
30 constexpr bool supportsNodecard() noexcept {
31 #if defined(__has_cpp_attribute) && !defined(_MSC_VER)
32  return __has_cpp_attribute(nodiscard) >= 201603L;
33 #elif defined(_MSC_VER) && _MSC_VER >= 1911 // Visual Studio 2017 15.3
34  return true;
35 #else
36  return false;
37 #endif
38 }
39 
44 constexpr bool supportsDeprecated() noexcept {
45 #if defined(__has_cpp_attribute) && !defined(_MSC_VER)
46  return __has_cpp_attribute(deprecated) >= 201309L;
47 #elif defined(_MSC_VER)
48  return true; // MSVC has always supported deprecated
49 #else
50  return false;
51 #endif
52 }
53 
58 constexpr bool supportsFallthrough() noexcept {
59 #if defined(__has_cpp_attribute) && !defined(_MSC_VER)
60  return __has_cpp_attribute(fallthrough) >= 201603L;
61 #elif defined(_MSC_VER) && _MSC_VER >= 1911 // Visual Studio 2017 15.3
62  return true;
63 #else
64  return false;
65 #endif
66 }
67 
73 constexpr bool hasAttributeSupport(const char* /* attribute_name */) noexcept {
74  // This is a placeholder for a more sophisticated implementation
75  // that could check attribute support by name at compile time
76  return false;
77 }
78 
79 } // namespace platform
80 } // namespace trlc
81 
82 // =============================================================================
83 // Core Attribute Detection
84 // =============================================================================
85 
93 #if defined(__has_cpp_attribute) && !defined(_MSC_VER)
94  #define TRLC_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
95 #else
96  #define TRLC_HAS_CPP_ATTRIBUTE(x) 0
97 #endif
98 
105 #ifdef __has_builtin
106  #define TRLC_HAS_BUILTIN(x) __has_builtin(x)
107 #else
108  #define TRLC_HAS_BUILTIN(x) 0
109 #endif
110 
111 // =============================================================================
112 // Portable C++ Attributes
113 // =============================================================================
114 
126 #if TRLC_HAS_CPP_ATTRIBUTE(nodiscard) >= 201603L
127  #define TRLC_NODISCARD [[nodiscard]]
128 #elif defined(_MSC_VER) && _MSC_VER >= 1911 // Visual Studio 2017 15.3 supports [[nodiscard]]
129  #define TRLC_NODISCARD [[nodiscard]]
130 #elif defined(__GNUC__) || defined(__clang__)
131  #define TRLC_NODISCARD __attribute__((warn_unused_result))
132 #elif defined(_MSC_VER) && _MSC_VER >= 1700
133  #define TRLC_NODISCARD _Check_return_
134 #else
135  #define TRLC_NODISCARD
136 #endif
137 
149 #if TRLC_HAS_CPP_ATTRIBUTE(deprecated) >= 201309L
150  #define TRLC_DEPRECATED [[deprecated]]
151 #elif defined(_MSC_VER) && _MSC_VER >= 1400 // MSVC has supported [[deprecated]] since VS2005
152  #define TRLC_DEPRECATED [[deprecated]]
153 #elif defined(__GNUC__) || defined(__clang__)
154  #define TRLC_DEPRECATED __attribute__((deprecated))
155 #elif defined(_MSC_VER)
156  #define TRLC_DEPRECATED __declspec(deprecated)
157 #else
158  #define TRLC_DEPRECATED
159 #endif
160 
173 #if TRLC_HAS_CPP_ATTRIBUTE(deprecated) >= 201309L
174  #define TRLC_DEPRECATED_MSG(msg) [[deprecated(msg)]]
175 #elif defined(_MSC_VER) && _MSC_VER >= 1400
176  #define TRLC_DEPRECATED_MSG(msg) [[deprecated(msg)]]
177 #elif defined(__GNUC__) || defined(__clang__)
178  #define TRLC_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
179 #elif defined(_MSC_VER)
180  #define TRLC_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
181 #else
182  #define TRLC_DEPRECATED_MSG(msg) TRLC_DEPRECATED
183 #endif
184 
203 #if TRLC_HAS_CPP_ATTRIBUTE(fallthrough) >= 201603L
204  #define TRLC_FALLTHROUGH [[fallthrough]]
205 #elif defined(_MSC_VER) && _MSC_VER >= 1911 // Visual Studio 2017 15.3 supports [[fallthrough]]
206  #define TRLC_FALLTHROUGH [[fallthrough]]
207 #elif defined(__GNUC__) && __GNUC__ >= 7
208  #define TRLC_FALLTHROUGH __attribute__((fallthrough))
209 #elif defined(__clang__) && TRLC_HAS_CPP_ATTRIBUTE(clang::fallthrough)
210  #define TRLC_FALLTHROUGH [[clang::fallthrough]]
211 #else
212  #define TRLC_FALLTHROUGH ((void)0)
213 #endif
214 
229 #if TRLC_HAS_CPP_ATTRIBUTE(maybe_unused) >= 201603L
230  #define TRLC_MAYBE_UNUSED [[maybe_unused]]
231 #elif defined(__GNUC__) || defined(__clang__)
232  #define TRLC_MAYBE_UNUSED __attribute__((unused))
233 #else
234  #define TRLC_MAYBE_UNUSED
235 #endif
236 
237 // =============================================================================
238 // Inlining Control
239 // =============================================================================
240 
252 #if defined(__GNUC__) || defined(__clang__)
253  #define TRLC_FORCE_INLINE __attribute__((always_inline)) inline
254 #elif defined(_MSC_VER)
255  #define TRLC_FORCE_INLINE __forceinline
256 #elif defined(__INTEL_COMPILER)
257  #define TRLC_FORCE_INLINE __forceinline
258 #else
259  #define TRLC_FORCE_INLINE inline
260 #endif
261 
273 #if defined(__GNUC__) || defined(__clang__)
274  #define TRLC_NEVER_INLINE __attribute__((noinline))
275 #elif defined(_MSC_VER)
276  #define TRLC_NEVER_INLINE __declspec(noinline)
277 #elif defined(__INTEL_COMPILER)
278  #define TRLC_NEVER_INLINE __declspec(noinline)
279 #else
280  #define TRLC_NEVER_INLINE
281 #endif
282 
293 #define TRLC_INLINE inline
294 
295 // =============================================================================
296 // Branch Prediction Hints
297 // =============================================================================
298 
315 #if defined(__GNUC__) || defined(__clang__)
316  #define TRLC_LIKELY(x) __builtin_expect(!!(x), 1)
317 #elif defined(__INTEL_COMPILER)
318  #define TRLC_LIKELY(x) __builtin_expect(!!(x), 1)
319 #else
320  #define TRLC_LIKELY(x) (x)
321 #endif
322 
339 #if defined(__GNUC__) || defined(__clang__)
340  #define TRLC_UNLIKELY(x) __builtin_expect(!!(x), 0)
341 #elif defined(__INTEL_COMPILER)
342  #define TRLC_UNLIKELY(x) __builtin_expect(!!(x), 0)
343 #else
344  #define TRLC_UNLIKELY(x) (x)
345 #endif
346 
347 // =============================================================================
348 // Exception Safety
349 // =============================================================================
350 
364 #if !defined(__cpp_exceptions) || __cpp_exceptions == 0 || \
365  defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0
366  #define TRLC_NOEXCEPT
367  #define TRLC_HAS_EXCEPTIONS_ENABLED 0
368 #else
369  #define TRLC_NOEXCEPT noexcept
370  #define TRLC_HAS_EXCEPTIONS_ENABLED 1
371 #endif
372 
388 #if TRLC_HAS_EXCEPTIONS_ENABLED
389  #define TRLC_NOEXCEPT_IF(cond) noexcept(cond)
390 #else
391  #define TRLC_NOEXCEPT_IF(cond)
392 #endif
393 
394 // =============================================================================
395 // Symbol Visibility Control
396 // =============================================================================
397 
412 #if defined(_WIN32) || defined(_WIN64)
413  #define TRLC_API_EXPORT __declspec(dllexport)
414 #elif defined(__GNUC__) || defined(__clang__)
415  #define TRLC_API_EXPORT __attribute__((visibility("default")))
416 #elif defined(__INTEL_COMPILER)
417  #define TRLC_API_EXPORT __attribute__((visibility("default")))
418 #else
419  #define TRLC_API_EXPORT
420 #endif
421 
433 #if defined(_WIN32) || defined(_WIN64)
434  #define TRLC_API_IMPORT __declspec(dllimport)
435 #elif defined(__GNUC__) || defined(__clang__)
436  #define TRLC_API_IMPORT __attribute__((visibility("default")))
437 #elif defined(__INTEL_COMPILER)
438  #define TRLC_API_IMPORT __attribute__((visibility("default")))
439 #else
440  #define TRLC_API_IMPORT
441 #endif
442 
456 #if defined(__GNUC__) || defined(__clang__)
457  #define TRLC_API_HIDDEN __attribute__((visibility("hidden")))
458 #elif defined(__INTEL_COMPILER)
459  #define TRLC_API_HIDDEN __attribute__((visibility("hidden")))
460 #else
461  #define TRLC_API_HIDDEN
462 #endif
463 
478 #ifdef TRLC_BUILDING_SHARED
479  #define TRLC_API TRLC_API_EXPORT
480 #else
481  #define TRLC_API TRLC_API_IMPORT
482 #endif
483 
484 // =============================================================================
485 // C++ Standard Detection
486 // =============================================================================
487 
494 #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
495  #define TRLC_HAS_CPP17 1
496 #else
497  #define TRLC_HAS_CPP17 0
498 #endif
499 
500 // =============================================================================
501 // Utility Macros
502 // =============================================================================
503 
524 // TRLC_CONSTEXPR_IF is defined in cpp_standard.hpp
525 
537 #if defined(__GNUC__) || defined(__clang__)
538  #define TRLC_RESTRICT __restrict__
539 #elif defined(_MSC_VER)
540  #define TRLC_RESTRICT __restrict
541 #elif defined(__INTEL_COMPILER)
542  #define TRLC_RESTRICT __restrict
543 #else
544  #define TRLC_RESTRICT
545 #endif
546 
561 #if defined(__GNUC__) || defined(__clang__)
562  #define TRLC_PACKED __attribute__((packed))
563 #elif defined(_MSC_VER)
564  #define TRLC_PACKED
565  #define TRLC_PACK_BEGIN __pragma(pack(push, 1))
566  #define TRLC_PACK_END __pragma(pack(pop))
567 #else
568  #define TRLC_PACKED
569  #define TRLC_PACK_BEGIN
570  #define TRLC_PACK_END
571 #endif
572 
573 #ifndef TRLC_PACK_BEGIN
574  #define TRLC_PACK_BEGIN
575  #define TRLC_PACK_END
576 #endif
577 
590 #if defined(__GNUC__) || defined(__clang__)
591  #define TRLC_ALIGNED(bytes) __attribute__((aligned(bytes)))
592 #elif defined(_MSC_VER)
593  #define TRLC_ALIGNED(bytes) __declspec(align(bytes))
594 #elif defined(__INTEL_COMPILER)
595  #define TRLC_ALIGNED(bytes) __declspec(align(bytes))
596 #else
597  #define TRLC_ALIGNED(bytes)
598 #endif
599 
610 #define TRLC_CACHE_ALIGNED TRLC_ALIGNED(64)
611 
626 #if defined(__GNUC__) || defined(__clang__)
627  #define TRLC_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
628  #define TRLC_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
629  #define TRLC_DIAGNOSTIC_IGNORE_UNUSED_PARAMETER \
630  _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
631  #define TRLC_DIAGNOSTIC_IGNORE_UNUSED_VARIABLE \
632  _Pragma("GCC diagnostic ignored \"-Wunused-variable\"")
633  #define TRLC_DIAGNOSTIC_IGNORE_UNUSED_FUNCTION \
634  _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
635 #elif defined(_MSC_VER)
636  #define TRLC_DIAGNOSTIC_PUSH __pragma(warning(push))
637  #define TRLC_DIAGNOSTIC_POP __pragma(warning(pop))
638  #define TRLC_DIAGNOSTIC_IGNORE_UNUSED_PARAMETER __pragma(warning(disable : 4100))
639  #define TRLC_DIAGNOSTIC_IGNORE_UNUSED_VARIABLE __pragma(warning(disable : 4101))
640  #define TRLC_DIAGNOSTIC_IGNORE_UNUSED_FUNCTION __pragma(warning(disable : 4505))
641 #else
642  #define TRLC_DIAGNOSTIC_PUSH
643  #define TRLC_DIAGNOSTIC_POP
644  #define TRLC_DIAGNOSTIC_IGNORE_UNUSED_PARAMETER
645  #define TRLC_DIAGNOSTIC_IGNORE_UNUSED_VARIABLE
646  #define TRLC_DIAGNOSTIC_IGNORE_UNUSED_FUNCTION
647 #endif
648 
649 // =============================================================================
650 // Conditional Compilation Helpers
651 // =============================================================================
652 
668 #define TRLC_IF(condition, code) \
669  do { \
670  if constexpr (condition) { \
671  code; \
672  } \
673  } while (0)
674 
692 #define TRLC_IF_ELSE(condition, then_code, else_code) \
693  do { \
694  if constexpr (condition) { \
695  then_code; \
696  } else { \
697  else_code; \
698  } \
699  } while (0)
700 
701 // =============================================================================
702 // Compiler Bug Workarounds
703 // =============================================================================
704 
722 #define TRLC_USE(var) ((void)(var))
723 
739 #if defined(__GNUC__) || defined(__clang__)
740  #define TRLC_UNREACHABLE() __builtin_unreachable()
741 #elif defined(_MSC_VER)
742  #define TRLC_UNREACHABLE() __assume(0)
743 #else
744  #define TRLC_UNREACHABLE() ((void)0)
745 #endif
746 
758 #define TRLC_STRINGIFY(x) #x
759 #define TRLC_STRINGIFY_EXPANDED(x) TRLC_STRINGIFY(x)
760 #define TRLC_CONCAT(a, b) a##b
761 #define TRLC_CONCAT_EXPANDED(a, b) TRLC_CONCAT(a, b)
762 
763 // =============================================================================
764 // Feature Test Helpers
765 // =============================================================================
766 
784 #define TRLC_FEATURE_AVAILABLE(feature) (TRLC_HAS_##feature)
785 
803 #if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
804  #define TRLC_ON_WINDOWS(code) code
805  #define TRLC_ON_POSIX(code)
806  #define TRLC_PLATFORM_WINDOWS 1
807  #define TRLC_PLATFORM_POSIX 0
808 #elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
809  #define TRLC_ON_WINDOWS(code)
810  #define TRLC_ON_POSIX(code) code
811  #define TRLC_PLATFORM_WINDOWS 0
812  #define TRLC_PLATFORM_POSIX 1
813 #else
814  #define TRLC_ON_WINDOWS(code)
815  #define TRLC_ON_POSIX(code)
816  #define TRLC_PLATFORM_WINDOWS 0
817  #define TRLC_PLATFORM_POSIX 0
818 #endif
819 
837 #if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || \
838  defined(_M_X64)
839  #define TRLC_ON_X86_64(code) code
840  #define TRLC_ARCH_X86_64 1
841 #else
842  #define TRLC_ON_X86_64(code)
843  #define TRLC_ARCH_X86_64 0
844 #endif
845 
846 #if defined(__aarch64__) || defined(_M_ARM64)
847  #define TRLC_ON_ARM64(code) code
848  #define TRLC_ARCH_ARM64 1
849 #else
850  #define TRLC_ON_ARM64(code)
851  #define TRLC_ARCH_ARM64 0
852 #endif
853 
854 // =============================================================================
855 // Version and Compatibility
856 // =============================================================================
857 
863 #define TRLC_MACROS_VERSION_MAJOR 1
864 #define TRLC_MACROS_VERSION_MINOR 0
865 #define TRLC_MACROS_VERSION_PATCH 0
866 #define TRLC_MACROS_VERSION_STRING "1.0.0"
867 
882 #define TRLC_MACROS_VERSION_AT_LEAST(major, minor, patch) \
883  ((TRLC_MACROS_VERSION_MAJOR > (major)) || \
884  (TRLC_MACROS_VERSION_MAJOR == (major) && TRLC_MACROS_VERSION_MINOR > (minor)) || \
885  (TRLC_MACROS_VERSION_MAJOR == (major) && TRLC_MACROS_VERSION_MINOR == (minor) && \
886  TRLC_MACROS_VERSION_PATCH >= (patch)))
887 
888 // Mark this header as successfully included
889 #define TRLC_MACROS_INCLUDED
890 
891 // =============================================================================
892 // End of macros.hpp
893 // =============================================================================
static bool supportsDeprecated()
Check if compiler supports deprecated attribute.
Definition: macros.hpp:44
static bool supportsFallthrough()
Check if compiler supports fallthrough attribute.
Definition: macros.hpp:58
static bool supportsNodecard()
Check if compiler supports nodiscard attribute.
Definition: macros.hpp:30
static bool hasAttributeSupport(const char *)
Check if compiler supports a specific C++ attribute.
Definition: macros.hpp:73