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