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