1 // CODYlib -*- mode:c++ -*-
2 // Copyright (C) 2020 Nathan Sidwell, nathan@acm.org
3 // License: Apache v2.0
8 #define __has_builtin(X) 0
11 #define __has_include(X) 0
15 #if __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE)
16 #define CODY_LOC_BUILTIN 1
17 #elif __has_include (<source_location>)
18 #include <source_location>
19 #ifdef __cpp_lib_source_location
20 #define CODY_LOC_SOURCE 1
29 // Location is needed regardless of checking, to make the fatal
38 constexpr Location (char const *file_
41 #elif !CODY_LOC_SOURCE
47 #elif !CODY_LOC_SOURCE
51 :file (file_
), line (line_
)
55 #if !CODY_LOC_BUILTIN && CODY_LOC_SOURCE
56 using source_location
= std::source_location
;
58 constexpr Location (source_location loc
= source_location::current ())
59 : Location (loc
.file (), loc
.line ())
65 constexpr char const *File () const
69 constexpr unsigned Line () const
79 , Location
const = Location ()
80 #if !CODY_LOC_BUILTIN && !CODY_LOC_SOURCE
81 #define HCF(M) HCF ((M), Cody::Location (__FILE__, __LINE__))
87 void AssertFailed
[[noreturn
]] (Location loc
= Location ()) noexcept
;
88 void Unreachable
[[noreturn
]] (Location loc
= Location ()) noexcept
;
89 #if !CODY_LOC_BUILTIN && !CODY_LOC_SOURCE
90 #define AssertFailed() AssertFailed (Cody::Location (__FILE__, __LINE__))
91 #define Unreachable() Unreachable (Cody::Location (__FILE__, __LINE__))
94 // Do we have __VA_OPT__, alas no specific feature macro for it :(
95 // From stack overflow
96 // https://stackoverflow.com/questions/48045470/portably-detect-va-opt-support
97 // Relies on having variadic macros, but they're a C++11 thing, so
99 #define HAVE_ARG_3(a,b,c,...) c
100 #define HAVE_VA_OPT_(...) HAVE_ARG_3(__VA_OPT__(,),true,false,)
101 #define HAVE_VA_OPT HAVE_VA_OPT_(?)
103 // Oh, for lazily evaluated function parameters
105 // Assert is variadic, so you can write Assert (TPL<A,B>(C)) without
106 // extraneous parens. I don't think we need that though.
107 #define Assert(EXPR, ...) \
108 (__builtin_expect (bool (EXPR __VA_OPT__ (, __VA_ARGS__)), true) \
109 ? (void)0 : AssertFailed ())
111 // If you don't have the GNU ,##__VA_ARGS__ pasting extension, we'll
112 // need another fallback
113 #define Assert(EXPR, ...) \
114 (__builtin_expect (bool (EXPR, ##__VA_ARGS__), true) \
115 ? (void)0 : AssertFailed ())
118 // Not asserting, use EXPR in an unevaluated context
120 #define Assert(EXPR, ...) \
121 ((void)sizeof (bool (EXPR __VA_OPT__ (, __VA_ARGS__))), (void)0)
123 #define Assert(EXPR, ...) \
124 ((void)sizeof (bool (EXPR, ##__VA_ARGS__)), (void)0)
127 inline void Unreachable () noexcept
129 __builtin_unreachable ();