TRLC Platform Library  1.0.0
Header-only C++ library for compile-time platform detection and abstraction
compiler.hpp
Go to the documentation of this file.
1 #pragma once
2 
68 namespace trlc {
69 namespace platform {
70 
120 enum class CompilerType : int {
121  unknown = 0,
122  gcc,
123  clang,
124  msvc,
125  intel_classic,
126  intel_llvm,
127  mingw
128 };
129 
176  int major;
177  int minor;
178  int patch;
179 
194  constexpr CompilerVersion(int maj, int min, int pat = 0) noexcept
195  : major(maj), minor(min), patch(pat) {}
196 
206  constexpr CompilerVersion() noexcept : major(0), minor(0), patch(0) {}
207 
230  constexpr bool operator>=(const CompilerVersion& other) const noexcept {
231  if (major != other.major)
232  return major > other.major;
233  if (minor != other.minor)
234  return minor > other.minor;
235  return patch >= other.patch;
236  }
237 
252  constexpr bool operator<(const CompilerVersion& other) const noexcept {
253  if (major != other.major)
254  return major < other.major;
255  if (minor != other.minor)
256  return minor < other.minor;
257  return patch < other.patch;
258  }
259 
274  constexpr bool operator==(const CompilerVersion& other) const noexcept {
275  return major == other.major && minor == other.minor && patch == other.patch;
276  }
277 
291  constexpr bool operator!=(const CompilerVersion& other) const noexcept {
292  return !(*this == other);
293  }
294 
300  constexpr bool operator>(const CompilerVersion& other) const noexcept {
301  return !(*this < other) && !(*this == other);
302  }
303 
309  constexpr bool operator<=(const CompilerVersion& other) const noexcept {
310  return (*this < other) || (*this == other);
311  }
312 };
313 
323 constexpr CompilerType getCompilerType() noexcept {
324 // Check for Intel compilers first (they may also define GCC/Clang macros)
325 #if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC)
326  #if defined(__clang__)
327  return CompilerType::intel_llvm; // Intel C++ Compiler based on LLVM
328  #else
329  return CompilerType::intel_classic; // Legacy Intel C++ Compiler
330  #endif
331 // Check for Clang (must be before GCC since Clang may define __GNUC__)
332 #elif defined(__clang__)
333  return CompilerType::clang;
334 // Check for GCC
335 #elif defined(__GNUC__)
336  #if defined(__MINGW32__) || defined(__MINGW64__)
337  return CompilerType::mingw;
338  #else
339  return CompilerType::gcc;
340  #endif
341 // Check for MSVC
342 #elif defined(_MSC_VER)
343  return CompilerType::msvc;
344 #else
345  return CompilerType::unknown;
346 #endif
347 }
348 
357 constexpr CompilerVersion getCompilerVersion() noexcept {
358 #if defined(__INTEL_COMPILER)
359  // Intel compiler version format: VVRR (VV = major, RR = minor)
360  return CompilerVersion(
361  __INTEL_COMPILER / 100, (__INTEL_COMPILER % 100) / 10, __INTEL_COMPILER % 10);
362 #elif defined(__clang__)
363  return CompilerVersion(__clang_major__, __clang_minor__, __clang_patchlevel__);
364 #elif defined(__GNUC__)
365  #if defined(__GNUC_PATCHLEVEL__)
366  return CompilerVersion(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
367  #else
368  return CompilerVersion(__GNUC__, __GNUC_MINOR__, 0);
369  #endif
370 #elif defined(_MSC_VER)
371  // MSVC version mapping (simplified)
372  #if _MSC_VER >= 1940 // Visual Studio 2022 17.10+
373  return CompilerVersion(19, 4, (_MSC_VER - 1940));
374  #elif _MSC_VER >= 1930 // Visual Studio 2022 17.0-17.9
375  return CompilerVersion(19, 3, (_MSC_VER - 1930));
376  #elif _MSC_VER >= 1920 // Visual Studio 2019
377  return CompilerVersion(19, 2, (_MSC_VER - 1920));
378  #elif _MSC_VER >= 1910 // Visual Studio 2017
379  return CompilerVersion(19, 1, (_MSC_VER - 1910));
380  #elif _MSC_VER >= 1900 // Visual Studio 2015
381  return CompilerVersion(19, 0, (_MSC_VER - 1900));
382  #else
383  return CompilerVersion(_MSC_VER / 100, (_MSC_VER % 100) / 10, _MSC_VER % 10);
384  #endif
385 #else
386  return CompilerVersion(0, 0, 0);
387 #endif
388 }
389 
398 constexpr const char* getCompilerName() noexcept {
399  switch (getCompilerType()) {
400  case CompilerType::gcc:
401  return "gcc";
402  case CompilerType::clang:
403  return "clang";
404  case CompilerType::msvc:
405  return "msvc";
407  return "intel_classic";
409  return "intel_llvm";
410  case CompilerType::mingw:
411  return "mingw";
413  default:
414  return "unknown";
415  }
416 }
417 
428 constexpr bool hasBuiltinAttribute([[maybe_unused]] const char* attribute_name) noexcept {
429  constexpr auto compiler = getCompilerType();
430  return compiler == CompilerType::gcc || compiler == CompilerType::clang ||
431  compiler == CompilerType::mingw || compiler == CompilerType::intel_llvm;
432 }
433 
441 constexpr bool supportsInlineAssembly() noexcept {
442  constexpr auto compiler = getCompilerType();
443  // MSVC has different inline assembly syntax and limitations
444  return compiler == CompilerType::gcc || compiler == CompilerType::clang ||
445  compiler == CompilerType::mingw || compiler == CompilerType::intel_classic ||
446  compiler == CompilerType::intel_llvm;
447 }
448 
456 constexpr bool hasColorDiagnostics() noexcept {
457  constexpr auto compiler = getCompilerType();
458  return compiler == CompilerType::gcc || compiler == CompilerType::clang ||
459  compiler == CompilerType::mingw || compiler == CompilerType::intel_llvm;
460 }
461 
462 //==============================================================================
463 // Consolidated Compiler Information
464 //==============================================================================
465 
472 struct CompilerInfo {
475  const char* name;
479 
485  constexpr bool isAtLeast(const CompilerVersion& min_version) const noexcept {
486  return version >= min_version;
487  }
488 
493  constexpr bool isGccCompatible() const noexcept {
496  }
497 
502  constexpr bool isClangCompatible() const noexcept {
504  }
505 };
506 
517 constexpr CompilerInfo getCompilerInfo() noexcept {
518  return CompilerInfo{getCompilerType(),
520  getCompilerName(),
521  hasBuiltinAttribute(""), // Generic builtin support check
524 }
525 
526 } // namespace platform
527 } // namespace trlc
528 
529 // Convenience macros for conditional compilation
530 
534 #if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC)
535  #define TRLC_COMPILER_GCC 0
536 #elif defined(__clang__)
537  #define TRLC_COMPILER_GCC 0
538 #elif defined(__GNUC__)
539  #if defined(__MINGW32__) || defined(__MINGW64__)
540  #define TRLC_COMPILER_GCC 0 // MinGW is separate
541  #else
542  #define TRLC_COMPILER_GCC 1
543  #endif
544 #else
545  #define TRLC_COMPILER_GCC 0
546 #endif
547 
551 #if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC)
552  #if defined(__clang__)
553  #define TRLC_COMPILER_CLANG 0 // Intel LLVM-based, not pure Clang
554  #else
555  #define TRLC_COMPILER_CLANG 0
556  #endif
557 #elif defined(__clang__)
558  #define TRLC_COMPILER_CLANG 1
559 #else
560  #define TRLC_COMPILER_CLANG 0
561 #endif
562 
566 #if defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER)
567  #define TRLC_COMPILER_MSVC 1
568 #else
569  #define TRLC_COMPILER_MSVC 0
570 #endif
571 
575 #if defined(__INTEL_COMPILER) && !defined(__clang__)
576  #define TRLC_COMPILER_INTEL 1
577 #else
578  #define TRLC_COMPILER_INTEL 0
579 #endif
580 
584 #if (defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC)) && defined(__clang__)
585  #define TRLC_COMPILER_INTEL_LLVM 1
586 #else
587  #define TRLC_COMPILER_INTEL_LLVM 0
588 #endif
589 
593 #if defined(__GNUC__) && (defined(__MINGW32__) || defined(__MINGW64__))
594  #define TRLC_COMPILER_MINGW 1
595 #else
596  #define TRLC_COMPILER_MINGW 0
597 #endif
598 
602 #if defined(__INTEL_COMPILER)
603  #define TRLC_COMPILER_VERSION_MAJOR (__INTEL_COMPILER / 100)
604  #define TRLC_COMPILER_VERSION_MINOR ((__INTEL_COMPILER % 100) / 10)
605  #define TRLC_COMPILER_VERSION_PATCH (__INTEL_COMPILER % 10)
606 #elif defined(__clang__)
607  #define TRLC_COMPILER_VERSION_MAJOR __clang_major__
608  #define TRLC_COMPILER_VERSION_MINOR __clang_minor__
609  #define TRLC_COMPILER_VERSION_PATCH __clang_patchlevel__
610 #elif defined(__GNUC__)
611  #define TRLC_COMPILER_VERSION_MAJOR __GNUC__
612  #define TRLC_COMPILER_VERSION_MINOR __GNUC_MINOR__
613  #ifdef __GNUC_PATCHLEVEL__
614  #define TRLC_COMPILER_VERSION_PATCH __GNUC_PATCHLEVEL__
615  #else
616  #define TRLC_COMPILER_VERSION_PATCH 0
617  #endif
618 #elif defined(_MSC_VER)
619  #if _MSC_VER >= 1940
620  #define TRLC_COMPILER_VERSION_MAJOR 19
621  #define TRLC_COMPILER_VERSION_MINOR 4
622  #define TRLC_COMPILER_VERSION_PATCH (_MSC_VER - 1940)
623  #elif _MSC_VER >= 1930
624  #define TRLC_COMPILER_VERSION_MAJOR 19
625  #define TRLC_COMPILER_VERSION_MINOR 3
626  #define TRLC_COMPILER_VERSION_PATCH (_MSC_VER - 1930)
627  #elif _MSC_VER >= 1920
628  #define TRLC_COMPILER_VERSION_MAJOR 19
629  #define TRLC_COMPILER_VERSION_MINOR 2
630  #define TRLC_COMPILER_VERSION_PATCH (_MSC_VER - 1920)
631  #elif _MSC_VER >= 1910
632  #define TRLC_COMPILER_VERSION_MAJOR 19
633  #define TRLC_COMPILER_VERSION_MINOR 1
634  #define TRLC_COMPILER_VERSION_PATCH (_MSC_VER - 1910)
635  #elif _MSC_VER >= 1900
636  #define TRLC_COMPILER_VERSION_MAJOR 19
637  #define TRLC_COMPILER_VERSION_MINOR 0
638  #define TRLC_COMPILER_VERSION_PATCH (_MSC_VER - 1900)
639  #else
640  #define TRLC_COMPILER_VERSION_MAJOR (_MSC_VER / 100)
641  #define TRLC_COMPILER_VERSION_MINOR ((_MSC_VER % 100) / 10)
642  #define TRLC_COMPILER_VERSION_PATCH (_MSC_VER % 10)
643  #endif
644 #else
645  #define TRLC_COMPILER_VERSION_MAJOR 0
646  #define TRLC_COMPILER_VERSION_MINOR 0
647  #define TRLC_COMPILER_VERSION_PATCH 0
648 #endif
649 
656 #define TRLC_COMPILER_VERSION_ATLEAST(major, minor, patch) \
657  ((TRLC_COMPILER_VERSION_MAJOR > (major)) || \
658  (TRLC_COMPILER_VERSION_MAJOR == (major) && TRLC_COMPILER_VERSION_MINOR > (minor)) || \
659  (TRLC_COMPILER_VERSION_MAJOR == (major) && TRLC_COMPILER_VERSION_MINOR == (minor) && \
660  TRLC_COMPILER_VERSION_PATCH >= (patch)))
661 
665 #define TRLC_COMPILER_VERSION (trlc::platform::getCompilerVersion())
666 
670 #define TRLC_COMPILER_NAME (trlc::platform::getCompilerName())
static bool hasBuiltinAttribute([[maybe_unused]] const char *attribute_name)
Checks if compiler supports __builtin attributes.
Definition: compiler.hpp:428
static bool supportsInlineAssembly()
Checks if compiler supports inline assembly.
Definition: compiler.hpp:441
CompilerType
Compiler identification enumeration.
Definition: compiler.hpp:120
@ mingw
MinGW compiler (GCC-based for Windows) - Windows cross-compilation.
@ intel_classic
Legacy Intel C++ Compiler - Performance-optimized.
@ clang
Clang/LLVM compiler - Modern, standards-compliant.
@ msvc
Microsoft Visual C++ compiler - Windows-focused.
@ intel_llvm
Intel C++ Compiler based on LLVM - Modern Intel toolchain.
@ unknown
Unknown or unsupported compiler.
@ gcc
GNU Compiler Collection - Cross-platform, open-source.
static CompilerType getCompilerType()
Detects the current compiler type at compile time.
Definition: compiler.hpp:323
static bool hasColorDiagnostics()
Checks if compiler supports colored diagnostics.
Definition: compiler.hpp:456
static CompilerInfo getCompilerInfo()
Get consolidated compiler information.
Definition: compiler.hpp:517
static const char * getCompilerName()
Gets the compiler name as a string.
Definition: compiler.hpp:398
static CompilerVersion getCompilerVersion()
Gets the compiler version at compile time.
Definition: compiler.hpp:357
Consolidated compiler information structure.
Definition: compiler.hpp:472
bool has_inline_assembly
Supports inline assembly.
Definition: compiler.hpp:477
const char * name
Human-readable compiler name.
Definition: compiler.hpp:475
static bool isGccCompatible() const
Check if this is a GCC-compatible compiler.
Definition: compiler.hpp:493
bool has_builtin_attribute
Supports __has_builtin attributes.
Definition: compiler.hpp:476
CompilerVersion version
Compiler version information.
Definition: compiler.hpp:474
CompilerType type
Detected compiler type.
Definition: compiler.hpp:473
bool has_color_diagnostics
Supports colored diagnostic output.
Definition: compiler.hpp:478
static bool isAtLeast(const CompilerVersion &min_version) const
Check if compiler is at least the specified version.
Definition: compiler.hpp:485
static bool isClangCompatible() const
Check if this is a Clang-compatible compiler.
Definition: compiler.hpp:502
static bool operator>(const CompilerVersion &other) const
Greater than comparison.
Definition: compiler.hpp:300
static CompilerVersion(int maj, int min, int pat=0)
Constructs a compiler version.
Definition: compiler.hpp:194
static bool operator==(const CompilerVersion &other) const
Equality comparison.
Definition: compiler.hpp:274
static bool operator<(const CompilerVersion &other) const
Less than comparison.
Definition: compiler.hpp:252
int minor
Minor version number (e.g., 3 in GCC 9.3.0)
Definition: compiler.hpp:177
static bool operator>=(const CompilerVersion &other) const
Definition: compiler.hpp:230
int patch
Patch version number (e.g., 0 in GCC 9.3.0)
Definition: compiler.hpp:178
static CompilerVersion()
Default constructor for unknown version.
Definition: compiler.hpp:206
static bool operator!=(const CompilerVersion &other) const
Inequality comparison.
Definition: compiler.hpp:291
int major
Major version number (e.g., 9 in GCC 9.3.0)
Definition: compiler.hpp:176
static bool operator<=(const CompilerVersion &other) const
Less than or equal comparison.
Definition: compiler.hpp:309