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