1*bde483f2SJacob Faibussowitsch #ifndef PETSC_PREPROCESSOR_MACROS_H 2*bde483f2SJacob Faibussowitsch #define PETSC_PREPROCESSOR_MACROS_H 3*bde483f2SJacob Faibussowitsch 4*bde483f2SJacob Faibussowitsch #include <petscconf.h> 5*bde483f2SJacob Faibussowitsch #include <petscconf_poison.h> /* for PetscDefined() error checking */ 6*bde483f2SJacob Faibussowitsch 7*bde483f2SJacob Faibussowitsch /* ========================================================================== */ 8*bde483f2SJacob Faibussowitsch /* This facilitates using the C version of PETSc from C++ and the C++ version from C. */ 9*bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 10*bde483f2SJacob Faibussowitsch # define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_CXX 11*bde483f2SJacob Faibussowitsch #else 12*bde483f2SJacob Faibussowitsch # define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_C 13*bde483f2SJacob Faibussowitsch #endif 14*bde483f2SJacob Faibussowitsch 15*bde483f2SJacob Faibussowitsch /* ========================================================================== */ 16*bde483f2SJacob Faibussowitsch /* Since PETSc manages its own extern "C" handling users should never include PETSc include 17*bde483f2SJacob Faibussowitsch * files within extern "C". This will generate a compiler error if a user does put the include 18*bde483f2SJacob Faibussowitsch * file within an extern "C". 19*bde483f2SJacob Faibussowitsch */ 20*bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 21*bde483f2SJacob Faibussowitsch void assert_never_put_petsc_headers_inside_an_extern_c(int); void assert_never_put_petsc_headers_inside_an_extern_c(double); 22*bde483f2SJacob Faibussowitsch #endif 23*bde483f2SJacob Faibussowitsch 24*bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 25*bde483f2SJacob Faibussowitsch # define PETSC_RESTRICT PETSC_CXX_RESTRICT 26*bde483f2SJacob Faibussowitsch #else 27*bde483f2SJacob Faibussowitsch # define PETSC_RESTRICT PETSC_C_RESTRICT 28*bde483f2SJacob Faibussowitsch #endif 29*bde483f2SJacob Faibussowitsch 30*bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 31*bde483f2SJacob Faibussowitsch # define PETSC_INLINE PETSC_CXX_INLINE 32*bde483f2SJacob Faibussowitsch #else 33*bde483f2SJacob Faibussowitsch # define PETSC_INLINE PETSC_C_INLINE 34*bde483f2SJacob Faibussowitsch #endif 35*bde483f2SJacob Faibussowitsch 36*bde483f2SJacob Faibussowitsch #define PETSC_STATIC_INLINE static PETSC_INLINE 37*bde483f2SJacob Faibussowitsch 38*bde483f2SJacob Faibussowitsch #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */ 39*bde483f2SJacob Faibussowitsch # define PETSC_DLLEXPORT __declspec(dllexport) 40*bde483f2SJacob Faibussowitsch # define PETSC_DLLIMPORT __declspec(dllimport) 41*bde483f2SJacob Faibussowitsch # define PETSC_VISIBILITY_INTERNAL 42*bde483f2SJacob Faibussowitsch #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX) 43*bde483f2SJacob Faibussowitsch # define PETSC_DLLEXPORT __attribute__((visibility ("default"))) 44*bde483f2SJacob Faibussowitsch # define PETSC_DLLIMPORT __attribute__((visibility ("default"))) 45*bde483f2SJacob Faibussowitsch # define PETSC_VISIBILITY_INTERNAL __attribute__((visibility ("hidden"))) 46*bde483f2SJacob Faibussowitsch #elif !defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_C) 47*bde483f2SJacob Faibussowitsch # define PETSC_DLLEXPORT __attribute__((visibility ("default"))) 48*bde483f2SJacob Faibussowitsch # define PETSC_DLLIMPORT __attribute__((visibility ("default"))) 49*bde483f2SJacob Faibussowitsch # define PETSC_VISIBILITY_INTERNAL __attribute__((visibility ("hidden"))) 50*bde483f2SJacob Faibussowitsch #else 51*bde483f2SJacob Faibussowitsch # define PETSC_DLLEXPORT 52*bde483f2SJacob Faibussowitsch # define PETSC_DLLIMPORT 53*bde483f2SJacob Faibussowitsch # define PETSC_VISIBILITY_INTERNAL 54*bde483f2SJacob Faibussowitsch #endif 55*bde483f2SJacob Faibussowitsch 56*bde483f2SJacob Faibussowitsch #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */ 57*bde483f2SJacob Faibussowitsch # define PETSC_VISIBILITY_PUBLIC PETSC_DLLEXPORT 58*bde483f2SJacob Faibussowitsch #else /* Win32 users need this to import symbols from petsc.dll */ 59*bde483f2SJacob Faibussowitsch # define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT 60*bde483f2SJacob Faibussowitsch #endif 61*bde483f2SJacob Faibussowitsch 62*bde483f2SJacob Faibussowitsch /* Functions tagged with PETSC_EXTERN in the header files are always defined as extern "C" when 63*bde483f2SJacob Faibussowitsch * compiled with C++ so they may be used from C and are always visible in the shared libraries 64*bde483f2SJacob Faibussowitsch */ 65*bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 66*bde483f2SJacob Faibussowitsch # define PETSC_EXTERN extern "C" PETSC_VISIBILITY_PUBLIC 67*bde483f2SJacob Faibussowitsch # define PETSC_EXTERN_TYPEDEF extern "C" 68*bde483f2SJacob Faibussowitsch # define PETSC_INTERN extern "C" PETSC_VISIBILITY_INTERNAL 69*bde483f2SJacob Faibussowitsch #else 70*bde483f2SJacob Faibussowitsch # define PETSC_EXTERN extern PETSC_VISIBILITY_PUBLIC 71*bde483f2SJacob Faibussowitsch # define PETSC_EXTERN_TYPEDEF 72*bde483f2SJacob Faibussowitsch # define PETSC_INTERN extern PETSC_VISIBILITY_INTERNAL 73*bde483f2SJacob Faibussowitsch #endif 74*bde483f2SJacob Faibussowitsch 75*bde483f2SJacob Faibussowitsch #if defined(PETSC_USE_SINGLE_LIBRARY) 76*bde483f2SJacob Faibussowitsch # define PETSC_SINGLE_LIBRARY_INTERN PETSC_INTERN 77*bde483f2SJacob Faibussowitsch #else 78*bde483f2SJacob Faibussowitsch # define PETSC_SINGLE_LIBRARY_INTERN PETSC_EXTERN 79*bde483f2SJacob Faibussowitsch #endif 80*bde483f2SJacob Faibussowitsch 81*bde483f2SJacob Faibussowitsch /*MC 82*bde483f2SJacob Faibussowitsch PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler 83*bde483f2SJacob Faibussowitsch 84*bde483f2SJacob Faibussowitsch Synopsis: 85*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 86*bde483f2SJacob Faibussowitsch boolean PetscHasAttribute(name) 87*bde483f2SJacob Faibussowitsch 88*bde483f2SJacob Faibussowitsch Input Parameter: 89*bde483f2SJacob Faibussowitsch . name - The name of the attribute to test 90*bde483f2SJacob Faibussowitsch 91*bde483f2SJacob Faibussowitsch Notes: 92*bde483f2SJacob Faibussowitsch name should be identical to what you might pass to the __attribute__ declaration itself -- 93*bde483f2SJacob Faibussowitsch plain, unbroken text. 94*bde483f2SJacob Faibussowitsch 95*bde483f2SJacob Faibussowitsch As PetscHasAttribute() is wrapper over the function-like macro __has_attribute(), the exact 96*bde483f2SJacob Faibussowitsch type and value returned is implementation defined. In practice however, it usually returns 97*bde483f2SJacob Faibussowitsch the integer literal 1 if the attribute is supported, and integer literal 0 if the attribute 98*bde483f2SJacob Faibussowitsch is not supported. 99*bde483f2SJacob Faibussowitsch 100*bde483f2SJacob Faibussowitsch Example Usage: 101*bde483f2SJacob Faibussowitsch Typical usage is using the preprocessor 102*bde483f2SJacob Faibussowitsch 103*bde483f2SJacob Faibussowitsch .vb 104*bde483f2SJacob Faibussowitsch #if PetscHasAttribute(always_inline) 105*bde483f2SJacob Faibussowitsch # define MY_ALWAYS_INLINE __attribute__((always_inline)) 106*bde483f2SJacob Faibussowitsch #else 107*bde483f2SJacob Faibussowitsch # define MY_ALWAYS_INLINE 108*bde483f2SJacob Faibussowitsch #endif 109*bde483f2SJacob Faibussowitsch 110*bde483f2SJacob Faibussowitsch void foo(void) MY_ALWAYS_INLINE; 111*bde483f2SJacob Faibussowitsch .ve 112*bde483f2SJacob Faibussowitsch 113*bde483f2SJacob Faibussowitsch but it can also be used in regular code 114*bde483f2SJacob Faibussowitsch 115*bde483f2SJacob Faibussowitsch .vb 116*bde483f2SJacob Faibussowitsch if (PetscHasAttribute(some_attribute)) { 117*bde483f2SJacob Faibussowitsch foo(); 118*bde483f2SJacob Faibussowitsch } else { 119*bde483f2SJacob Faibussowitsch bar(); 120*bde483f2SJacob Faibussowitsch } 121*bde483f2SJacob Faibussowitsch .ve 122*bde483f2SJacob Faibussowitsch 123*bde483f2SJacob Faibussowitsch Level: intermediate 124*bde483f2SJacob Faibussowitsch 125*bde483f2SJacob Faibussowitsch .seealso: PetscDefined(), PetscLikely(), PetscUnlikely() 126*bde483f2SJacob Faibussowitsch M*/ 127*bde483f2SJacob Faibussowitsch #if !defined(__has_attribute) 128*bde483f2SJacob Faibussowitsch # define __has_attribute(x) 0 129*bde483f2SJacob Faibussowitsch #endif 130*bde483f2SJacob Faibussowitsch #define PetscHasAttribute(name) __has_attribute(name) 131*bde483f2SJacob Faibussowitsch 132*bde483f2SJacob Faibussowitsch /*MC 133*bde483f2SJacob Faibussowitsch PETSC_NULLPTR - Standard way of indicating a null value or pointer 134*bde483f2SJacob Faibussowitsch 135*bde483f2SJacob Faibussowitsch Notes: 136*bde483f2SJacob Faibussowitsch Equivalent to NULL in C source, and nullptr in C++ source. Note that for the purposes of 137*bde483f2SJacob Faibussowitsch interoperability between C and C++, setting a pointer to PETSC_NULLPTR in C++ is functonially 138*bde483f2SJacob Faibussowitsch equivalent to setting the same pointer to NULL in C. That is to say that the following 139*bde483f2SJacob Faibussowitsch expressions are equivalent\: 140*bde483f2SJacob Faibussowitsch 141*bde483f2SJacob Faibussowitsch .vb 142*bde483f2SJacob Faibussowitsch ptr == PETSC_NULLPTR 143*bde483f2SJacob Faibussowitsch ptr == NULL 144*bde483f2SJacob Faibussowitsch ptr == 0 145*bde483f2SJacob Faibussowitsch !ptr 146*bde483f2SJacob Faibussowitsch 147*bde483f2SJacob Faibussowitsch ptr = PETSC_NULLPTR 148*bde483f2SJacob Faibussowitsch ptr = NULL 149*bde483f2SJacob Faibussowitsch ptr = 0 150*bde483f2SJacob Faibussowitsch .ve 151*bde483f2SJacob Faibussowitsch 152*bde483f2SJacob Faibussowitsch and for completeness' sake\: 153*bde483f2SJacob Faibussowitsch 154*bde483f2SJacob Faibussowitsch .vb 155*bde483f2SJacob Faibussowitsch PETSC_NULLPTR == NULL 156*bde483f2SJacob Faibussowitsch .ve 157*bde483f2SJacob Faibussowitsch 158*bde483f2SJacob Faibussowitsch Fortran Notes: 159*bde483f2SJacob Faibussowitsch Not available in Fortran 160*bde483f2SJacob Faibussowitsch 161*bde483f2SJacob Faibussowitsch Example Usage: 162*bde483f2SJacob Faibussowitsch .vb 163*bde483f2SJacob Faibussowitsch // may be used in place of '\0' or other such teminators in the definition of char arrays 164*bde483f2SJacob Faibussowitsch const char *const MyEnumTypes[] = { 165*bde483f2SJacob Faibussowitsch "foo", 166*bde483f2SJacob Faibussowitsch "bar", 167*bde483f2SJacob Faibussowitsch PETSC_NULLPTR 168*bde483f2SJacob Faibussowitsch }; 169*bde483f2SJacob Faibussowitsch 170*bde483f2SJacob Faibussowitsch // may be used to nullify objects 171*bde483f2SJacob Faibussowitsch PetscObject obj = PETSC_NULLPTR; 172*bde483f2SJacob Faibussowitsch 173*bde483f2SJacob Faibussowitsch // may be used in any function expecting NULL 174*bde483f2SJacob Faibussowitsch PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor"); 175*bde483f2SJacob Faibussowitsch .ve 176*bde483f2SJacob Faibussowitsch 177*bde483f2SJacob Faibussowitsch Developer Notes: 178*bde483f2SJacob Faibussowitsch PETSC_NULLPTR must be used in place of NULL in all C++ source files. Using NULL in source 179*bde483f2SJacob Faibussowitsch files compiled with a C++ compiler may lead to unexpected side-effects in function overload 180*bde483f2SJacob Faibussowitsch resolution and/or compiler warnings. 181*bde483f2SJacob Faibussowitsch 182*bde483f2SJacob Faibussowitsch Level: beginner 183*bde483f2SJacob Faibussowitsch 184*bde483f2SJacob Faibussowitsch .seealso: PETSC_CONSTEXPR, PETSC_CONSTEXPR_14, PETSC_NOEXCEPT, PETSC_NODISCARD 185*bde483f2SJacob Faibussowitsch MC*/ 186*bde483f2SJacob Faibussowitsch 187*bde483f2SJacob Faibussowitsch /*MC 188*bde483f2SJacob Faibussowitsch PETSC_CONSTEXPR - C++ constexpr 189*bde483f2SJacob Faibussowitsch 190*bde483f2SJacob Faibussowitsch Notes: 191*bde483f2SJacob Faibussowitsch Equivalent to constexpr when using a C++ compiler that supports C++11. Expands to nothing 192*bde483f2SJacob Faibussowitsch if the C++ compiler does not suppport C++11 or when not compiling with a C++ compiler. Note 193*bde483f2SJacob Faibussowitsch that this cannot be used in cases where an empty expansion would result in invalid code. It 194*bde483f2SJacob Faibussowitsch is safe to use this in C source files. 195*bde483f2SJacob Faibussowitsch 196*bde483f2SJacob Faibussowitsch Fortran Notes: 197*bde483f2SJacob Faibussowitsch Not available in Fortran 198*bde483f2SJacob Faibussowitsch 199*bde483f2SJacob Faibussowitsch Example Usage: 200*bde483f2SJacob Faibussowitsch .vb 201*bde483f2SJacob Faibussowitsch PETSC_CONSTEXPR int factorial(int n) 202*bde483f2SJacob Faibussowitsch { 203*bde483f2SJacob Faibussowitsch return n <= 1 ? 1 : (n * factorial(n - 1)); 204*bde483f2SJacob Faibussowitsch } 205*bde483f2SJacob Faibussowitsch 206*bde483f2SJacob Faibussowitsch PETSC_CONSTEXPR auto foo = factorial(5); // foo = 125, deduced type of int 207*bde483f2SJacob Faibussowitsch .ve 208*bde483f2SJacob Faibussowitsch 209*bde483f2SJacob Faibussowitsch Level: beginner 210*bde483f2SJacob Faibussowitsch 211*bde483f2SJacob Faibussowitsch .seealso: PETSC_CONSTEXPR_14, PETSC_NOEXCEPT, PETSC_NULLPTR, PETSC_NODISCARD 212*bde483f2SJacob Faibussowitsch MC*/ 213*bde483f2SJacob Faibussowitsch 214*bde483f2SJacob Faibussowitsch /*MC 215*bde483f2SJacob Faibussowitsch PETSC_CONSTEXPR_14 - C++14 constexpr 216*bde483f2SJacob Faibussowitsch 217*bde483f2SJacob Faibussowitsch Notes: 218*bde483f2SJacob Faibussowitsch Equivalent to constexpr when using a C++ compiler that supports C++14. Expands to nothing 219*bde483f2SJacob Faibussowitsch if the C++ compiler does not suppport C++14 or when not compiling with a C++ compiler. Note 220*bde483f2SJacob Faibussowitsch that this cannot be used in cases where an empty expansion would result in invalid code. It 221*bde483f2SJacob Faibussowitsch is safe to use this in C source files. 222*bde483f2SJacob Faibussowitsch 223*bde483f2SJacob Faibussowitsch Fortran Notes: 224*bde483f2SJacob Faibussowitsch Not available in Fortran 225*bde483f2SJacob Faibussowitsch 226*bde483f2SJacob Faibussowitsch Example Usage: 227*bde483f2SJacob Faibussowitsch .vb 228*bde483f2SJacob Faibussowitsch PETSC_CONSTEXPR_14 int factorial(int n) 229*bde483f2SJacob Faibussowitsch { 230*bde483f2SJacob Faibussowitsch int r = 1; 231*bde483f2SJacob Faibussowitsch 232*bde483f2SJacob Faibussowitsch do { 233*bde483f2SJacob Faibussowitsch r *= n; 234*bde483f2SJacob Faibussowitsch } while (--n); 235*bde483f2SJacob Faibussowitsch return r; 236*bde483f2SJacob Faibussowitsch } 237*bde483f2SJacob Faibussowitsch .ve 238*bde483f2SJacob Faibussowitsch 239*bde483f2SJacob Faibussowitsch Level: beginner 240*bde483f2SJacob Faibussowitsch 241*bde483f2SJacob Faibussowitsch .seealso: PETSC_CONSTEXPR, PETSC_NULLPTR, PETSC_NOEXCEPT, PETSC_NODISCARD 242*bde483f2SJacob Faibussowitsch MC*/ 243*bde483f2SJacob Faibussowitsch 244*bde483f2SJacob Faibussowitsch /*MC 245*bde483f2SJacob Faibussowitsch PETSC_NOEXCEPT - C++ noexcept 246*bde483f2SJacob Faibussowitsch 247*bde483f2SJacob Faibussowitsch Notes: 248*bde483f2SJacob Faibussowitsch Equivalent to noexcept when using a C++ compiler, and nothing otherwise. It is safe to use 249*bde483f2SJacob Faibussowitsch this in C source files. 250*bde483f2SJacob Faibussowitsch 251*bde483f2SJacob Faibussowitsch Fortran Notes: 252*bde483f2SJacob Faibussowitsch Not available in Fortran 253*bde483f2SJacob Faibussowitsch 254*bde483f2SJacob Faibussowitsch Example Usage: 255*bde483f2SJacob Faibussowitsch .vb 256*bde483f2SJacob Faibussowitsch int factorial(int n) PETSC_NOEXCEPT 257*bde483f2SJacob Faibussowitsch { 258*bde483f2SJacob Faibussowitsch return n <= 1 ? 1 : (n * factorial(n - 1)); 259*bde483f2SJacob Faibussowitsch } 260*bde483f2SJacob Faibussowitsch .ve 261*bde483f2SJacob Faibussowitsch 262*bde483f2SJacob Faibussowitsch Level: beginner 263*bde483f2SJacob Faibussowitsch 264*bde483f2SJacob Faibussowitsch .seealso: PETSC_NULLPTR, PETSC_CONSTEXPR, PETSC_CONSTEXPR_14, PETSC_NODISCARD 265*bde483f2SJacob Faibussowitsch MC*/ 266*bde483f2SJacob Faibussowitsch 267*bde483f2SJacob Faibussowitsch /*MC 268*bde483f2SJacob Faibussowitsch PETSC_NODISCARD - Mark the return value of a function as non-discardable 269*bde483f2SJacob Faibussowitsch 270*bde483f2SJacob Faibussowitsch Notes: 271*bde483f2SJacob Faibussowitsch Hints to the compiler that the return value of a function must be captured. A diagnostic may 272*bde483f2SJacob Faibussowitsch (but is not required) be emitted if the value is discarded. It is safe to use this in C 273*bde483f2SJacob Faibussowitsch and C++ source files. 274*bde483f2SJacob Faibussowitsch 275*bde483f2SJacob Faibussowitsch Fortran Notes: 276*bde483f2SJacob Faibussowitsch Not available in Fortran 277*bde483f2SJacob Faibussowitsch 278*bde483f2SJacob Faibussowitsch Example Usage: 279*bde483f2SJacob Faibussowitsch .vb 280*bde483f2SJacob Faibussowitsch class Foo 281*bde483f2SJacob Faibussowitsch { 282*bde483f2SJacob Faibussowitsch int x; 283*bde483f2SJacob Faibussowitsch 284*bde483f2SJacob Faibussowitsch public: 285*bde483f2SJacob Faibussowitsch PETSC_NODISCARD Foo(int y) : x(y) { } 286*bde483f2SJacob Faibussowitsch }; 287*bde483f2SJacob Faibussowitsch 288*bde483f2SJacob Faibussowitsch PETSC_NODISCARD int factorial(int n) 289*bde483f2SJacob Faibussowitsch { 290*bde483f2SJacob Faibussowitsch return n <= 1 ? 1 : (n * factorial(n - 1)); 291*bde483f2SJacob Faibussowitsch } 292*bde483f2SJacob Faibussowitsch 293*bde483f2SJacob Faibussowitsch auto x = factorial(10); // OK, capturing return value 294*bde483f2SJacob Faibussowitsch factorial(10); // Warning: ignoring return value of function declared 'nodiscard' 295*bde483f2SJacob Faibussowitsch 296*bde483f2SJacob Faibussowitsch auto f = Foo(x); // OK, capturing constructed object 297*bde483f2SJacob Faibussowitsch Foo(x); // Warning: Ignoring temporary created by a constructor declared 'nodiscard' 298*bde483f2SJacob Faibussowitsch .ve 299*bde483f2SJacob Faibussowitsch 300*bde483f2SJacob Faibussowitsch Developer Notes: 301*bde483f2SJacob Faibussowitsch It is highly recommended if not downright required that any PETSc routines written in C++ 302*bde483f2SJacob Faibussowitsch returning a PetscErrorCode be marked PETSC_NODISCARD. Ignoring the return value of PETSc 303*bde483f2SJacob Faibussowitsch routines is not supported; unhandled errors may leave PETSc in an unrecoverable state. 304*bde483f2SJacob Faibussowitsch 305*bde483f2SJacob Faibussowitsch Level: beginner 306*bde483f2SJacob Faibussowitsch 307*bde483f2SJacob Faibussowitsch .seealso: PETSC_NULLPTR, PETSC_CONSTEXPR, PETSC_CONSTEXPR_14, PETSC_NOEXCEPT 308*bde483f2SJacob Faibussowitsch MC*/ 309*bde483f2SJacob Faibussowitsch 310*bde483f2SJacob Faibussowitsch /* C++11 features */ 311*bde483f2SJacob Faibussowitsch #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_DIALECT_CXX11) 312*bde483f2SJacob Faibussowitsch # define PETSC_NULLPTR nullptr 313*bde483f2SJacob Faibussowitsch # define PETSC_CONSTEXPR constexpr 314*bde483f2SJacob Faibussowitsch # define PETSC_NOEXCEPT noexcept 315*bde483f2SJacob Faibussowitsch # define PETSC_NOEXCEPT_ARG(cond_) noexcept(cond_) 316*bde483f2SJacob Faibussowitsch #else 317*bde483f2SJacob Faibussowitsch # define PETSC_NULLPTR NULL 318*bde483f2SJacob Faibussowitsch # define PETSC_CONSTEXPR 319*bde483f2SJacob Faibussowitsch # define PETSC_NOEXCEPT 320*bde483f2SJacob Faibussowitsch # define PETSC_NOEXCEPT_ARG(cond_) 321*bde483f2SJacob Faibussowitsch #endif 322*bde483f2SJacob Faibussowitsch 323*bde483f2SJacob Faibussowitsch /* C++14 features */ 324*bde483f2SJacob Faibussowitsch #if defined(PETSC_HAVE_CXX_DIALECT_CXX14) 325*bde483f2SJacob Faibussowitsch # define PETSC_CONSTEXPR_14 PETSC_CONSTEXPR 326*bde483f2SJacob Faibussowitsch #else 327*bde483f2SJacob Faibussowitsch # define PETSC_CONSTEXPR_14 328*bde483f2SJacob Faibussowitsch #endif 329*bde483f2SJacob Faibussowitsch 330*bde483f2SJacob Faibussowitsch /* C++17 features */ 331*bde483f2SJacob Faibussowitsch /* We met cases that the host CXX compiler (say mpicxx) supports C++17, but nvcc does not 332*bde483f2SJacob Faibussowitsch * agree, even with -ccbin mpicxx! */ 333*bde483f2SJacob Faibussowitsch #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_DIALECT_CXX17) && (!defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_CUDA_DIALECT_CXX17)) 334*bde483f2SJacob Faibussowitsch # define PETSC_NODISCARD [[nodiscard]] 335*bde483f2SJacob Faibussowitsch #else 336*bde483f2SJacob Faibussowitsch # if PetscHasAttribute(warn_unused_result) 337*bde483f2SJacob Faibussowitsch # define PETSC_NODISCARD __attribute__((warn_unused_result)) 338*bde483f2SJacob Faibussowitsch # else 339*bde483f2SJacob Faibussowitsch # define PETSC_NODISCARD 340*bde483f2SJacob Faibussowitsch # endif 341*bde483f2SJacob Faibussowitsch #endif 342*bde483f2SJacob Faibussowitsch 343*bde483f2SJacob Faibussowitsch #include <petscversion.h> 344*bde483f2SJacob Faibussowitsch #define PETSC_AUTHOR_INFO " The PETSc Team\n petsc-maint@mcs.anl.gov\n https://petsc.org/\n" 345*bde483f2SJacob Faibussowitsch 346*bde483f2SJacob Faibussowitsch /*MC 347*bde483f2SJacob Faibussowitsch PetscUnlikely - Hints the compiler that the given condition is usually FALSE 348*bde483f2SJacob Faibussowitsch 349*bde483f2SJacob Faibussowitsch Synopsis: 350*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 351*bde483f2SJacob Faibussowitsch bool PetscUnlikely(bool cond) 352*bde483f2SJacob Faibussowitsch 353*bde483f2SJacob Faibussowitsch Not Collective 354*bde483f2SJacob Faibussowitsch 355*bde483f2SJacob Faibussowitsch Input Parameter: 356*bde483f2SJacob Faibussowitsch . cond - Boolean expression 357*bde483f2SJacob Faibussowitsch 358*bde483f2SJacob Faibussowitsch Notes: 359*bde483f2SJacob Faibussowitsch Not available from fortran. 360*bde483f2SJacob Faibussowitsch 361*bde483f2SJacob Faibussowitsch This returns the same truth value, it is only a hint to compilers that the result of cond is 362*bde483f2SJacob Faibussowitsch unlikely to be true. 363*bde483f2SJacob Faibussowitsch 364*bde483f2SJacob Faibussowitsch Example usage: 365*bde483f2SJacob Faibussowitsch .vb 366*bde483f2SJacob Faibussowitsch if (PetscUnlikely(cond)) { 367*bde483f2SJacob Faibussowitsch foo(); // cold path 368*bde483f2SJacob Faibussowitsch } else { 369*bde483f2SJacob Faibussowitsch bar(); // hot path 370*bde483f2SJacob Faibussowitsch } 371*bde483f2SJacob Faibussowitsch .ve 372*bde483f2SJacob Faibussowitsch 373*bde483f2SJacob Faibussowitsch Level: advanced 374*bde483f2SJacob Faibussowitsch 375*bde483f2SJacob Faibussowitsch .seealso: PetscLikely(), PetscUnlikelyDebug(), CHKERRQ, PetscDefined(), PetscHasAttribute() 376*bde483f2SJacob Faibussowitsch M*/ 377*bde483f2SJacob Faibussowitsch 378*bde483f2SJacob Faibussowitsch /*MC 379*bde483f2SJacob Faibussowitsch PetscLikely - Hints the compiler that the given condition is usually TRUE 380*bde483f2SJacob Faibussowitsch 381*bde483f2SJacob Faibussowitsch Synopsis: 382*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 383*bde483f2SJacob Faibussowitsch bool PetscLikely(bool cond) 384*bde483f2SJacob Faibussowitsch 385*bde483f2SJacob Faibussowitsch Not Collective 386*bde483f2SJacob Faibussowitsch 387*bde483f2SJacob Faibussowitsch Input Parameter: 388*bde483f2SJacob Faibussowitsch . cond - Boolean expression 389*bde483f2SJacob Faibussowitsch 390*bde483f2SJacob Faibussowitsch Notes: 391*bde483f2SJacob Faibussowitsch Not available from fortran. 392*bde483f2SJacob Faibussowitsch 393*bde483f2SJacob Faibussowitsch This returns the same truth value, it is only a hint to compilers that the result of cond is 394*bde483f2SJacob Faibussowitsch likely to be true. 395*bde483f2SJacob Faibussowitsch 396*bde483f2SJacob Faibussowitsch Example usage: 397*bde483f2SJacob Faibussowitsch .vb 398*bde483f2SJacob Faibussowitsch if (PetscLikely(cond)) { 399*bde483f2SJacob Faibussowitsch foo(); // hot path 400*bde483f2SJacob Faibussowitsch } else { 401*bde483f2SJacob Faibussowitsch bar(); // cold path 402*bde483f2SJacob Faibussowitsch } 403*bde483f2SJacob Faibussowitsch .ve 404*bde483f2SJacob Faibussowitsch 405*bde483f2SJacob Faibussowitsch Level: advanced 406*bde483f2SJacob Faibussowitsch 407*bde483f2SJacob Faibussowitsch .seealso: PetscUnlikely(), PetscDefined(), PetscHasAttribute() 408*bde483f2SJacob Faibussowitsch M*/ 409*bde483f2SJacob Faibussowitsch #if defined(PETSC_HAVE_BUILTIN_EXPECT) 410*bde483f2SJacob Faibussowitsch # define PetscUnlikely(cond) __builtin_expect(!!(cond),0) 411*bde483f2SJacob Faibussowitsch # define PetscLikely(cond) __builtin_expect(!!(cond),1) 412*bde483f2SJacob Faibussowitsch #else 413*bde483f2SJacob Faibussowitsch # define PetscUnlikely(cond) (cond) 414*bde483f2SJacob Faibussowitsch # define PetscLikely(cond) (cond) 415*bde483f2SJacob Faibussowitsch #endif 416*bde483f2SJacob Faibussowitsch 417*bde483f2SJacob Faibussowitsch #if defined(__GNUC__) 418*bde483f2SJacob Faibussowitsch /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */ 419*bde483f2SJacob Faibussowitsch # define PetscUnreachable_() __builtin_unreachable() 420*bde483f2SJacob Faibussowitsch #elif defined(_MSC_VER) /* MSVC */ 421*bde483f2SJacob Faibussowitsch # define PetscUnreachable_() __assume(0) 422*bde483f2SJacob Faibussowitsch #else /* ??? */ 423*bde483f2SJacob Faibussowitsch # define PetscUnreachable_() SETERRABORT(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Code path explicitly marked as unreachable executed") 424*bde483f2SJacob Faibussowitsch #endif 425*bde483f2SJacob Faibussowitsch 426*bde483f2SJacob Faibussowitsch /*MC 427*bde483f2SJacob Faibussowitsch PetscUnreachable() - Indicate to the compiler that a code-path is logically unreachable 428*bde483f2SJacob Faibussowitsch 429*bde483f2SJacob Faibussowitsch Synopsis: 430*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 431*bde483f2SJacob Faibussowitsch void PetscUnreachable(void) 432*bde483f2SJacob Faibussowitsch 433*bde483f2SJacob Faibussowitsch Notes: 434*bde483f2SJacob Faibussowitsch Indicates to the compiler (usually via some built-in) that a particular code path is always 435*bde483f2SJacob Faibussowitsch unreachable. Behavior is undefined if this function is ever executed, the user can expect an 436*bde483f2SJacob Faibussowitsch unceremonious crash. 437*bde483f2SJacob Faibussowitsch 438*bde483f2SJacob Faibussowitsch Example usage: 439*bde483f2SJacob Faibussowitsch Useful in situations such as switches over enums where not all enumeration values are 440*bde483f2SJacob Faibussowitsch explicitly covered by the switch 441*bde483f2SJacob Faibussowitsch 442*bde483f2SJacob Faibussowitsch .vb 443*bde483f2SJacob Faibussowitsch typedef enum {RED, GREEN, BLUE} Color; 444*bde483f2SJacob Faibussowitsch 445*bde483f2SJacob Faibussowitsch int foo(Color c) 446*bde483f2SJacob Faibussowitsch { 447*bde483f2SJacob Faibussowitsch // it is known to programmer (or checked previously) that c is either RED or GREEN 448*bde483f2SJacob Faibussowitsch // but compiler may not be able to deduce this and/or emit spurious warnings 449*bde483f2SJacob Faibussowitsch switch (c) { 450*bde483f2SJacob Faibussowitsch case RED: 451*bde483f2SJacob Faibussowitsch return bar(); 452*bde483f2SJacob Faibussowitsch case GREEN: 453*bde483f2SJacob Faibussowitsch return baz(); 454*bde483f2SJacob Faibussowitsch default: 455*bde483f2SJacob Faibussowitsch PetscUnreachable(); // program is ill-formed if executed 456*bde483f2SJacob Faibussowitsch } 457*bde483f2SJacob Faibussowitsch } 458*bde483f2SJacob Faibussowitsch .ve 459*bde483f2SJacob Faibussowitsch 460*bde483f2SJacob Faibussowitsch Level: advanced 461*bde483f2SJacob Faibussowitsch 462*bde483f2SJacob Faibussowitsch .seealso: SETERRABORT(), PETSCABORT() 463*bde483f2SJacob Faibussowitsch MC*/ 464*bde483f2SJacob Faibussowitsch #define PetscUnreachable() PetscUnreachable_() 465*bde483f2SJacob Faibussowitsch 466*bde483f2SJacob Faibussowitsch /*MC 467*bde483f2SJacob Faibussowitsch PetscExpand - Expand macro argument 468*bde483f2SJacob Faibussowitsch 469*bde483f2SJacob Faibussowitsch Synopsis: 470*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 471*bde483f2SJacob Faibussowitsch <macro-expansion> PetscExpand(x) 472*bde483f2SJacob Faibussowitsch 473*bde483f2SJacob Faibussowitsch Input Paramter: 474*bde483f2SJacob Faibussowitsch . x - The preprocessor token to expand 475*bde483f2SJacob Faibussowitsch 476*bde483f2SJacob Faibussowitsch .seealso: PetscStringize(), PetscConcat() 477*bde483f2SJacob Faibussowitsch MC*/ 478*bde483f2SJacob Faibussowitsch #define PetscExpand(x) x 479*bde483f2SJacob Faibussowitsch 480*bde483f2SJacob Faibussowitsch /*MC 481*bde483f2SJacob Faibussowitsch PetscStringize - Stringize a token 482*bde483f2SJacob Faibussowitsch 483*bde483f2SJacob Faibussowitsch Synopsis: 484*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 485*bde483f2SJacob Faibussowitsch const char* PetscStringize(x) 486*bde483f2SJacob Faibussowitsch 487*bde483f2SJacob Faibussowitsch Input Parameter: 488*bde483f2SJacob Faibussowitsch . x - The token you would like to stringize 489*bde483f2SJacob Faibussowitsch 490*bde483f2SJacob Faibussowitsch Output Parameter: 491*bde483f2SJacob Faibussowitsch . <return-value> - The string representation of x 492*bde483f2SJacob Faibussowitsch 493*bde483f2SJacob Faibussowitsch Notes: 494*bde483f2SJacob Faibussowitsch Not available from Fortran. 495*bde483f2SJacob Faibussowitsch 496*bde483f2SJacob Faibussowitsch PetscStringize() expands x before stringizing it, if you do not wish to do so, use 497*bde483f2SJacob Faibussowitsch PetscStringize_() instead. 498*bde483f2SJacob Faibussowitsch 499*bde483f2SJacob Faibussowitsch Example Usage: 500*bde483f2SJacob Faibussowitsch .vb 501*bde483f2SJacob Faibussowitsch #define MY_OTHER_VAR hello there 502*bde483f2SJacob Faibussowitsch #define MY_VAR MY_OTHER_VAR 503*bde483f2SJacob Faibussowitsch 504*bde483f2SJacob Faibussowitsch PetscStringize(MY_VAR) -> "hello there" 505*bde483f2SJacob Faibussowitsch PetscStringize_(MY_VAR) -> "MY_VAR" 506*bde483f2SJacob Faibussowitsch 507*bde483f2SJacob Faibussowitsch int foo; 508*bde483f2SJacob Faibussowitsch PetscStringize(foo) -> "foo" 509*bde483f2SJacob Faibussowitsch PetscStringize_(foo) -> "foo" 510*bde483f2SJacob Faibussowitsch .ve 511*bde483f2SJacob Faibussowitsch 512*bde483f2SJacob Faibussowitsch Level: beginner 513*bde483f2SJacob Faibussowitsch 514*bde483f2SJacob Faibussowitsch .seealso: PetscConcat(), PetscExpandToNothing(), PetscExpand() 515*bde483f2SJacob Faibussowitsch MC*/ 516*bde483f2SJacob Faibussowitsch #define PetscStringize_(x) #x 517*bde483f2SJacob Faibussowitsch #define PetscStringize(x) PetscStringize_(x) 518*bde483f2SJacob Faibussowitsch 519*bde483f2SJacob Faibussowitsch /*MC 520*bde483f2SJacob Faibussowitsch PetscConcat - Concatenate two tokens 521*bde483f2SJacob Faibussowitsch 522*bde483f2SJacob Faibussowitsch Synopsis: 523*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 524*bde483f2SJacob Faibussowitsch <macro-expansion> PetscConcat(x, y) 525*bde483f2SJacob Faibussowitsch 526*bde483f2SJacob Faibussowitsch Input Parameters: 527*bde483f2SJacob Faibussowitsch + x - First token 528*bde483f2SJacob Faibussowitsch - y - Second token 529*bde483f2SJacob Faibussowitsch 530*bde483f2SJacob Faibussowitsch Notes: 531*bde483f2SJacob Faibussowitsch Not available from Fortran. 532*bde483f2SJacob Faibussowitsch 533*bde483f2SJacob Faibussowitsch PetscConcat() will expand both arguments before pasting them together, use PetscConcat_() 534*bde483f2SJacob Faibussowitsch if you don't want to expand them. 535*bde483f2SJacob Faibussowitsch 536*bde483f2SJacob Faibussowitsch Example usage: 537*bde483f2SJacob Faibussowitsch .vb 538*bde483f2SJacob Faibussowitsch PetscConcat(hello,there) -> hellothere 539*bde483f2SJacob Faibussowitsch 540*bde483f2SJacob Faibussowitsch #define HELLO hello 541*bde483f2SJacob Faibussowitsch PetscConcat(HELLO,there) -> hellothere 542*bde483f2SJacob Faibussowitsch PetscConcat_(HELLO,there) -> HELLOthere 543*bde483f2SJacob Faibussowitsch .ve 544*bde483f2SJacob Faibussowitsch 545*bde483f2SJacob Faibussowitsch Level: beginner 546*bde483f2SJacob Faibussowitsch 547*bde483f2SJacob Faibussowitsch .seealso: PetscStringize(), PetscExpand() 548*bde483f2SJacob Faibussowitsch MC*/ 549*bde483f2SJacob Faibussowitsch #define PetscConcat_(x,y) x ## y 550*bde483f2SJacob Faibussowitsch #define PetscConcat(x,y) PetscConcat_(x,y) 551*bde483f2SJacob Faibussowitsch 552*bde483f2SJacob Faibussowitsch #define PETSC_INTERNAL_COMPL_0 1 553*bde483f2SJacob Faibussowitsch #define PETSC_INTERNAL_COMPL_1 0 554*bde483f2SJacob Faibussowitsch 555*bde483f2SJacob Faibussowitsch /*MC 556*bde483f2SJacob Faibussowitsch PetscCompl - Expands to the integer complement of its argument 557*bde483f2SJacob Faibussowitsch 558*bde483f2SJacob Faibussowitsch Synopsis: 559*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 560*bde483f2SJacob Faibussowitsch int PetscCompl(b) 561*bde483f2SJacob Faibussowitsch 562*bde483f2SJacob Faibussowitsch Input Parameter: 563*bde483f2SJacob Faibussowitsch . b - Preprocessor variable, must expand to either integer literal 0 or 1 564*bde483f2SJacob Faibussowitsch 565*bde483f2SJacob Faibussowitsch Output Paramter: 566*bde483f2SJacob Faibussowitsch . <return-value> - Either integer literal 0 or 1 567*bde483f2SJacob Faibussowitsch 568*bde483f2SJacob Faibussowitsch Notes: 569*bde483f2SJacob Faibussowitsch Not available from Fortran. 570*bde483f2SJacob Faibussowitsch 571*bde483f2SJacob Faibussowitsch Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to 572*bde483f2SJacob Faibussowitsch 0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its 573*bde483f2SJacob Faibussowitsch argument before returning the complement. 574*bde483f2SJacob Faibussowitsch 575*bde483f2SJacob Faibussowitsch This macro can be useful for negating PetscDefined() inside macros e.g. 576*bde483f2SJacob Faibussowitsch 577*bde483f2SJacob Faibussowitsch $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO)) 578*bde483f2SJacob Faibussowitsch 579*bde483f2SJacob Faibussowitsch Example usage: 580*bde483f2SJacob Faibussowitsch .vb 581*bde483f2SJacob Faibussowitsch #define MY_VAR 1 582*bde483f2SJacob Faibussowitsch PetscCompl(MY_VAR) -> 0 583*bde483f2SJacob Faibussowitsch 584*bde483f2SJacob Faibussowitsch #undef MY_VAR 585*bde483f2SJacob Faibussowitsch #define MY_VAR 0 586*bde483f2SJacob Faibussowitsch PetscCompl(MY_VAR) -> 1 587*bde483f2SJacob Faibussowitsch .ve 588*bde483f2SJacob Faibussowitsch 589*bde483f2SJacob Faibussowitsch Level: beginner 590*bde483f2SJacob Faibussowitsch 591*bde483f2SJacob Faibussowitsch .seealso: PetscConcat(), PetscDefined() 592*bde483f2SJacob Faibussowitsch MC*/ 593*bde483f2SJacob Faibussowitsch #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_,PetscExpand(b)) 594*bde483f2SJacob Faibussowitsch 595*bde483f2SJacob Faibussowitsch #if !defined(PETSC_SKIP_VARIADIC_MACROS) 596*bde483f2SJacob Faibussowitsch /*MC 597*bde483f2SJacob Faibussowitsch PetscDefined - Determine whether a boolean macro is defined 598*bde483f2SJacob Faibussowitsch 599*bde483f2SJacob Faibussowitsch Synopsis: 600*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 601*bde483f2SJacob Faibussowitsch int PetscDefined(def) 602*bde483f2SJacob Faibussowitsch 603*bde483f2SJacob Faibussowitsch Input Parameter: 604*bde483f2SJacob Faibussowitsch . def - PETSc-style preprocessor variable (without PETSC_ prepended!) 605*bde483f2SJacob Faibussowitsch 606*bde483f2SJacob Faibussowitsch Outut Parameter: 607*bde483f2SJacob Faibussowitsch . <return-value> - Either integer literal 0 or 1 608*bde483f2SJacob Faibussowitsch 609*bde483f2SJacob Faibussowitsch Notes: 610*bde483f2SJacob Faibussowitsch Not available from Fortran, requires variadic macro support, definition is disabled by 611*bde483f2SJacob Faibussowitsch defining PETSC_SKIP_VARIADIC_MACROS. 612*bde483f2SJacob Faibussowitsch 613*bde483f2SJacob Faibussowitsch PetscDefined() returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to 614*bde483f2SJacob Faibussowitsch integer literal 1. In all other cases, PetscDefined() returns integer literal 0. Therefore 615*bde483f2SJacob Faibussowitsch this macro should not be used if its argument may be defined to a non-empty value other than 616*bde483f2SJacob Faibussowitsch 1. 617*bde483f2SJacob Faibussowitsch 618*bde483f2SJacob Faibussowitsch The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to 619*bde483f2SJacob Faibussowitsch add custom checks in user code, one should use PetscDefined_(). 620*bde483f2SJacob Faibussowitsch 621*bde483f2SJacob Faibussowitsch $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d)) 622*bde483f2SJacob Faibussowitsch 623*bde483f2SJacob Faibussowitsch Developer Notes: 624*bde483f2SJacob Faibussowitsch Getting something that works in C and CPP for an arg that may or may not be defined is 625*bde483f2SJacob Faibussowitsch tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define, 626*bde483f2SJacob Faibussowitsch insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks 627*bde483f2SJacob Faibussowitsch the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair, 628*bde483f2SJacob Faibussowitsch and when the last step cherry picks the 2nd arg, we get a zero. 629*bde483f2SJacob Faibussowitsch 630*bde483f2SJacob Faibussowitsch Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a 631*bde483f2SJacob Faibussowitsch nonconforming implementation of variadic macros. 632*bde483f2SJacob Faibussowitsch 633*bde483f2SJacob Faibussowitsch Example Usage: 634*bde483f2SJacob Faibussowitsch Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG 635*bde483f2SJacob Faibussowitsch is defined then 636*bde483f2SJacob Faibussowitsch 637*bde483f2SJacob Faibussowitsch .vb 638*bde483f2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG) 639*bde483f2SJacob Faibussowitsch foo(); 640*bde483f2SJacob Faibussowitsch #else 641*bde483f2SJacob Faibussowitsch bar(); 642*bde483f2SJacob Faibussowitsch #endif 643*bde483f2SJacob Faibussowitsch 644*bde483f2SJacob Faibussowitsch // or alternatively within normal code 645*bde483f2SJacob Faibussowitsch if (PetscDefined(USE_DEBUG)) { 646*bde483f2SJacob Faibussowitsch foo(); 647*bde483f2SJacob Faibussowitsch } else { 648*bde483f2SJacob Faibussowitsch bar(); 649*bde483f2SJacob Faibussowitsch } 650*bde483f2SJacob Faibussowitsch .ve 651*bde483f2SJacob Faibussowitsch 652*bde483f2SJacob Faibussowitsch is equivalent to 653*bde483f2SJacob Faibussowitsch 654*bde483f2SJacob Faibussowitsch .vb 655*bde483f2SJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) 656*bde483f2SJacob Faibussowitsch # if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro 657*bde483f2SJacob Faibussowitsch foo(); 658*bde483f2SJacob Faibussowitsch # elif PETSC_USE_DEBUG == 1 659*bde483f2SJacob Faibussowitsch foo(); 660*bde483f2SJacob Faibussowitsch # else 661*bde483f2SJacob Faibussowitsch bar(); 662*bde483f2SJacob Faibussowitsch # endif 663*bde483f2SJacob Faibussowitsch #else 664*bde483f2SJacob Faibussowitsch bar(); 665*bde483f2SJacob Faibussowitsch #endif 666*bde483f2SJacob Faibussowitsch .ve 667*bde483f2SJacob Faibussowitsch 668*bde483f2SJacob Faibussowitsch Level: intermediate 669*bde483f2SJacob Faibussowitsch 670*bde483f2SJacob Faibussowitsch .seealso: PetscHasAttribute(), PetscUnlikely(), PetscLikely(), PetscConcat(), 671*bde483f2SJacob Faibussowitsch PetscExpandToNothing(), PetscCompl() 672*bde483f2SJacob Faibussowitsch MC*/ 673*bde483f2SJacob Faibussowitsch #define PetscDefined_arg_1 shift, 674*bde483f2SJacob Faibussowitsch #define PetscDefined_arg_ shift, 675*bde483f2SJacob Faibussowitsch #define PetscDefined__take_second_expanded(ignored, val, ...) val 676*bde483f2SJacob Faibussowitsch #define PetscDefined__take_second_expand(args) PetscDefined__take_second_expanded args 677*bde483f2SJacob Faibussowitsch #define PetscDefined__take_second(...) PetscDefined__take_second_expand((__VA_ARGS__)) 678*bde483f2SJacob Faibussowitsch #define PetscDefined__(arg1_or_junk) PetscDefined__take_second(arg1_or_junk 1, 0, at_) 679*bde483f2SJacob Faibussowitsch #define PetscDefined_(value) PetscDefined__(PetscConcat_(PetscDefined_arg_,value)) 680*bde483f2SJacob Faibussowitsch #define PetscDefined(def) PetscDefined_(PetscConcat(PETSC_,def)) 681*bde483f2SJacob Faibussowitsch 682*bde483f2SJacob Faibussowitsch /*MC 683*bde483f2SJacob Faibussowitsch PetscUnlikelyDebug - Hints the compiler that the given condition is usually FALSE, eliding 684*bde483f2SJacob Faibussowitsch the check in optimized mode 685*bde483f2SJacob Faibussowitsch 686*bde483f2SJacob Faibussowitsch Synopsis: 687*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 688*bde483f2SJacob Faibussowitsch bool PetscUnlikelyDebug(bool cond) 689*bde483f2SJacob Faibussowitsch 690*bde483f2SJacob Faibussowitsch Not Collective 691*bde483f2SJacob Faibussowitsch 692*bde483f2SJacob Faibussowitsch Input Parameters: 693*bde483f2SJacob Faibussowitsch . cond - Boolean expression 694*bde483f2SJacob Faibussowitsch 695*bde483f2SJacob Faibussowitsch Notes: 696*bde483f2SJacob Faibussowitsch Not available from Fortran, requires variadic macro support, definition is disabled by 697*bde483f2SJacob Faibussowitsch defining PETSC_SKIP_VARIADIC_MACROS. 698*bde483f2SJacob Faibussowitsch 699*bde483f2SJacob Faibussowitsch This returns the same truth value, it is only a hint to compilers that the result of cond is 700*bde483f2SJacob Faibussowitsch likely to be false. When PETSc is compiled in optimized mode this will always return 701*bde483f2SJacob Faibussowitsch false. Additionally, cond is guaranteed to not be evaluated when PETSc is compiled in 702*bde483f2SJacob Faibussowitsch optimized mode. 703*bde483f2SJacob Faibussowitsch 704*bde483f2SJacob Faibussowitsch Example usage: 705*bde483f2SJacob Faibussowitsch This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG) 706*bde483f2SJacob Faibussowitsch is true. So 707*bde483f2SJacob Faibussowitsch 708*bde483f2SJacob Faibussowitsch .vb 709*bde483f2SJacob Faibussowitsch if (PetscUnlikelyDebug(cond)) { 710*bde483f2SJacob Faibussowitsch foo(); 711*bde483f2SJacob Faibussowitsch } else { 712*bde483f2SJacob Faibussowitsch bar(); 713*bde483f2SJacob Faibussowitsch } 714*bde483f2SJacob Faibussowitsch .ve 715*bde483f2SJacob Faibussowitsch 716*bde483f2SJacob Faibussowitsch is equivalent to 717*bde483f2SJacob Faibussowitsch 718*bde483f2SJacob Faibussowitsch .vb 719*bde483f2SJacob Faibussowitsch if (PetscDefined(USE_DEBUG)) { 720*bde483f2SJacob Faibussowitsch if (PetscUnlikely(cond)) { 721*bde483f2SJacob Faibussowitsch foo(); 722*bde483f2SJacob Faibussowitsch } else { 723*bde483f2SJacob Faibussowitsch bar(); 724*bde483f2SJacob Faibussowitsch } 725*bde483f2SJacob Faibussowitsch } else { 726*bde483f2SJacob Faibussowitsch bar(); 727*bde483f2SJacob Faibussowitsch } 728*bde483f2SJacob Faibussowitsch .ve 729*bde483f2SJacob Faibussowitsch 730*bde483f2SJacob Faibussowitsch Level: advanced 731*bde483f2SJacob Faibussowitsch 732*bde483f2SJacob Faibussowitsch .seealso: PetscUnlikely(), PetscLikely(), CHKERRQ, SETERRQ 733*bde483f2SJacob Faibussowitsch M*/ 734*bde483f2SJacob Faibussowitsch #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond)) 735*bde483f2SJacob Faibussowitsch 736*bde483f2SJacob Faibussowitsch /*MC 737*bde483f2SJacob Faibussowitsch PetscExpandToNothing - Expands to absolutely nothing at all 738*bde483f2SJacob Faibussowitsch 739*bde483f2SJacob Faibussowitsch Synopsis: 740*bde483f2SJacob Faibussowitsch #include <petscmacros.h> 741*bde483f2SJacob Faibussowitsch void PetscExpandToNothing(...) 742*bde483f2SJacob Faibussowitsch 743*bde483f2SJacob Faibussowitsch Input Parameter: 744*bde483f2SJacob Faibussowitsch . __VA_ARGS__ - Anything at all 745*bde483f2SJacob Faibussowitsch 746*bde483f2SJacob Faibussowitsch Notes: 747*bde483f2SJacob Faibussowitsch Not available from Fortran, requires variadic macro support, definition is disabled by 748*bde483f2SJacob Faibussowitsch defining PETSC_SKIP_VARIADIC_MACROS. 749*bde483f2SJacob Faibussowitsch 750*bde483f2SJacob Faibussowitsch Must have at least 1 parameter. 751*bde483f2SJacob Faibussowitsch 752*bde483f2SJacob Faibussowitsch Example usage: 753*bde483f2SJacob Faibussowitsch .vb 754*bde483f2SJacob Faibussowitsch PetscExpandToNothing(a,b,c) -> *nothing* 755*bde483f2SJacob Faibussowitsch .ve 756*bde483f2SJacob Faibussowitsch 757*bde483f2SJacob Faibussowitsch Level: beginner 758*bde483f2SJacob Faibussowitsch 759*bde483f2SJacob Faibussowitsch .seealso: PetscConcat(), PetscDefined(), PetscStringize(), PetscExpand() 760*bde483f2SJacob Faibussowitsch MC*/ 761*bde483f2SJacob Faibussowitsch #define PetscExpandToNothing(...) 762*bde483f2SJacob Faibussowitsch #endif /* !PETSC_SKIP_VARIADIC_MACROS */ 763*bde483f2SJacob Faibussowitsch 764*bde483f2SJacob Faibussowitsch #endif /* PETSC_PREPROCESSOR_MACROS_H */ 765