xref: /petsc/include/petscmacros.h (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
1bde483f2SJacob Faibussowitsch #ifndef PETSC_PREPROCESSOR_MACROS_H
2bde483f2SJacob Faibussowitsch #define PETSC_PREPROCESSOR_MACROS_H
3bde483f2SJacob Faibussowitsch 
4bde483f2SJacob Faibussowitsch #include <petscconf.h>
5bde483f2SJacob Faibussowitsch #include <petscconf_poison.h> /* for PetscDefined() error checking */
6bde483f2SJacob Faibussowitsch 
7ac09b921SBarry Smith /* SUBMANSEC = Sys */
8ac09b921SBarry Smith 
9bde483f2SJacob Faibussowitsch /* ========================================================================== */
10bde483f2SJacob Faibussowitsch /* This facilitates using the C version of PETSc from C++ and the C++ version from C. */
11bde483f2SJacob Faibussowitsch #if defined(__cplusplus)
12bde483f2SJacob Faibussowitsch #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_CXX
13bde483f2SJacob Faibussowitsch #else
14bde483f2SJacob Faibussowitsch #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_C
15bde483f2SJacob Faibussowitsch #endif
16bde483f2SJacob Faibussowitsch 
17bde483f2SJacob Faibussowitsch /* ========================================================================== */
18bde483f2SJacob Faibussowitsch /* Since PETSc manages its own extern "C" handling users should never include PETSc include
19bde483f2SJacob Faibussowitsch  * files within extern "C". This will generate a compiler error if a user does put the include
20bde483f2SJacob Faibussowitsch  * file within an extern "C".
21bde483f2SJacob Faibussowitsch  */
22bde483f2SJacob Faibussowitsch #if defined(__cplusplus)
23*9371c9d4SSatish Balay void assert_never_put_petsc_headers_inside_an_extern_c(int);
24*9371c9d4SSatish Balay void assert_never_put_petsc_headers_inside_an_extern_c(double);
25bde483f2SJacob Faibussowitsch #endif
26bde483f2SJacob Faibussowitsch 
27bde483f2SJacob Faibussowitsch #if defined(__cplusplus)
28bde483f2SJacob Faibussowitsch #define PETSC_RESTRICT PETSC_CXX_RESTRICT
29bde483f2SJacob Faibussowitsch #else
306ee8c794SJacob Faibussowitsch #define PETSC_RESTRICT restrict
31bde483f2SJacob Faibussowitsch #endif
32bde483f2SJacob Faibussowitsch 
336ee8c794SJacob Faibussowitsch #define PETSC_INLINE        PETSC_DEPRECATED_MACRO("GCC warning \"PETSC_INLINE is deprecated (since version 3.17)\"") inline
349fbee547SJacob Faibussowitsch #define PETSC_STATIC_INLINE PETSC_DEPRECATED_MACRO("GCC warning \"PETSC_STATIC_INLINE is deprecated (since version 3.17)\"") static inline
35bde483f2SJacob Faibussowitsch 
36bde483f2SJacob Faibussowitsch #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */
37bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT __declspec(dllexport)
38bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT __declspec(dllimport)
39bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL
40bde483f2SJacob Faibussowitsch #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX)
41bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT           __attribute__((visibility("default")))
42bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT           __attribute__((visibility("default")))
43bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden")))
44bde483f2SJacob Faibussowitsch #elif !defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_C)
45bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT           __attribute__((visibility("default")))
46bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT           __attribute__((visibility("default")))
47bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden")))
48bde483f2SJacob Faibussowitsch #else
49bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT
50bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT
51bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL
52bde483f2SJacob Faibussowitsch #endif
53bde483f2SJacob Faibussowitsch 
54bde483f2SJacob Faibussowitsch #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */
55bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_PUBLIC PETSC_DLLEXPORT
56bde483f2SJacob Faibussowitsch #else /* Win32 users need this to import symbols from petsc.dll */
57bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT
58bde483f2SJacob Faibussowitsch #endif
59bde483f2SJacob Faibussowitsch 
60bde483f2SJacob Faibussowitsch /* Functions tagged with PETSC_EXTERN in the header files are always defined as extern "C" when
61bde483f2SJacob Faibussowitsch  * compiled with C++ so they may be used from C and are always visible in the shared libraries
62bde483f2SJacob Faibussowitsch  */
63bde483f2SJacob Faibussowitsch #if defined(__cplusplus)
64bde483f2SJacob Faibussowitsch #define PETSC_EXTERN         extern "C" PETSC_VISIBILITY_PUBLIC
65bde483f2SJacob Faibussowitsch #define PETSC_EXTERN_TYPEDEF extern "C"
66bde483f2SJacob Faibussowitsch #define PETSC_INTERN         extern "C" PETSC_VISIBILITY_INTERNAL
67bde483f2SJacob Faibussowitsch #else
68bde483f2SJacob Faibussowitsch #define PETSC_EXTERN extern PETSC_VISIBILITY_PUBLIC
69bde483f2SJacob Faibussowitsch #define PETSC_EXTERN_TYPEDEF
70bde483f2SJacob Faibussowitsch #define PETSC_INTERN extern PETSC_VISIBILITY_INTERNAL
71bde483f2SJacob Faibussowitsch #endif
72bde483f2SJacob Faibussowitsch 
73bde483f2SJacob Faibussowitsch #if defined(PETSC_USE_SINGLE_LIBRARY)
74bde483f2SJacob Faibussowitsch #define PETSC_SINGLE_LIBRARY_INTERN PETSC_INTERN
75bde483f2SJacob Faibussowitsch #else
76bde483f2SJacob Faibussowitsch #define PETSC_SINGLE_LIBRARY_INTERN PETSC_EXTERN
77bde483f2SJacob Faibussowitsch #endif
78bde483f2SJacob Faibussowitsch 
79bde483f2SJacob Faibussowitsch /*MC
80bde483f2SJacob Faibussowitsch   PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler
81bde483f2SJacob Faibussowitsch 
82bde483f2SJacob Faibussowitsch   Synopsis:
83bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
84bde483f2SJacob Faibussowitsch   boolean PetscHasAttribute(name)
85bde483f2SJacob Faibussowitsch 
86bde483f2SJacob Faibussowitsch   Input Parameter:
87bde483f2SJacob Faibussowitsch . name - The name of the attribute to test
88bde483f2SJacob Faibussowitsch 
89bde483f2SJacob Faibussowitsch   Notes:
90bde483f2SJacob Faibussowitsch   name should be identical to what you might pass to the __attribute__ declaration itself --
91bde483f2SJacob Faibussowitsch   plain, unbroken text.
92bde483f2SJacob Faibussowitsch 
9387497f52SBarry Smith   As `PetscHasAttribute()` is wrapper over the function-like macro __has_attribute(), the exact
94bde483f2SJacob Faibussowitsch   type and value returned is implementation defined. In practice however, it usually returns
95bde483f2SJacob Faibussowitsch   the integer literal 1 if the attribute is supported, and integer literal 0 if the attribute
96bde483f2SJacob Faibussowitsch   is not supported.
97bde483f2SJacob Faibussowitsch 
98bde483f2SJacob Faibussowitsch   Example Usage:
99bde483f2SJacob Faibussowitsch   Typical usage is using the preprocessor
100bde483f2SJacob Faibussowitsch 
101bde483f2SJacob Faibussowitsch .vb
102bde483f2SJacob Faibussowitsch   #if PetscHasAttribute(always_inline)
103bde483f2SJacob Faibussowitsch   #  define MY_ALWAYS_INLINE __attribute__((always_inline))
104bde483f2SJacob Faibussowitsch   #else
105bde483f2SJacob Faibussowitsch   #  define MY_ALWAYS_INLINE
106bde483f2SJacob Faibussowitsch   #endif
107bde483f2SJacob Faibussowitsch 
108bde483f2SJacob Faibussowitsch   void foo(void) MY_ALWAYS_INLINE;
109bde483f2SJacob Faibussowitsch .ve
110bde483f2SJacob Faibussowitsch 
111bde483f2SJacob Faibussowitsch   but it can also be used in regular code
112bde483f2SJacob Faibussowitsch 
113bde483f2SJacob Faibussowitsch .vb
114bde483f2SJacob Faibussowitsch   if (PetscHasAttribute(some_attribute)) {
115bde483f2SJacob Faibussowitsch     foo();
116bde483f2SJacob Faibussowitsch   } else {
117bde483f2SJacob Faibussowitsch     bar();
118bde483f2SJacob Faibussowitsch   }
119bde483f2SJacob Faibussowitsch .ve
120bde483f2SJacob Faibussowitsch 
121bde483f2SJacob Faibussowitsch   Level: intermediate
122bde483f2SJacob Faibussowitsch 
123db781477SPatrick Sanan .seealso: `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`, `PETSC_ATTRIBUTE_FORMAT`
124bde483f2SJacob Faibussowitsch M*/
125bde483f2SJacob Faibussowitsch #if !defined(__has_attribute)
126bde483f2SJacob Faibussowitsch #define __has_attribute(x) 0
127bde483f2SJacob Faibussowitsch #endif
128bde483f2SJacob Faibussowitsch #define PetscHasAttribute(name) __has_attribute(name)
129bde483f2SJacob Faibussowitsch 
130bde483f2SJacob Faibussowitsch /*MC
13163a3b9bcSJacob Faibussowitsch   PETSC_ATTRIBUTE_FORMAT - Indicate to the compiler that specified arguments should be treated
13263a3b9bcSJacob Faibussowitsch   as format specifiers and checked for validity
13363a3b9bcSJacob Faibussowitsch 
13463a3b9bcSJacob Faibussowitsch   Synopsis:
13563a3b9bcSJacob Faibussowitsch   #include <petscmacros.h>
13663a3b9bcSJacob Faibussowitsch   <attribute declaration> PETSC_ATTRIBUTE_FORMAT(int strIdx, int vaArgIdx)
13763a3b9bcSJacob Faibussowitsch 
13863a3b9bcSJacob Faibussowitsch   Input Parameters:
13963a3b9bcSJacob Faibussowitsch + strIdx   - The (1-indexed) location of the format string in the argument list
14063a3b9bcSJacob Faibussowitsch - vaArgIdx - The (1-indexed) location of the first formattable argument in the argument list
14163a3b9bcSJacob Faibussowitsch 
14263a3b9bcSJacob Faibussowitsch   Notes:
14363a3b9bcSJacob Faibussowitsch   This function attribute causes the compiler to issue warnings when the format specifier does
14463a3b9bcSJacob Faibussowitsch   not match the type of the variable that will be formatted, or when there exists a mismatch
14563a3b9bcSJacob Faibussowitsch   between the number of format specifiers and variables to be formatted. It is safe to use this
14663a3b9bcSJacob Faibussowitsch   macro if your compiler does not support format specifier checking (though this is
14763a3b9bcSJacob Faibussowitsch   exceeedingly rare).
14863a3b9bcSJacob Faibussowitsch 
14963a3b9bcSJacob Faibussowitsch   Both strIdx and vaArgIdx must be compile-time constant integer literals and cannot have the
15063a3b9bcSJacob Faibussowitsch   same value.
15163a3b9bcSJacob Faibussowitsch 
15263a3b9bcSJacob Faibussowitsch   The arguments to be formatted (and therefore checked by the compiler) must be "contiguous" in
15363a3b9bcSJacob Faibussowitsch   the argument list, that is, there is no way to indicate gaps which should not be checked.
15463a3b9bcSJacob Faibussowitsch 
15587497f52SBarry Smith   Definition is suppressed by defining `PETSC_SKIP_ATTRIBUTE_FORMAT` prior to including PETSc
15663a3b9bcSJacob Faibussowitsch   header files. In this case the macro will expand empty.
15763a3b9bcSJacob Faibussowitsch 
15863a3b9bcSJacob Faibussowitsch   Example Usage:
15963a3b9bcSJacob Faibussowitsch .vb
16063a3b9bcSJacob Faibussowitsch   // format string is 2nd argument, variable argument list containing args is 3rd argument
16163a3b9bcSJacob Faibussowitsch   void my_printf(void *obj, const char *fmt_string, ...) PETSC_ATTRIBUTE_FORMAT(2,3)
16263a3b9bcSJacob Faibussowitsch 
16363a3b9bcSJacob Faibussowitsch   int    x = 1;
16463a3b9bcSJacob Faibussowitsch   double y = 50.0;
16563a3b9bcSJacob Faibussowitsch 
16663a3b9bcSJacob Faibussowitsch   my_printf(NULL,"%g",x);      // WARNING, format specifier does not match for 'int'!
16763a3b9bcSJacob Faibussowitsch   my_printf(NULL,"%d",x,y);    // WARNING, more arguments than format specifiers!
16863a3b9bcSJacob Faibussowitsch   my_printf(NULL,"%d %g",x,y); // OK
16963a3b9bcSJacob Faibussowitsch .ve
17063a3b9bcSJacob Faibussowitsch 
17163a3b9bcSJacob Faibussowitsch   Level: developer
17263a3b9bcSJacob Faibussowitsch 
173db781477SPatrick Sanan .seealso: `PETSC_ATTRIBUTE_COLD`, `PetscHasAttribute()`
17463a3b9bcSJacob Faibussowitsch M*/
17563a3b9bcSJacob Faibussowitsch #if PetscHasAttribute(format) && !defined(PETSC_SKIP_ATTRIBUTE_FORMAT)
17663a3b9bcSJacob Faibussowitsch #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) __attribute__((format(printf, strIdx, vaArgIdx)))
17763a3b9bcSJacob Faibussowitsch #else
17863a3b9bcSJacob Faibussowitsch #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx)
17963a3b9bcSJacob Faibussowitsch #endif
18063a3b9bcSJacob Faibussowitsch 
18163a3b9bcSJacob Faibussowitsch /*MC
182d8e4614bSJacob Faibussowitsch   PETSC_ATTRIBUTE_COLD - Indicate to the compiler that a function is very unlikely to be
183d8e4614bSJacob Faibussowitsch   executed
184d8e4614bSJacob Faibussowitsch 
185d8e4614bSJacob Faibussowitsch   Notes:
186d8e4614bSJacob Faibussowitsch   The marked function is often optimized for size rather than speed and may be grouped alongside
187d8e4614bSJacob Faibussowitsch   other equally frigid routines improving code locality of lukewarm or hotter parts of program.
188d8e4614bSJacob Faibussowitsch 
189d8e4614bSJacob Faibussowitsch   The paths leading to cold functions are usually automatically marked as unlikely by the
190d8e4614bSJacob Faibussowitsch   compiler. It may thus be useful to mark functions used to handle unlikely conditions -- such
191d8e4614bSJacob Faibussowitsch   as error handlers -- as cold to improve optimization of the surrounding temperate functions.
192d8e4614bSJacob Faibussowitsch 
193d8e4614bSJacob Faibussowitsch   Example Usage:
194d8e4614bSJacob Faibussowitsch .vb
195d8e4614bSJacob Faibussowitsch   void my_error_handler(...) PETSC_ATTRIBUTE_COLD;
196d8e4614bSJacob Faibussowitsch 
197d8e4614bSJacob Faibussowitsch   if (temperature < 0) {
198d8e4614bSJacob Faibussowitsch     return my_error_handler(...); // chilly!
199d8e4614bSJacob Faibussowitsch   }
200d8e4614bSJacob Faibussowitsch .ve
201d8e4614bSJacob Faibussowitsch 
202d8e4614bSJacob Faibussowitsch   Level: intermediate
203d8e4614bSJacob Faibussowitsch 
204db781477SPatrick Sanan .seealso: `PetscUnlikely()`, `PetscUnlikelyDebug()`, `PetscLikely()`, `PetscLikelyDebug()`,
205db781477SPatrick Sanan           `PetscUnreachable()`, `PETSC_ATTRIBUTE_FORMAT`
206d8e4614bSJacob Faibussowitsch M*/
207d8e4614bSJacob Faibussowitsch #if PetscHasAttribute(__cold__)
208d8e4614bSJacob Faibussowitsch #define PETSC_ATTRIBUTE_COLD __attribute__((__cold__))
209d8e4614bSJacob Faibussowitsch #elif PetscHasAttribute(cold) /* some implementations (old gcc) use no underscores */
210d8e4614bSJacob Faibussowitsch #define PETSC_ATTRIBUTE_COLD __attribute__((cold))
211d8e4614bSJacob Faibussowitsch #else
212d8e4614bSJacob Faibussowitsch #define PETSC_ATTRIBUTE_COLD
213d8e4614bSJacob Faibussowitsch #endif
214d8e4614bSJacob Faibussowitsch 
215d8e4614bSJacob Faibussowitsch /*MC
216bde483f2SJacob Faibussowitsch   PETSC_NULLPTR - Standard way of indicating a null value or pointer
217bde483f2SJacob Faibussowitsch 
218bde483f2SJacob Faibussowitsch   Notes:
219bde483f2SJacob Faibussowitsch   Equivalent to NULL in C source, and nullptr in C++ source. Note that for the purposes of
22087497f52SBarry Smith   interoperability between C and C++, setting a pointer to `PETSC_NULLPTR` in C++ is functonially
221bde483f2SJacob Faibussowitsch   equivalent to setting the same pointer to NULL in C. That is to say that the following
222bde483f2SJacob Faibussowitsch   expressions are equivalent\:
223bde483f2SJacob Faibussowitsch 
224bde483f2SJacob Faibussowitsch .vb
225bde483f2SJacob Faibussowitsch   ptr == PETSC_NULLPTR
226bde483f2SJacob Faibussowitsch   ptr == NULL
227bde483f2SJacob Faibussowitsch   ptr == 0
228bde483f2SJacob Faibussowitsch   !ptr
229bde483f2SJacob Faibussowitsch 
230bde483f2SJacob Faibussowitsch   ptr = PETSC_NULLPTR
231bde483f2SJacob Faibussowitsch   ptr = NULL
232bde483f2SJacob Faibussowitsch   ptr = 0
233bde483f2SJacob Faibussowitsch .ve
234bde483f2SJacob Faibussowitsch 
235bde483f2SJacob Faibussowitsch   and for completeness' sake\:
236bde483f2SJacob Faibussowitsch 
237bde483f2SJacob Faibussowitsch .vb
238bde483f2SJacob Faibussowitsch   PETSC_NULLPTR == NULL
239bde483f2SJacob Faibussowitsch .ve
240bde483f2SJacob Faibussowitsch 
241bde483f2SJacob Faibussowitsch   Fortran Notes:
242bde483f2SJacob Faibussowitsch   Not available in Fortran
243bde483f2SJacob Faibussowitsch 
244bde483f2SJacob Faibussowitsch   Example Usage:
245bde483f2SJacob Faibussowitsch .vb
246bde483f2SJacob Faibussowitsch   // may be used in place of '\0' or other such teminators in the definition of char arrays
247bde483f2SJacob Faibussowitsch   const char *const MyEnumTypes[] = {
248bde483f2SJacob Faibussowitsch     "foo",
249bde483f2SJacob Faibussowitsch     "bar",
250bde483f2SJacob Faibussowitsch     PETSC_NULLPTR
251bde483f2SJacob Faibussowitsch   };
252bde483f2SJacob Faibussowitsch 
253bde483f2SJacob Faibussowitsch   // may be used to nullify objects
254bde483f2SJacob Faibussowitsch   PetscObject obj = PETSC_NULLPTR;
255bde483f2SJacob Faibussowitsch 
256bde483f2SJacob Faibussowitsch   // may be used in any function expecting NULL
257bde483f2SJacob Faibussowitsch   PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor");
258bde483f2SJacob Faibussowitsch .ve
259bde483f2SJacob Faibussowitsch 
260bde483f2SJacob Faibussowitsch   Developer Notes:
26187497f52SBarry Smith   `PETSC_NULLPTR` must be used in place of NULL in all C++ source files. Using NULL in source
262bde483f2SJacob Faibussowitsch   files compiled with a C++ compiler may lead to unexpected side-effects in function overload
263bde483f2SJacob Faibussowitsch   resolution and/or compiler warnings.
264bde483f2SJacob Faibussowitsch 
265bde483f2SJacob Faibussowitsch   Level: beginner
266bde483f2SJacob Faibussowitsch 
267db781477SPatrick Sanan .seealso: `PETSC_CONSTEXPR_14`, `PETSC_NODISCARD`
268817da375SSatish Balay M*/
269bde483f2SJacob Faibussowitsch 
270bde483f2SJacob Faibussowitsch /*MC
271bde483f2SJacob Faibussowitsch   PETSC_CONSTEXPR_14 - C++14 constexpr
272bde483f2SJacob Faibussowitsch 
273bde483f2SJacob Faibussowitsch   Notes:
274bde483f2SJacob Faibussowitsch   Equivalent to constexpr when using a C++ compiler that supports C++14. Expands to nothing
275bde483f2SJacob Faibussowitsch   if the C++ compiler does not suppport C++14 or when not compiling with a C++ compiler. Note
276bde483f2SJacob Faibussowitsch   that this cannot be used in cases where an empty expansion would result in invalid code. It
277bde483f2SJacob Faibussowitsch   is safe to use this in C source files.
278bde483f2SJacob Faibussowitsch 
279bde483f2SJacob Faibussowitsch   Fortran Notes:
280bde483f2SJacob Faibussowitsch   Not available in Fortran
281bde483f2SJacob Faibussowitsch 
282bde483f2SJacob Faibussowitsch   Example Usage:
283bde483f2SJacob Faibussowitsch .vb
284bde483f2SJacob Faibussowitsch   PETSC_CONSTEXPR_14 int factorial(int n)
285bde483f2SJacob Faibussowitsch   {
286bde483f2SJacob Faibussowitsch     int r = 1;
287bde483f2SJacob Faibussowitsch 
288bde483f2SJacob Faibussowitsch     do {
289bde483f2SJacob Faibussowitsch       r *= n;
290bde483f2SJacob Faibussowitsch     } while (--n);
291bde483f2SJacob Faibussowitsch     return r;
292bde483f2SJacob Faibussowitsch   }
293bde483f2SJacob Faibussowitsch .ve
294bde483f2SJacob Faibussowitsch 
295bde483f2SJacob Faibussowitsch   Level: beginner
296bde483f2SJacob Faibussowitsch 
297db781477SPatrick Sanan .seealso: `PETSC_NULLPTR`, `PETSC_NODISCARD`
298817da375SSatish Balay M*/
299bde483f2SJacob Faibussowitsch 
300bde483f2SJacob Faibussowitsch /*MC
301bde483f2SJacob Faibussowitsch   PETSC_NODISCARD - Mark the return value of a function as non-discardable
302bde483f2SJacob Faibussowitsch 
303bde483f2SJacob Faibussowitsch   Notes:
304bde483f2SJacob Faibussowitsch   Hints to the compiler that the return value of a function must be captured. A diagnostic may
305bde483f2SJacob Faibussowitsch   (but is not required) be emitted if the value is discarded. It is safe to use this in C
306bde483f2SJacob Faibussowitsch   and C++ source files.
307bde483f2SJacob Faibussowitsch 
308bde483f2SJacob Faibussowitsch   Fortran Notes:
309bde483f2SJacob Faibussowitsch   Not available in Fortran
310bde483f2SJacob Faibussowitsch 
311bde483f2SJacob Faibussowitsch   Example Usage:
312bde483f2SJacob Faibussowitsch .vb
313bde483f2SJacob Faibussowitsch   class Foo
314bde483f2SJacob Faibussowitsch   {
315bde483f2SJacob Faibussowitsch     int x;
316bde483f2SJacob Faibussowitsch 
317bde483f2SJacob Faibussowitsch   public:
318bde483f2SJacob Faibussowitsch     PETSC_NODISCARD Foo(int y) : x(y) { }
319bde483f2SJacob Faibussowitsch   };
320bde483f2SJacob Faibussowitsch 
321bde483f2SJacob Faibussowitsch   PETSC_NODISCARD int factorial(int n)
322bde483f2SJacob Faibussowitsch   {
323bde483f2SJacob Faibussowitsch     return n <= 1 ? 1 : (n * factorial(n - 1));
324bde483f2SJacob Faibussowitsch   }
325bde483f2SJacob Faibussowitsch 
326bde483f2SJacob Faibussowitsch   auto x = factorial(10); // OK, capturing return value
327bde483f2SJacob Faibussowitsch   factorial(10);          // Warning: ignoring return value of function declared 'nodiscard'
328bde483f2SJacob Faibussowitsch 
329bde483f2SJacob Faibussowitsch   auto f = Foo(x); // OK, capturing constructed object
330bde483f2SJacob Faibussowitsch   Foo(x);          // Warning: Ignoring temporary created by a constructor declared 'nodiscard'
331bde483f2SJacob Faibussowitsch .ve
332bde483f2SJacob Faibussowitsch 
333bde483f2SJacob Faibussowitsch   Developer Notes:
334bde483f2SJacob Faibussowitsch   It is highly recommended if not downright required that any PETSc routines written in C++
33587497f52SBarry Smith   returning a PetscErrorCode be marked `PETSC_NODISCARD`. Ignoring the return value of PETSc
336bde483f2SJacob Faibussowitsch   routines is not supported; unhandled errors may leave PETSc in an unrecoverable state.
337bde483f2SJacob Faibussowitsch 
338bde483f2SJacob Faibussowitsch   Level: beginner
339bde483f2SJacob Faibussowitsch 
340db781477SPatrick Sanan .seealso: `PETSC_NULLPTR`, `PETSC_CONSTEXPR_14`
341817da375SSatish Balay M*/
342bde483f2SJacob Faibussowitsch 
343bde483f2SJacob Faibussowitsch /* C++11 features */
3446ee8c794SJacob Faibussowitsch #if defined(__cplusplus)
345bde483f2SJacob Faibussowitsch #define PETSC_NULLPTR nullptr
346bde483f2SJacob Faibussowitsch #else
347bde483f2SJacob Faibussowitsch #define PETSC_NULLPTR NULL
348bde483f2SJacob Faibussowitsch #endif
349bde483f2SJacob Faibussowitsch 
350bde483f2SJacob Faibussowitsch /* C++14 features */
3517796e686SJacob Faibussowitsch #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_DIALECT_CXX14) && __cplusplus >= 201402L
3526ee8c794SJacob Faibussowitsch #define PETSC_CONSTEXPR_14 constexpr
353bde483f2SJacob Faibussowitsch #else
354bde483f2SJacob Faibussowitsch #define PETSC_CONSTEXPR_14
355bde483f2SJacob Faibussowitsch #endif
356bde483f2SJacob Faibussowitsch 
357bde483f2SJacob Faibussowitsch /* C++17 features */
358bde483f2SJacob Faibussowitsch /* We met cases that the host CXX compiler (say mpicxx) supports C++17, but nvcc does not
359bde483f2SJacob Faibussowitsch  * agree, even with -ccbin mpicxx! */
360bde483f2SJacob Faibussowitsch #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_DIALECT_CXX17) && (!defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_CUDA_DIALECT_CXX17))
361bde483f2SJacob Faibussowitsch #define PETSC_NODISCARD [[nodiscard]]
362bde483f2SJacob Faibussowitsch #else
363bde483f2SJacob Faibussowitsch #if PetscHasAttribute(warn_unused_result)
364bde483f2SJacob Faibussowitsch #define PETSC_NODISCARD __attribute__((warn_unused_result))
365bde483f2SJacob Faibussowitsch #else
366bde483f2SJacob Faibussowitsch #define PETSC_NODISCARD
367bde483f2SJacob Faibussowitsch #endif
368bde483f2SJacob Faibussowitsch #endif
369bde483f2SJacob Faibussowitsch 
370bde483f2SJacob Faibussowitsch #include <petscversion.h>
371bde483f2SJacob Faibussowitsch #define PETSC_AUTHOR_INFO "       The PETSc Team\n    petsc-maint@mcs.anl.gov\n https://petsc.org/\n"
372bde483f2SJacob Faibussowitsch 
373267267bdSJacob Faibussowitsch /* designated initializers since C99 and C++20, MSVC never supports them though */
374267267bdSJacob Faibussowitsch #if defined(_MSC_VER) || (defined(__cplusplus) && (__cplusplus < 202002L))
375267267bdSJacob Faibussowitsch #define PetscDesignatedInitializer(name, ...) __VA_ARGS__
376267267bdSJacob Faibussowitsch #else
377267267bdSJacob Faibussowitsch #define PetscDesignatedInitializer(name, ...) .name = __VA_ARGS__
378267267bdSJacob Faibussowitsch #endif
379267267bdSJacob Faibussowitsch 
380bde483f2SJacob Faibussowitsch /*MC
38187497f52SBarry Smith   PetscUnlikely - Hints the compiler that the given condition is usually false
382bde483f2SJacob Faibussowitsch 
383bde483f2SJacob Faibussowitsch   Synopsis:
384bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
385bde483f2SJacob Faibussowitsch   bool PetscUnlikely(bool cond)
386bde483f2SJacob Faibussowitsch 
387bde483f2SJacob Faibussowitsch   Not Collective
388bde483f2SJacob Faibussowitsch 
389bde483f2SJacob Faibussowitsch   Input Parameter:
390bde483f2SJacob Faibussowitsch . cond - Boolean expression
391bde483f2SJacob Faibussowitsch 
392bde483f2SJacob Faibussowitsch   Notes:
393bde483f2SJacob Faibussowitsch   Not available from fortran.
394bde483f2SJacob Faibussowitsch 
395bde483f2SJacob Faibussowitsch   This returns the same truth value, it is only a hint to compilers that the result of cond is
396bde483f2SJacob Faibussowitsch   unlikely to be true.
397bde483f2SJacob Faibussowitsch 
398bde483f2SJacob Faibussowitsch   Example usage:
399bde483f2SJacob Faibussowitsch .vb
400bde483f2SJacob Faibussowitsch   if (PetscUnlikely(cond)) {
401bde483f2SJacob Faibussowitsch     foo(); // cold path
402bde483f2SJacob Faibussowitsch   } else {
403bde483f2SJacob Faibussowitsch     bar(); // hot path
404bde483f2SJacob Faibussowitsch   }
405bde483f2SJacob Faibussowitsch .ve
406bde483f2SJacob Faibussowitsch 
407bde483f2SJacob Faibussowitsch   Level: advanced
408bde483f2SJacob Faibussowitsch 
409db781477SPatrick Sanan .seealso: `PetscLikely()`, `PetscUnlikelyDebug()`, `PetscCall()`, `PetscDefined()`, `PetscHasAttribute()`,
410db781477SPatrick Sanan           `PETSC_ATTRIBUTE_COLD`
411bde483f2SJacob Faibussowitsch M*/
412bde483f2SJacob Faibussowitsch 
413bde483f2SJacob Faibussowitsch /*MC
41487497f52SBarry Smith   PetscLikely - Hints the compiler that the given condition is usually true
415bde483f2SJacob Faibussowitsch 
416bde483f2SJacob Faibussowitsch   Synopsis:
417bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
418bde483f2SJacob Faibussowitsch   bool PetscLikely(bool cond)
419bde483f2SJacob Faibussowitsch 
420bde483f2SJacob Faibussowitsch   Not Collective
421bde483f2SJacob Faibussowitsch 
422bde483f2SJacob Faibussowitsch   Input Parameter:
423bde483f2SJacob Faibussowitsch . cond - Boolean expression
424bde483f2SJacob Faibussowitsch 
425bde483f2SJacob Faibussowitsch   Notes:
426bde483f2SJacob Faibussowitsch   Not available from fortran.
427bde483f2SJacob Faibussowitsch 
428bde483f2SJacob Faibussowitsch   This returns the same truth value, it is only a hint to compilers that the result of cond is
429bde483f2SJacob Faibussowitsch   likely to be true.
430bde483f2SJacob Faibussowitsch 
431bde483f2SJacob Faibussowitsch   Example usage:
432bde483f2SJacob Faibussowitsch .vb
433bde483f2SJacob Faibussowitsch   if (PetscLikely(cond)) {
434bde483f2SJacob Faibussowitsch     foo(); // hot path
435bde483f2SJacob Faibussowitsch   } else {
436bde483f2SJacob Faibussowitsch     bar(); // cold path
437bde483f2SJacob Faibussowitsch   }
438bde483f2SJacob Faibussowitsch .ve
439bde483f2SJacob Faibussowitsch 
440bde483f2SJacob Faibussowitsch   Level: advanced
441bde483f2SJacob Faibussowitsch 
442db781477SPatrick Sanan .seealso: `PetscUnlikely()`, `PetscDefined()`, `PetscHasAttribute()`
443db781477SPatrick Sanan           `PETSC_ATTRIBUTE_COLD`
444bde483f2SJacob Faibussowitsch M*/
445bde483f2SJacob Faibussowitsch #if defined(PETSC_HAVE_BUILTIN_EXPECT)
446bde483f2SJacob Faibussowitsch #define PetscUnlikely(cond) __builtin_expect(!!(cond), 0)
447bde483f2SJacob Faibussowitsch #define PetscLikely(cond)   __builtin_expect(!!(cond), 1)
448bde483f2SJacob Faibussowitsch #else
449bde483f2SJacob Faibussowitsch #define PetscUnlikely(cond) (cond)
450bde483f2SJacob Faibussowitsch #define PetscLikely(cond)   (cond)
451bde483f2SJacob Faibussowitsch #endif
452bde483f2SJacob Faibussowitsch 
453bde483f2SJacob Faibussowitsch /*MC
454817da375SSatish Balay   PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable
455bde483f2SJacob Faibussowitsch 
456bde483f2SJacob Faibussowitsch   Synopsis:
457bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
458bde483f2SJacob Faibussowitsch   void PetscUnreachable(void)
459bde483f2SJacob Faibussowitsch 
460bde483f2SJacob Faibussowitsch   Notes:
461bde483f2SJacob Faibussowitsch   Indicates to the compiler (usually via some built-in) that a particular code path is always
462bde483f2SJacob Faibussowitsch   unreachable. Behavior is undefined if this function is ever executed, the user can expect an
463bde483f2SJacob Faibussowitsch   unceremonious crash.
464bde483f2SJacob Faibussowitsch 
465bde483f2SJacob Faibussowitsch   Example usage:
466bde483f2SJacob Faibussowitsch   Useful in situations such as switches over enums where not all enumeration values are
467bde483f2SJacob Faibussowitsch   explicitly covered by the switch
468bde483f2SJacob Faibussowitsch 
469bde483f2SJacob Faibussowitsch .vb
470bde483f2SJacob Faibussowitsch   typedef enum {RED, GREEN, BLUE} Color;
471bde483f2SJacob Faibussowitsch 
472bde483f2SJacob Faibussowitsch   int foo(Color c)
473bde483f2SJacob Faibussowitsch   {
474bde483f2SJacob Faibussowitsch     // it is known to programmer (or checked previously) that c is either RED or GREEN
475bde483f2SJacob Faibussowitsch     // but compiler may not be able to deduce this and/or emit spurious warnings
476bde483f2SJacob Faibussowitsch     switch (c) {
477bde483f2SJacob Faibussowitsch       case RED:
478bde483f2SJacob Faibussowitsch         return bar();
479bde483f2SJacob Faibussowitsch       case GREEN:
480bde483f2SJacob Faibussowitsch         return baz();
481bde483f2SJacob Faibussowitsch       default:
482bde483f2SJacob Faibussowitsch         PetscUnreachable(); // program is ill-formed if executed
483bde483f2SJacob Faibussowitsch     }
484bde483f2SJacob Faibussowitsch   }
485bde483f2SJacob Faibussowitsch .ve
486bde483f2SJacob Faibussowitsch 
487bde483f2SJacob Faibussowitsch   Level: advanced
488bde483f2SJacob Faibussowitsch 
489db781477SPatrick Sanan .seealso: `SETERRABORT()`, `PETSCABORT()`, `PETSC_ATTRIBUTE_COLD`
490817da375SSatish Balay M*/
491e58a63e1SJacob Faibussowitsch #if defined(__GNUC__)
492e58a63e1SJacob Faibussowitsch /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */
493e58a63e1SJacob Faibussowitsch #define PetscUnreachable() __builtin_unreachable()
494e58a63e1SJacob Faibussowitsch #elif defined(_MSC_VER) /* MSVC */
495e58a63e1SJacob Faibussowitsch #define PetscUnreachable() __assume(0)
496e58a63e1SJacob Faibussowitsch #else /* ??? */
497e58a63e1SJacob Faibussowitsch #define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Code path explicitly marked as unreachable executed")
498e58a63e1SJacob Faibussowitsch #endif
499bde483f2SJacob Faibussowitsch 
500bde483f2SJacob Faibussowitsch /*MC
501bde483f2SJacob Faibussowitsch   PetscExpand - Expand macro argument
502bde483f2SJacob Faibussowitsch 
503bde483f2SJacob Faibussowitsch   Synopsis:
504bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
505bde483f2SJacob Faibussowitsch   <macro-expansion> PetscExpand(x)
506bde483f2SJacob Faibussowitsch 
5076aad120cSJose E. Roman   Input Parameter:
508bde483f2SJacob Faibussowitsch . x - The preprocessor token to expand
509bde483f2SJacob Faibussowitsch 
51049762cbcSSatish Balay   Level: beginner
51149762cbcSSatish Balay 
512db781477SPatrick Sanan .seealso: `PetscStringize()`, `PetscConcat()`
513817da375SSatish Balay M*/
514e58a63e1SJacob Faibussowitsch #define PetscExpand_(...) __VA_ARGS__
515e58a63e1SJacob Faibussowitsch #define PetscExpand(...)  PetscExpand_(__VA_ARGS__)
516bde483f2SJacob Faibussowitsch 
517bde483f2SJacob Faibussowitsch /*MC
518bde483f2SJacob Faibussowitsch   PetscStringize - Stringize a token
519bde483f2SJacob Faibussowitsch 
520bde483f2SJacob Faibussowitsch   Synopsis:
521bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
522bde483f2SJacob Faibussowitsch   const char* PetscStringize(x)
523bde483f2SJacob Faibussowitsch 
524bde483f2SJacob Faibussowitsch   Input Parameter:
525bde483f2SJacob Faibussowitsch . x - The token you would like to stringize
526bde483f2SJacob Faibussowitsch 
527bde483f2SJacob Faibussowitsch   Output Parameter:
528bde483f2SJacob Faibussowitsch . <return-value> - The string representation of x
529bde483f2SJacob Faibussowitsch 
530bde483f2SJacob Faibussowitsch   Notes:
531bde483f2SJacob Faibussowitsch   Not available from Fortran.
532bde483f2SJacob Faibussowitsch 
533bde483f2SJacob Faibussowitsch   PetscStringize() expands x before stringizing it, if you do not wish to do so, use
534bde483f2SJacob Faibussowitsch   PetscStringize_() instead.
535bde483f2SJacob Faibussowitsch 
536bde483f2SJacob Faibussowitsch   Example Usage:
537bde483f2SJacob Faibussowitsch .vb
538bde483f2SJacob Faibussowitsch   #define MY_OTHER_VAR hello there
539bde483f2SJacob Faibussowitsch   #define MY_VAR       MY_OTHER_VAR
540bde483f2SJacob Faibussowitsch 
541bde483f2SJacob Faibussowitsch   PetscStringize(MY_VAR)  -> "hello there"
542bde483f2SJacob Faibussowitsch   PetscStringize_(MY_VAR) -> "MY_VAR"
543bde483f2SJacob Faibussowitsch 
544bde483f2SJacob Faibussowitsch   int foo;
545bde483f2SJacob Faibussowitsch   PetscStringize(foo)  -> "foo"
546bde483f2SJacob Faibussowitsch   PetscStringize_(foo) -> "foo"
547bde483f2SJacob Faibussowitsch .ve
548bde483f2SJacob Faibussowitsch 
549bde483f2SJacob Faibussowitsch   Level: beginner
550bde483f2SJacob Faibussowitsch 
551db781477SPatrick Sanan .seealso: `PetscConcat()`, `PetscExpandToNothing()`, `PetscExpand()`
552817da375SSatish Balay M*/
553bde483f2SJacob Faibussowitsch #define PetscStringize_(x) #x
554bde483f2SJacob Faibussowitsch #define PetscStringize(x)  PetscStringize_(x)
555bde483f2SJacob Faibussowitsch 
556bde483f2SJacob Faibussowitsch /*MC
557bde483f2SJacob Faibussowitsch   PetscConcat - Concatenate two tokens
558bde483f2SJacob Faibussowitsch 
559bde483f2SJacob Faibussowitsch   Synopsis:
560bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
561bde483f2SJacob Faibussowitsch   <macro-expansion> PetscConcat(x, y)
562bde483f2SJacob Faibussowitsch 
563bde483f2SJacob Faibussowitsch   Input Parameters:
564bde483f2SJacob Faibussowitsch + x - First token
565bde483f2SJacob Faibussowitsch - y - Second token
566bde483f2SJacob Faibussowitsch 
567bde483f2SJacob Faibussowitsch   Notes:
568bde483f2SJacob Faibussowitsch   Not available from Fortran.
569bde483f2SJacob Faibussowitsch 
570bde483f2SJacob Faibussowitsch   PetscConcat() will expand both arguments before pasting them together, use PetscConcat_()
571bde483f2SJacob Faibussowitsch   if you don't want to expand them.
572bde483f2SJacob Faibussowitsch 
573bde483f2SJacob Faibussowitsch   Example usage:
574bde483f2SJacob Faibussowitsch .vb
575bde483f2SJacob Faibussowitsch   PetscConcat(hello,there) -> hellothere
576bde483f2SJacob Faibussowitsch 
577bde483f2SJacob Faibussowitsch   #define HELLO hello
578bde483f2SJacob Faibussowitsch   PetscConcat(HELLO,there)  -> hellothere
579bde483f2SJacob Faibussowitsch   PetscConcat_(HELLO,there) -> HELLOthere
580bde483f2SJacob Faibussowitsch .ve
581bde483f2SJacob Faibussowitsch 
582bde483f2SJacob Faibussowitsch   Level: beginner
583bde483f2SJacob Faibussowitsch 
584db781477SPatrick Sanan .seealso: `PetscStringize()`, `PetscExpand()`
585817da375SSatish Balay M*/
586bde483f2SJacob Faibussowitsch #define PetscConcat_(x, y) x##y
587bde483f2SJacob Faibussowitsch #define PetscConcat(x, y)  PetscConcat_(x, y)
588bde483f2SJacob Faibussowitsch 
589bde483f2SJacob Faibussowitsch #define PETSC_INTERNAL_COMPL_0 1
590bde483f2SJacob Faibussowitsch #define PETSC_INTERNAL_COMPL_1 0
591bde483f2SJacob Faibussowitsch 
592bde483f2SJacob Faibussowitsch /*MC
593bde483f2SJacob Faibussowitsch   PetscCompl - Expands to the integer complement of its argument
594bde483f2SJacob Faibussowitsch 
595bde483f2SJacob Faibussowitsch   Synopsis:
596bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
597bde483f2SJacob Faibussowitsch   int PetscCompl(b)
598bde483f2SJacob Faibussowitsch 
599bde483f2SJacob Faibussowitsch   Input Parameter:
600bde483f2SJacob Faibussowitsch . b - Preprocessor variable, must expand to either integer literal 0 or 1
601bde483f2SJacob Faibussowitsch 
6026aad120cSJose E. Roman   Output Parameter:
603bde483f2SJacob Faibussowitsch . <return-value> - Either integer literal 0 or 1
604bde483f2SJacob Faibussowitsch 
605bde483f2SJacob Faibussowitsch   Notes:
606bde483f2SJacob Faibussowitsch   Not available from Fortran.
607bde483f2SJacob Faibussowitsch 
608bde483f2SJacob Faibussowitsch   Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to
609bde483f2SJacob Faibussowitsch   0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its
610bde483f2SJacob Faibussowitsch   argument before returning the complement.
611bde483f2SJacob Faibussowitsch 
612bde483f2SJacob Faibussowitsch   This macro can be useful for negating PetscDefined() inside macros e.g.
613bde483f2SJacob Faibussowitsch 
614bde483f2SJacob Faibussowitsch $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO))
615bde483f2SJacob Faibussowitsch 
616bde483f2SJacob Faibussowitsch   Example usage:
617bde483f2SJacob Faibussowitsch .vb
618bde483f2SJacob Faibussowitsch   #define MY_VAR 1
619bde483f2SJacob Faibussowitsch   PetscCompl(MY_VAR) -> 0
620bde483f2SJacob Faibussowitsch 
621bde483f2SJacob Faibussowitsch   #undef  MY_VAR
622bde483f2SJacob Faibussowitsch   #define MY_VAR 0
623bde483f2SJacob Faibussowitsch   PetscCompl(MY_VAR) -> 1
624bde483f2SJacob Faibussowitsch .ve
625bde483f2SJacob Faibussowitsch 
626bde483f2SJacob Faibussowitsch   Level: beginner
627bde483f2SJacob Faibussowitsch 
628db781477SPatrick Sanan .seealso: `PetscConcat()`, `PetscDefined()`
629817da375SSatish Balay M*/
630bde483f2SJacob Faibussowitsch #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_, PetscExpand(b))
631bde483f2SJacob Faibussowitsch 
632bde483f2SJacob Faibussowitsch #if !defined(PETSC_SKIP_VARIADIC_MACROS)
633bde483f2SJacob Faibussowitsch /*MC
634bde483f2SJacob Faibussowitsch   PetscDefined - Determine whether a boolean macro is defined
635bde483f2SJacob Faibussowitsch 
636bde483f2SJacob Faibussowitsch   Synopsis:
637bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
638bde483f2SJacob Faibussowitsch   int PetscDefined(def)
639bde483f2SJacob Faibussowitsch 
640bde483f2SJacob Faibussowitsch   Input Parameter:
641bde483f2SJacob Faibussowitsch . def - PETSc-style preprocessor variable (without PETSC_ prepended!)
642bde483f2SJacob Faibussowitsch 
643bde483f2SJacob Faibussowitsch   Outut Parameter:
644bde483f2SJacob Faibussowitsch . <return-value> - Either integer literal 0 or 1
645bde483f2SJacob Faibussowitsch 
646bde483f2SJacob Faibussowitsch   Notes:
647bde483f2SJacob Faibussowitsch   Not available from Fortran, requires variadic macro support, definition is disabled by
64887497f52SBarry Smith   defining `PETSC_SKIP_VARIADIC_MACROS`.
649bde483f2SJacob Faibussowitsch 
65087497f52SBarry Smith   `PetscDefined()` returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to
65187497f52SBarry Smith   integer literal 1. In all other cases, `PetscDefined()` returns integer literal 0. Therefore
652bde483f2SJacob Faibussowitsch   this macro should not be used if its argument may be defined to a non-empty value other than
653bde483f2SJacob Faibussowitsch   1.
654bde483f2SJacob Faibussowitsch 
655bde483f2SJacob Faibussowitsch   The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to
65687497f52SBarry Smith   add custom checks in user code, one should use `PetscDefined_()`.
657bde483f2SJacob Faibussowitsch 
658bde483f2SJacob Faibussowitsch $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d))
659bde483f2SJacob Faibussowitsch 
660bde483f2SJacob Faibussowitsch   Developer Notes:
661bde483f2SJacob Faibussowitsch   Getting something that works in C and CPP for an arg that may or may not be defined is
662bde483f2SJacob Faibussowitsch   tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define,
663bde483f2SJacob Faibussowitsch   insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks
664bde483f2SJacob Faibussowitsch   the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair,
665bde483f2SJacob Faibussowitsch   and when the last step cherry picks the 2nd arg, we get a zero.
666bde483f2SJacob Faibussowitsch 
667bde483f2SJacob Faibussowitsch   Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a
668bde483f2SJacob Faibussowitsch   nonconforming implementation of variadic macros.
669bde483f2SJacob Faibussowitsch 
670bde483f2SJacob Faibussowitsch   Example Usage:
671bde483f2SJacob Faibussowitsch   Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG
672bde483f2SJacob Faibussowitsch   is defined then
673bde483f2SJacob Faibussowitsch 
674bde483f2SJacob Faibussowitsch .vb
675bde483f2SJacob Faibussowitsch   #if PetscDefined(USE_DEBUG)
676bde483f2SJacob Faibussowitsch     foo();
677bde483f2SJacob Faibussowitsch   #else
678bde483f2SJacob Faibussowitsch     bar();
679bde483f2SJacob Faibussowitsch   #endif
680bde483f2SJacob Faibussowitsch 
681bde483f2SJacob Faibussowitsch   // or alternatively within normal code
682bde483f2SJacob Faibussowitsch   if (PetscDefined(USE_DEBUG)) {
683bde483f2SJacob Faibussowitsch     foo();
684bde483f2SJacob Faibussowitsch   } else {
685bde483f2SJacob Faibussowitsch     bar();
686bde483f2SJacob Faibussowitsch   }
687bde483f2SJacob Faibussowitsch .ve
688bde483f2SJacob Faibussowitsch 
689bde483f2SJacob Faibussowitsch   is equivalent to
690bde483f2SJacob Faibussowitsch 
691bde483f2SJacob Faibussowitsch .vb
692bde483f2SJacob Faibussowitsch   #if defined(PETSC_USE_DEBUG)
693bde483f2SJacob Faibussowitsch   #  if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro
694bde483f2SJacob Faibussowitsch        foo();
695bde483f2SJacob Faibussowitsch   #   elif PETSC_USE_DEBUG == 1
696bde483f2SJacob Faibussowitsch        foo();
697bde483f2SJacob Faibussowitsch   #   else
698bde483f2SJacob Faibussowitsch        bar();
699bde483f2SJacob Faibussowitsch   #  endif
700bde483f2SJacob Faibussowitsch   #else
701bde483f2SJacob Faibussowitsch   bar();
702bde483f2SJacob Faibussowitsch   #endif
703bde483f2SJacob Faibussowitsch .ve
704bde483f2SJacob Faibussowitsch 
705bde483f2SJacob Faibussowitsch   Level: intermediate
706bde483f2SJacob Faibussowitsch 
707db781477SPatrick Sanan .seealso: `PetscHasAttribute()`, `PetscUnlikely()`, `PetscLikely()`, `PetscConcat()`,
708db781477SPatrick Sanan           `PetscExpandToNothing()`, `PetscCompl()`
709817da375SSatish Balay M*/
710bde483f2SJacob Faibussowitsch #define PetscDefined_arg_1                                    shift,
711bde483f2SJacob Faibussowitsch #define PetscDefined_arg_                                     shift,
712bde483f2SJacob Faibussowitsch #define PetscDefined__take_second_expanded(ignored, val, ...) val
713bde483f2SJacob Faibussowitsch #define PetscDefined__take_second_expand(args)                PetscDefined__take_second_expanded args
714bde483f2SJacob Faibussowitsch #define PetscDefined__take_second(...)                        PetscDefined__take_second_expand((__VA_ARGS__))
715bde483f2SJacob Faibussowitsch #define PetscDefined__(arg1_or_junk)                          PetscDefined__take_second(arg1_or_junk 1, 0, at_)
716bde483f2SJacob Faibussowitsch #define PetscDefined_(value)                                  PetscDefined__(PetscConcat_(PetscDefined_arg_, value))
717bde483f2SJacob Faibussowitsch #define PetscDefined(def)                                     PetscDefined_(PetscConcat(PETSC_, def))
718bde483f2SJacob Faibussowitsch 
719bde483f2SJacob Faibussowitsch /*MC
72087497f52SBarry Smith   PetscUnlikelyDebug - Hints the compiler that the given condition is usually false, eliding
721bde483f2SJacob Faibussowitsch   the check in optimized mode
722bde483f2SJacob Faibussowitsch 
723bde483f2SJacob Faibussowitsch   Synopsis:
724bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
725bde483f2SJacob Faibussowitsch   bool PetscUnlikelyDebug(bool cond)
726bde483f2SJacob Faibussowitsch 
727bde483f2SJacob Faibussowitsch   Not Collective
728bde483f2SJacob Faibussowitsch 
729bde483f2SJacob Faibussowitsch   Input Parameters:
730bde483f2SJacob Faibussowitsch . cond - Boolean expression
731bde483f2SJacob Faibussowitsch 
732bde483f2SJacob Faibussowitsch   Notes:
733bde483f2SJacob Faibussowitsch   Not available from Fortran, requires variadic macro support, definition is disabled by
73487497f52SBarry Smith   defining `PETSC_SKIP_VARIADIC_MACROS`.
735bde483f2SJacob Faibussowitsch 
736bde483f2SJacob Faibussowitsch   This returns the same truth value, it is only a hint to compilers that the result of cond is
737bde483f2SJacob Faibussowitsch   likely to be false. When PETSc is compiled in optimized mode this will always return
738bde483f2SJacob Faibussowitsch   false. Additionally, cond is guaranteed to not be evaluated when PETSc is compiled in
739bde483f2SJacob Faibussowitsch   optimized mode.
740bde483f2SJacob Faibussowitsch 
741bde483f2SJacob Faibussowitsch   Example usage:
742bde483f2SJacob Faibussowitsch   This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG)
743bde483f2SJacob Faibussowitsch   is true. So
744bde483f2SJacob Faibussowitsch 
745bde483f2SJacob Faibussowitsch .vb
746bde483f2SJacob Faibussowitsch   if (PetscUnlikelyDebug(cond)) {
747bde483f2SJacob Faibussowitsch     foo();
748bde483f2SJacob Faibussowitsch   } else {
749bde483f2SJacob Faibussowitsch     bar();
750bde483f2SJacob Faibussowitsch   }
751bde483f2SJacob Faibussowitsch .ve
752bde483f2SJacob Faibussowitsch 
753bde483f2SJacob Faibussowitsch   is equivalent to
754bde483f2SJacob Faibussowitsch 
755bde483f2SJacob Faibussowitsch .vb
756bde483f2SJacob Faibussowitsch   if (PetscDefined(USE_DEBUG)) {
757bde483f2SJacob Faibussowitsch     if (PetscUnlikely(cond)) {
758bde483f2SJacob Faibussowitsch       foo();
759bde483f2SJacob Faibussowitsch     } else {
760bde483f2SJacob Faibussowitsch       bar();
761bde483f2SJacob Faibussowitsch     }
762bde483f2SJacob Faibussowitsch   } else {
763bde483f2SJacob Faibussowitsch     bar();
764bde483f2SJacob Faibussowitsch   }
765bde483f2SJacob Faibussowitsch .ve
766bde483f2SJacob Faibussowitsch 
767bde483f2SJacob Faibussowitsch   Level: advanced
768bde483f2SJacob Faibussowitsch 
769db781477SPatrick Sanan .seealso: `PetscUnlikely()`, `PetscLikely()`, `PetscCall()`, `SETERRQ`
770bde483f2SJacob Faibussowitsch M*/
771bde483f2SJacob Faibussowitsch #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond))
772bde483f2SJacob Faibussowitsch 
773f7e3c444SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
774f7e3c444SJacob Faibussowitsch // silence compiler warnings when using -pedantic, this is only used by the linter and it cares
775f7e3c444SJacob Faibussowitsch // not what ISO C allows
776*9371c9d4SSatish Balay #define PetscMacroReturns_(retexpr, ...) \
777*9371c9d4SSatish Balay   __extension__({ \
778*9371c9d4SSatish Balay     __VA_ARGS__; \
779*9371c9d4SSatish Balay     retexpr; \
780*9371c9d4SSatish Balay   })
781f7e3c444SJacob Faibussowitsch #else
782*9371c9d4SSatish Balay #define PetscMacroReturns_(retexpr, ...) \
783*9371c9d4SSatish Balay   retexpr; \
784*9371c9d4SSatish Balay   do { __VA_ARGS__; } while (0)
785f7e3c444SJacob Faibussowitsch #endif
786f7e3c444SJacob Faibussowitsch 
787bde483f2SJacob Faibussowitsch /*MC
788bde483f2SJacob Faibussowitsch   PetscExpandToNothing - Expands to absolutely nothing at all
789bde483f2SJacob Faibussowitsch 
790bde483f2SJacob Faibussowitsch   Synopsis:
791bde483f2SJacob Faibussowitsch   #include <petscmacros.h>
792bde483f2SJacob Faibussowitsch   void PetscExpandToNothing(...)
793bde483f2SJacob Faibussowitsch 
794bde483f2SJacob Faibussowitsch   Input Parameter:
795bde483f2SJacob Faibussowitsch . __VA_ARGS__ - Anything at all
796bde483f2SJacob Faibussowitsch 
797bde483f2SJacob Faibussowitsch   Notes:
798bde483f2SJacob Faibussowitsch   Not available from Fortran, requires variadic macro support, definition is disabled by
79987497f52SBarry Smith   defining `PETSC_SKIP_VARIADIC_MACROS`.
800bde483f2SJacob Faibussowitsch 
801bde483f2SJacob Faibussowitsch   Must have at least 1 parameter.
802bde483f2SJacob Faibussowitsch 
803bde483f2SJacob Faibussowitsch   Example usage:
804bde483f2SJacob Faibussowitsch .vb
805bde483f2SJacob Faibussowitsch   PetscExpandToNothing(a,b,c) -> *nothing*
806bde483f2SJacob Faibussowitsch .ve
807bde483f2SJacob Faibussowitsch 
808bde483f2SJacob Faibussowitsch   Level: beginner
809bde483f2SJacob Faibussowitsch 
810db781477SPatrick Sanan .seealso: `PetscConcat()`, `PetscDefined()`, `PetscStringize()`, `PetscExpand()`
811817da375SSatish Balay M*/
812bde483f2SJacob Faibussowitsch #define PetscExpandToNothing(...)
813f7e3c444SJacob Faibussowitsch 
814f7e3c444SJacob Faibussowitsch /*MC
815f7e3c444SJacob Faibussowitsch   PetscMacroReturns - Define a macro body that returns a value
816f7e3c444SJacob Faibussowitsch 
817f7e3c444SJacob Faibussowitsch   Synopsis:
818f7e3c444SJacob Faibussowitsch   #include <petscmacros.h>
819f7e3c444SJacob Faibussowitsch   return_type PetscMacroReturns(return_type retexpr, ...)
820f7e3c444SJacob Faibussowitsch 
821f7e3c444SJacob Faibussowitsch   Input Parameters:
822f7e3c444SJacob Faibussowitsch + retexpr     - The value or expression that the macro should return
823f7e3c444SJacob Faibussowitsch - __VA_ARGS__ - The body of the macro
824f7e3c444SJacob Faibussowitsch 
825f7e3c444SJacob Faibussowitsch   Notes:
826f7e3c444SJacob Faibussowitsch   Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the
827f7e3c444SJacob Faibussowitsch   body of the macro and should not depend on values produced as a result of the expression. The
828f7e3c444SJacob Faibussowitsch   user should not assume that the result of this macro is equivalent to a single logical source
829f7e3c444SJacob Faibussowitsch   line. It is not portable to use macros defined using this one in conditional or loop bodies
830f7e3c444SJacob Faibussowitsch   without enclosing them in curly braces\:
831f7e3c444SJacob Faibussowitsch 
832f7e3c444SJacob Faibussowitsch .vb
833f7e3c444SJacob Faibussowitsch   #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0
834f7e3c444SJacob Faibussowitsch 
835f7e3c444SJacob Faibussowitsch   int err,x = 10;
836f7e3c444SJacob Faibussowitsch 
837f7e3c444SJacob Faibussowitsch   if (...) err = FOO(x);      // ERROR, body of FOO() executed outside the if statement
838f7e3c444SJacob Faibussowitsch   if (...) { err = FOO(x); }  // OK
839f7e3c444SJacob Faibussowitsch 
840f7e3c444SJacob Faibussowitsch   for (...) err = FOO(x);     // ERROR, body of FOO() executed outside the loop
841f7e3c444SJacob Faibussowitsch   for (...) { err = FOO(x); } // OK
842f7e3c444SJacob Faibussowitsch .ve
843f7e3c444SJacob Faibussowitsch 
844f7e3c444SJacob Faibussowitsch   It is also not portable to use this macro directly inside function call, conditional, loop,
845f7e3c444SJacob Faibussowitsch   or switch statements\:
846f7e3c444SJacob Faibussowitsch 
847f7e3c444SJacob Faibussowitsch .vb
848f7e3c444SJacob Faibussowitsch   extern void bar(int);
849f7e3c444SJacob Faibussowitsch 
850f7e3c444SJacob Faibussowitsch   int ret = FOO(x);
851f7e3c444SJacob Faibussowitsch 
852f7e3c444SJacob Faibussowitsch   bar(FOO(x)); // ERROR, may not compile
853f7e3c444SJacob Faibussowitsch   bar(ret);    // OK
854f7e3c444SJacob Faibussowitsch 
855f7e3c444SJacob Faibussowitsch   if (FOO(x))  // ERROR, may not compile
856f7e3c444SJacob Faibussowitsch   if (ret)     // OK
857f7e3c444SJacob Faibussowitsch .ve
858f7e3c444SJacob Faibussowitsch 
859f7e3c444SJacob Faibussowitsch   Example usage:
860f7e3c444SJacob Faibussowitsch .vb
861f7e3c444SJacob Faibussowitsch   #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10)
862f7e3c444SJacob Faibussowitsch 
863f7e3c444SJacob Faibussowitsch   int x = 10;
864f7e3c444SJacob Faibussowitsch   int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20
865f7e3c444SJacob Faibussowitsch 
866f7e3c444SJacob Faibussowitsch   // multiline macros allowed, but must declare with line continuation as usual
867f7e3c444SJacob Faibussowitsch   #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \
868f7e3c444SJacob Faibussowitsch     if (arg1 > 10) {                                            \
869f7e3c444SJacob Faibussowitsch       puts("big int!");                                         \
870f7e3c444SJacob Faibussowitsch     } else {                                                    \
871f7e3c444SJacob Faibussowitsch       return 7355608;                                           \
872f7e3c444SJacob Faibussowitsch     }                                                           \
873f7e3c444SJacob Faibussowitsch   )
874f7e3c444SJacob Faibussowitsch 
875f7e3c444SJacob Faibussowitsch   // if retexpr contains commas, must enclose it with braces
876f7e3c444SJacob Faibussowitsch   #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...)
877f7e3c444SJacob Faibussowitsch   #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...)
878f7e3c444SJacob Faibussowitsch 
879f7e3c444SJacob Faibussowitsch   int x = 10;
880f7e3c444SJacob Faibussowitsch   int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0
881f7e3c444SJacob Faibussowitsch   int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20
882f7e3c444SJacob Faibussowitsch .ve
883f7e3c444SJacob Faibussowitsch 
884f7e3c444SJacob Faibussowitsch   Level: intermediate
885f7e3c444SJacob Faibussowitsch 
886db781477SPatrick Sanan .seealso: `PetscExpand()`, `PetscConcat()`, `PetscStringize()`
887f7e3c444SJacob Faibussowitsch M*/
888f7e3c444SJacob Faibussowitsch #define PetscMacroReturns(retexpr, ...) PetscMacroReturns_(retexpr, __VA_ARGS__)
889f7e3c444SJacob Faibussowitsch 
890f7e3c444SJacob Faibussowitsch #define PetscMacroReturnStandard(...) PetscMacroReturns(0, __VA_ARGS__)
891f7e3c444SJacob Faibussowitsch 
892bde483f2SJacob Faibussowitsch #endif /* !PETSC_SKIP_VARIADIC_MACROS */
893bde483f2SJacob Faibussowitsch 
894dd39110bSPierre Jolivet /*MC
895dd39110bSPierre Jolivet   PETSC_STATIC_ARRAY_LENGTH - Return the length of a static array
896dd39110bSPierre Jolivet 
897dd39110bSPierre Jolivet   Level: intermediate
898dd39110bSPierre Jolivet M*/
899dd39110bSPierre Jolivet #define PETSC_STATIC_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
900dd39110bSPierre Jolivet 
901296d8154SBarry Smith /*
902296d8154SBarry Smith   These macros allow extracting out the first argument or all but the first argument from a macro __VAR_ARGS__ INSIDE another macro.
903296d8154SBarry Smith 
904296d8154SBarry Smith   Example usage:
905296d8154SBarry Smith 
906296d8154SBarry Smith   #define mymacro(obj,...) {
907296d8154SBarry Smith     PETSC_FIRST_ARG((__VA_ARGS__,unused));
908296d8154SBarry Smith     f(22 PETSC_REST_ARG(__VA_ARGS__));
909296d8154SBarry Smith   }
910296d8154SBarry Smith 
911296d8154SBarry Smith   Note you add a dummy extra argument to __VA_ARGS__ and enclose them in an extra set of () for PETSC_FIRST_ARG() and PETSC_REST_ARG(__VA_ARGS__) automatically adds a leading comma only if there are additional arguments
912296d8154SBarry Smith 
913296d8154SBarry Smith   Reference:
914296d8154SBarry Smith   https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick
915296d8154SBarry Smith */
916296d8154SBarry Smith #define PETSC_FIRST_ARG_(N, ...)                                                                      N
917296d8154SBarry Smith #define PETSC_FIRST_ARG(args)                                                                         PETSC_FIRST_ARG_ args
918296d8154SBarry Smith #define PETSC_SELECT_16TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16
919296d8154SBarry Smith #define PETSC_NUM(...)                                                                                PETSC_SELECT_16TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
920296d8154SBarry Smith #define PETSC_REST_HELPER_TWOORMORE(first, ...)                                                       , __VA_ARGS__
921296d8154SBarry Smith #define PETSC_REST_HELPER_ONE(first)
922296d8154SBarry Smith #define PETSC_REST_HELPER2(qty, ...) PETSC_REST_HELPER_##qty(__VA_ARGS__)
923296d8154SBarry Smith #define PETSC_REST_HELPER(qty, ...)  PETSC_REST_HELPER2(qty, __VA_ARGS__)
924296d8154SBarry Smith #define PETSC_REST_ARG(...)          PETSC_REST_HELPER(PETSC_NUM(__VA_ARGS__), __VA_ARGS__)
925296d8154SBarry Smith 
926bde483f2SJacob Faibussowitsch #endif /* PETSC_PREPROCESSOR_MACROS_H */
927