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