1 #pragma once 2 3 #include <petscconf.h> 4 #include <petscconf_poison.h> /* for PetscDefined() error checking */ 5 6 /* SUBMANSEC = Sys */ 7 8 #if defined(__cplusplus) 9 #if __cplusplus <= 201103L 10 #define PETSC_CPP_VERSION 11 11 #elif __cplusplus <= 201402L 12 #define PETSC_CPP_VERSION 14 13 #elif __cplusplus <= 201703L 14 #define PETSC_CPP_VERSION 17 15 #elif __cplusplus <= 202002L 16 #define PETSC_CPP_VERSION 20 17 #else 18 #define PETSC_CPP_VERSION 22 // current year, or date of c++2b ratification 19 #endif 20 #endif // __cplusplus 21 22 #ifndef PETSC_CPP_VERSION 23 #define PETSC_CPP_VERSION 0 24 #endif 25 26 #if defined(__STDC_VERSION__) 27 #if __STDC_VERSION__ <= 199901L 28 // C99 except that 99 is >= 11 or 17 so we shorten it to 9 instead 29 #define PETSC_C_VERSION 9 30 #elif __STDC_VERSION__ <= 201112L 31 #define PETSC_C_VERSION 11 32 #elif __STDC_VERSION__ <= 201710L 33 #define PETSC_C_VERSION 17 34 #else 35 #define PETSC_C_VERSION 22 // current year, or date of c2b ratification 36 #endif 37 #endif // __STDC_VERSION__ 38 39 #ifndef PETSC_C_VERSION 40 #define PETSC_C_VERSION 0 41 #endif 42 43 /* ========================================================================== */ 44 /* This facilitates using the C version of PETSc from C++ and the C++ version from C. */ 45 #if defined(__cplusplus) 46 #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_CXX 47 #else 48 #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_C 49 #endif 50 51 /* ========================================================================== */ 52 /* Since PETSc manages its own extern "C" handling users should never include PETSc include 53 * files within extern "C". This will generate a compiler error if a user does put the include 54 * file within an extern "C". 55 */ 56 #if defined(__cplusplus) 57 void assert_never_put_petsc_headers_inside_an_extern_c(int); 58 void assert_never_put_petsc_headers_inside_an_extern_c(double); 59 #endif 60 61 #if defined(__cplusplus) 62 #define PETSC_RESTRICT PETSC_CXX_RESTRICT 63 #else 64 #define PETSC_RESTRICT restrict 65 #endif 66 67 #define PETSC_INLINE PETSC_DEPRECATED_MACRO(3, 17, 0, "inline", ) inline 68 #define PETSC_STATIC_INLINE PETSC_DEPRECATED_MACRO(3, 17, 0, "static inline", ) static inline 69 70 #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */ 71 #define PETSC_DLLEXPORT __declspec(dllexport) 72 #define PETSC_DLLIMPORT __declspec(dllimport) 73 #define PETSC_VISIBILITY_INTERNAL 74 #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX) 75 #define PETSC_DLLEXPORT __attribute__((visibility("default"))) 76 #define PETSC_DLLIMPORT __attribute__((visibility("default"))) 77 #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden"))) 78 #elif !defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_C) 79 #define PETSC_DLLEXPORT __attribute__((visibility("default"))) 80 #define PETSC_DLLIMPORT __attribute__((visibility("default"))) 81 #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden"))) 82 #else 83 #define PETSC_DLLEXPORT 84 #define PETSC_DLLIMPORT 85 #define PETSC_VISIBILITY_INTERNAL 86 #endif 87 88 #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */ 89 #define PETSC_VISIBILITY_PUBLIC PETSC_DLLEXPORT 90 #else /* Win32 users need this to import symbols from petsc.dll */ 91 #define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT 92 #endif 93 94 /* Functions tagged with PETSC_EXTERN in the header files are always defined as extern "C" when 95 * compiled with C++ so they may be used from C and are always visible in the shared libraries 96 */ 97 #if defined(__cplusplus) 98 #define PETSC_EXTERN extern "C" PETSC_VISIBILITY_PUBLIC 99 #define PETSC_EXTERN_TYPEDEF extern "C" 100 #define PETSC_INTERN extern "C" PETSC_VISIBILITY_INTERNAL 101 #else 102 #define PETSC_EXTERN extern PETSC_VISIBILITY_PUBLIC 103 #define PETSC_EXTERN_TYPEDEF 104 #define PETSC_INTERN extern PETSC_VISIBILITY_INTERNAL 105 #endif 106 107 #if defined(PETSC_USE_SINGLE_LIBRARY) 108 #define PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PETSC_VISIBILITY_INTERNAL 109 #define PETSC_SINGLE_LIBRARY_INTERN PETSC_INTERN 110 #else 111 #define PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PETSC_VISIBILITY_PUBLIC 112 #define PETSC_SINGLE_LIBRARY_INTERN PETSC_EXTERN 113 #endif 114 115 #if !defined(__has_feature) 116 #define __has_feature(x) 0 117 #endif 118 119 /*MC 120 PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler 121 122 Synopsis: 123 #include <petscmacros.h> 124 int PetscHasAttribute(name) 125 126 Input Parameter: 127 . name - The name of the attribute to test 128 129 Level: intermediate 130 131 Notes: 132 name should be identical to what you might pass to the __attribute__ declaration itself -- 133 plain, unbroken text. 134 135 As `PetscHasAttribute()` is wrapper over the function-like macro `__has_attribute()`, the 136 exact type and value returned is implementation defined. In practice however, it usually 137 returns `1` if the attribute is supported and `0` if the attribute is not supported. 138 139 Example Usage: 140 Typical usage is using the preprocessor 141 142 .vb 143 #if PetscHasAttribute(always_inline) 144 # define MY_ALWAYS_INLINE __attribute__((always_inline)) 145 #else 146 # define MY_ALWAYS_INLINE 147 #endif 148 149 void foo(void) MY_ALWAYS_INLINE; 150 .ve 151 152 but it can also be used in regular code 153 154 .vb 155 if (PetscHasAttribute(some_attribute)) { 156 foo(); 157 } else { 158 bar(); 159 } 160 .ve 161 162 .seealso: `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`, 163 `PETSC_ATTRIBUTE_FORMAT`, `PETSC_ATTRIBUTE_MAY_ALIAS` 164 M*/ 165 #if !defined(__has_attribute) 166 #define __has_attribute(x) 0 167 #endif 168 #define PetscHasAttribute(name) __has_attribute(name) 169 170 /*MC 171 PetscHasBuiltin - Determine whether a particular builtin method is supported by the compiler 172 173 Synopsis: 174 #include <petscmacros.h> 175 int PetscHasBuiltin(name) 176 177 Input Parameter: 178 . name - the name of the builtin routine 179 180 Level: intermediate 181 182 Notes: 183 Evaluates to `1` if the builtin is supported and `0` otherwise. Note the term "evaluates" 184 (vs "expands") is deliberate; even though `PetscHasBuiltin()` is a macro the underlying 185 detector is itself is a compiler extension with implementation-defined return type and 186 semantics. Some compilers implement it as a macro, others as a compiler function. In practice 187 however, all supporting compilers return an integer boolean as described. 188 189 Example Usage: 190 Typical usage is in preprocessor directives 191 192 .vb 193 #if PetscHasBuiltin(__builtin_trap) 194 __builtin_trap(); 195 #else 196 abort(); 197 #endif 198 .ve 199 200 But it may also be used in regular code 201 202 .vb 203 if (PetscHasBuiltin(__builtin_alloca)) { 204 foo(); 205 } else { 206 bar(); 207 } 208 .ve 209 210 .seealso: `PetscHasAttribute()`, `PetscAssume()` 211 M*/ 212 #if !defined(__has_builtin) 213 #define __has_builtin(x) 0 214 #endif 215 // clangs __has_builtin prior to clang 10 did not properly handle non-function builtins such as 216 // __builtin_types_compatible_p which take types or other non-functiony things as 217 // arguments. The correct way to detect these then is to use __is_identifier (also a clang 218 // extension). GCC has always worked as expected. see https://stackoverflow.com/a/45043153 219 #if defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 10) && defined(__is_identifier) 220 #define PetscHasBuiltin(name) __is_identifier(name) 221 #else 222 #define PetscHasBuiltin(name) __has_builtin(name) 223 #endif 224 225 #if !defined(PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG) 226 /* 227 Support for Clang (>=3.2) matching type tag arguments with void* buffer types. 228 This allows the compiler to detect cases where the MPI datatype argument passed to a MPI routine 229 does not match the actual type of the argument being passed in 230 */ 231 #if PetscHasAttribute(pointer_with_type_tag) 232 #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) __attribute__((pointer_with_type_tag(MPI, bufno, typeno))) 233 #endif 234 235 #if PetscHasAttribute(type_tag_for_datatype) 236 #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type) __attribute__((type_tag_for_datatype(MPI, type))) 237 #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type) __attribute__((type_tag_for_datatype(MPI, type, layout_compatible))) 238 #endif 239 #endif // PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG 240 241 #ifndef PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE 242 #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) 243 #endif 244 245 #ifndef PETSC_ATTRIBUTE_MPI_TYPE_TAG 246 #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type) 247 #endif 248 249 #ifndef PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE 250 #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type) 251 #endif 252 253 /*MC 254 PETSC_ATTRIBUTE_FORMAT - Indicate to the compiler that specified arguments should be treated 255 as format specifiers and checked for validity 256 257 Synopsis: 258 #include <petscmacros.h> 259 <attribute declaration> PETSC_ATTRIBUTE_FORMAT(int strIdx, int vaArgIdx) 260 261 Input Parameters: 262 + strIdx - The (1-indexed) location of the format string in the argument list 263 - vaArgIdx - The (1-indexed) location of the first formattable argument in the argument list 264 265 Level: developer 266 267 Notes: 268 This function attribute causes the compiler to issue warnings when the format specifier does 269 not match the type of the variable that will be formatted, or when there exists a mismatch 270 between the number of format specifiers and variables to be formatted. It is safe to use this 271 macro if your compiler does not support format specifier checking (though this is 272 exceeedingly rare). 273 274 Both `strIdx` and `vaArgIdx` must be compile-time constant integer literals and cannot have the 275 same value. 276 277 The arguments to be formatted (and therefore checked by the compiler) must be "contiguous" in 278 the argument list, that is, there is no way to indicate gaps which should not be checked. 279 280 Definition is suppressed by defining `PETSC_SKIP_ATTRIBUTE_FORMAT` prior to including PETSc 281 header files. In this case the macro will expand empty. 282 283 Example Usage: 284 .vb 285 // format string is 2nd argument, variable argument list containing args is 3rd argument 286 void my_printf(void *obj, const char *fmt_string, ...) PETSC_ATTRIBUTE_FORMAT(2,3) 287 288 int x = 1; 289 double y = 50.0; 290 291 my_printf(NULL,"%g",x); // WARNING, format specifier does not match for 'int'! 292 my_printf(NULL,"%d",x,y); // WARNING, more arguments than format specifiers! 293 my_printf(NULL,"%d %g",x,y); // OK 294 .ve 295 296 .seealso: `PETSC_ATTRIBUTE_COLD`, `PetscHasAttribute()` 297 M*/ 298 #if PetscHasAttribute(format) && !defined(PETSC_SKIP_ATTRIBUTE_FORMAT) 299 #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) __attribute__((format(printf, strIdx, vaArgIdx))) 300 #else 301 #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) 302 #endif 303 304 /*MC 305 PETSC_ATTRIBUTE_COLD - Indicate to the compiler that a function is very unlikely to be 306 executed 307 308 Level: intermediate 309 310 Notes: 311 The marked function is often optimized for size rather than speed and may be grouped alongside 312 other equally frigid routines improving code locality of lukewarm or hotter parts of program. 313 314 The paths leading to cold functions are usually automatically marked as unlikely by the 315 compiler. It may thus be useful to mark functions used to handle unlikely conditions -- such 316 as error handlers -- as cold to improve optimization of the surrounding temperate functions. 317 318 Example Usage: 319 .vb 320 void my_error_handler(...) PETSC_ATTRIBUTE_COLD; 321 322 if (temperature < 0) { 323 return my_error_handler(...); // chilly! 324 } 325 .ve 326 327 .seealso: `PetscUnlikely()`, `PetscUnlikelyDebug()`, `PetscLikely()`, `PetscLikelyDebug()`, 328 `PetscUnreachable()`, `PETSC_ATTRIBUTE_FORMAT` 329 M*/ 330 #if PetscHasAttribute(__cold__) 331 #define PETSC_ATTRIBUTE_COLD __attribute__((__cold__)) 332 #elif PetscHasAttribute(cold) /* some implementations (old gcc) use no underscores */ 333 #define PETSC_ATTRIBUTE_COLD __attribute__((cold)) 334 #else 335 #define PETSC_ATTRIBUTE_COLD 336 #endif 337 338 /*MC 339 PETSC_ATTRIBUTE_MAY_ALIAS - Indicate to the compiler that a type is not 340 subjected to type-based alias analysis, but is instead assumed to be able to 341 alias any other type of objects 342 343 Example Usage: 344 .vb 345 typedef PetscScalar PetscScalarAlias PETSC_ATTRIBUTE_MAY_ALIAS; 346 347 PetscReal *pointer; 348 PetscScalarAlias *other_pointer = reinterpret_cast<PetscScalarAlias *>(pointer); 349 .ve 350 351 Level: advanced 352 353 .seealso: `PetscHasAttribute()` 354 M*/ 355 #if PetscHasAttribute(may_alias) && !defined(PETSC_SKIP_ATTRIBUTE_MAY_ALIAS) 356 #define PETSC_ATTRIBUTE_MAY_ALIAS __attribute__((may_alias)) 357 #else 358 #define PETSC_ATTRIBUTE_MAY_ALIAS 359 #endif 360 361 /*MC 362 PETSC_NULLPTR - Standard way of indicating a null value or pointer 363 364 No Fortran Support 365 366 Level: beginner 367 368 Notes: 369 Equivalent to `NULL` in C source, and `nullptr` in C++ source. Note that for the purposes of 370 interoperability between C and C++, setting a pointer to `PETSC_NULLPTR` in C++ is functonially 371 equivalent to setting the same pointer to `NULL` in C. That is to say that the following 372 expressions are equivalent\: 373 374 .vb 375 ptr == PETSC_NULLPTR 376 ptr == NULL 377 ptr == 0 378 !ptr 379 380 ptr = PETSC_NULLPTR 381 ptr = NULL 382 ptr = 0 383 .ve 384 385 and for completeness' sake\: 386 387 .vb 388 PETSC_NULLPTR == NULL 389 .ve 390 391 Example Usage: 392 .vb 393 // may be used in place of '\0' or other such terminators in the definition of char arrays 394 const char *const MyEnumTypes[] = { 395 "foo", 396 "bar", 397 PETSC_NULLPTR 398 }; 399 400 // may be used to nullify objects 401 PetscObject obj = PETSC_NULLPTR; 402 403 // may be used in any function expecting NULL 404 PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor"); 405 .ve 406 407 Developer Notes: 408 `PETSC_NULLPTR` must be used in place of `NULL` in all C++ source files. Using `NULL` in source 409 files compiled with a C++ compiler may lead to unexpected side-effects in function overload 410 resolution and/or compiler warnings. 411 412 .seealso: `PETSC_CONSTEXPR_14`, `PETSC_NODISCARD` 413 M*/ 414 415 /*MC 416 PETSC_CONSTEXPR_14 - C++14 constexpr 417 418 No Fortran Support 419 420 Level: beginner 421 422 Notes: 423 Equivalent to `constexpr` when using a C++ compiler that supports C++14. Expands to nothing 424 if the C++ compiler does not support C++14 or when not compiling with a C++ compiler. Note 425 that this cannot be used in cases where an empty expansion would result in invalid code. It 426 is safe to use this in C source files. 427 428 Example Usage: 429 .vb 430 PETSC_CONSTEXPR_14 int factorial(int n) 431 { 432 int r = 1; 433 434 do { 435 r *= n; 436 } while (--n); 437 return r; 438 } 439 .ve 440 441 .seealso: `PETSC_NULLPTR`, `PETSC_NODISCARD` 442 M*/ 443 444 /*MC 445 PETSC_NODISCARD - Mark the return value of a function as non-discardable 446 447 Not available in Fortran 448 449 Level: beginner 450 451 Notes: 452 Hints to the compiler that the return value of a function must be captured. A diagnostic may 453 (but is not required to) be emitted if the value is discarded. It is safe to use this in both 454 C and C++ source files. 455 456 In this context "captured" means assigning the return value of a function to a named 457 variable or casting it to `void`. Between the two, assigning to a named variable is the most 458 portable way of silencing any warnings, since `PETSC_NODISCARD` may expand to GCC's 459 `__attribute__((warn_unused_result))` which will still emit warnings when casting results to 460 `void`. 461 462 Example Usage: 463 .vb 464 class Foo 465 { 466 int x; 467 468 public: 469 PETSC_NODISCARD Foo(int y) : x(y) { } 470 }; 471 472 PETSC_NODISCARD int factorial(int n) 473 { 474 return n <= 1 ? 1 : (n * factorial(n - 1)); 475 } 476 477 factorial(10); // Warning: ignoring return value of function declared 'nodiscard' 478 auto x = factorial(10); // OK, capturing return value 479 (void)factorial(10); // Maybe OK, casting to void 480 auto y = factorial(10); // OK, capturing in y (and casting y to void to silence 481 (void)y; // set-but-not-used warnings) 482 483 Foo(x); // Warning: Ignoring temporary created by a constructor declared 'nodiscard' 484 auto f = Foo(x); // OK, capturing constructed object 485 (void)Foo(x); // Maybe OK, casting to void 486 auto g = Foo(x); // OK, capturing in g (and casting g to void to silence set-but-not-used 487 (void)g; // warnings) 488 .ve 489 490 .seealso: `PETSC_NULLPTR`, `PETSC_CONSTEXPR_14` 491 M*/ 492 493 /* C++11 features */ 494 #if defined(__cplusplus) || (PETSC_C_VERSION >= 23) 495 #define PETSC_NULLPTR nullptr 496 #else 497 #define PETSC_NULLPTR NULL 498 #endif 499 500 /* C++14 features */ 501 #if PETSC_CPP_VERSION >= 14 502 #define PETSC_CONSTEXPR_14 constexpr 503 #else 504 #define PETSC_CONSTEXPR_14 505 #endif 506 507 /* C++17 features */ 508 #if PETSC_CPP_VERSION >= 17 509 #define PETSC_CONSTEXPR_17 constexpr 510 #else 511 #define PETSC_CONSTEXPR_17 512 #endif 513 514 #if (PETSC_CPP_VERSION >= 17) || (PETSC_C_VERSION >= 23) 515 #define PETSC_NODISCARD [[nodiscard]] 516 #elif PetscHasAttribute(warn_unused_result) 517 #define PETSC_NODISCARD __attribute__((warn_unused_result)) 518 #else 519 #define PETSC_NODISCARD 520 #endif 521 522 #include <petscversion.h> 523 #define PETSC_AUTHOR_INFO " The PETSc Team\n petsc-maint@mcs.anl.gov\n https://petsc.org/\n" 524 525 /* designated initializers since C99 and C++20, MSVC never supports them though */ 526 #if defined(_MSC_VER) || (defined(__cplusplus) && (PETSC_CPP_VERSION < 20)) 527 #define PetscDesignatedInitializer(name, ...) __VA_ARGS__ 528 #else 529 #define PetscDesignatedInitializer(name, ...) .name = __VA_ARGS__ 530 #endif 531 532 /*MC 533 PetscUnlikely - Hints the compiler that the given condition is usually false 534 535 Synopsis: 536 #include <petscmacros.h> 537 bool PetscUnlikely(bool cond) 538 539 Not Collective; No Fortran Support 540 541 Input Parameter: 542 . cond - Boolean expression 543 544 Level: advanced 545 546 Note: 547 This returns the same truth value, it is only a hint to compilers that the result of cond is 548 unlikely to be true. 549 550 Example usage: 551 .vb 552 if (PetscUnlikely(cond)) { 553 foo(); // cold path 554 } else { 555 bar(); // hot path 556 } 557 .ve 558 559 .seealso: `PetscLikely()`, `PetscUnlikelyDebug()`, `PetscCall()`, `PetscDefined()`, `PetscHasAttribute()`, 560 `PETSC_ATTRIBUTE_COLD` 561 M*/ 562 563 /*MC 564 PetscLikely - Hints the compiler that the given condition is usually true 565 566 Synopsis: 567 #include <petscmacros.h> 568 bool PetscLikely(bool cond) 569 570 Not Collective; No Fortran Support 571 572 Input Parameter: 573 . cond - Boolean expression 574 575 Level: advanced 576 577 Note: 578 This returns the same truth value, it is only a hint to compilers that the result of cond is 579 likely to be true. 580 581 Example usage: 582 .vb 583 if (PetscLikely(cond)) { 584 foo(); // hot path 585 } else { 586 bar(); // cold path 587 } 588 .ve 589 590 .seealso: `PetscUnlikely()`, `PetscDefined()`, `PetscHasAttribute()` 591 `PETSC_ATTRIBUTE_COLD` 592 M*/ 593 #if defined(PETSC_HAVE_BUILTIN_EXPECT) 594 #define PetscUnlikely(cond) __builtin_expect(!!(cond), 0) 595 #define PetscLikely(cond) __builtin_expect(!!(cond), 1) 596 #else 597 #define PetscUnlikely(cond) (cond) 598 #define PetscLikely(cond) (cond) 599 #endif 600 601 /*MC 602 PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable 603 604 Synopsis: 605 #include <petscmacros.h> 606 void PetscUnreachable(void) 607 608 Level: advanced 609 610 Note: 611 Indicates to the compiler (usually via some built-in) that a particular code path is always 612 unreachable. Behavior is undefined if this function is ever executed, the user can expect an 613 unceremonious crash. 614 615 Example usage: 616 Useful in situations such as switches over enums where not all enumeration values are 617 explicitly covered by the switch 618 619 .vb 620 typedef enum {RED, GREEN, BLUE} Color; 621 622 int foo(Color c) 623 { 624 // it is known to programmer (or checked previously) that c is either RED or GREEN 625 // but compiler may not be able to deduce this and/or emit spurious warnings 626 switch (c) { 627 case RED: 628 return bar(); 629 case GREEN: 630 return baz(); 631 default: 632 PetscUnreachable(); // program is ill-formed if executed 633 } 634 } 635 .ve 636 637 .seealso: `SETERRABORT()`, `PETSCABORT()`, `PETSC_ATTRIBUTE_COLD`, `PetscAssume()` 638 M*/ 639 #if PETSC_CPP_VERSION >= 23 640 #include <utility> 641 #define PetscUnreachable() std::unreachable() 642 #elif defined(__GNUC__) 643 /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */ 644 #define PetscUnreachable() __builtin_unreachable() 645 #elif defined(_MSC_VER) /* MSVC */ 646 #define PetscUnreachable() __assume(0) 647 #else /* ??? */ 648 #define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Code path explicitly marked as unreachable executed") 649 #endif 650 651 /*MC 652 PetscAssume - Indicate to the compiler a condition that is defined to be true 653 654 Synopsis: 655 #include <petscmacros.h> 656 void PetscAssume(bool cond) 657 658 Input Parameter: 659 . cond - Boolean expression 660 661 Level: advanced 662 663 Notes: 664 If supported by the compiler, `cond` is used to inform the optimizer of an invariant 665 truth. The argument itself is never evaluated, so any side effects of the expression will be 666 discarded. This macro is used in `PetscAssert()` to retain information gained from debug 667 checks that would be lost in optimized builds. For example\: 668 669 .vb 670 PetscErrorCode foo(PetscInt x) { 671 672 PetscAssert(x >= 0, ...); 673 } 674 .ve 675 676 The assertion checks that `x` is positive when debugging is enabled (and returns from `foo()` 677 if it is not). This implicitly informs the optimizer that `x` cannot be negative. However, 678 when debugging is disabled any `PetscAssert()` checks are tautologically false, and hence the 679 optimizer cannot deduce any information from them. 680 681 Due to compiler limitations `PetscAssume()` works best when `cond` involves 682 constants. Certain compilers do not yet propagate symbolic inequalities i.e.\: 683 684 .vb 685 int a, b, var_five; 686 687 // BEST, all supporting compilers will understand a cannot be >= 5 688 PetscAssume(a < 5); 689 690 // OK, some compilers may understand that a cannot be >= 5 691 PetscAssume(a <= b && b < 5); 692 693 // WORST, most compilers will not get the memo 694 PetscAssume(a <= b && b < var_five); 695 .ve 696 697 If the condition is violated at runtime then behavior is wholly undefined. If the 698 condition is violated at compile-time, the condition "supersedes" the compile-time violation 699 and the program is ill-formed, no diagnostic required. For example consider the following\: 700 701 .vb 702 PetscInt x = 0; 703 704 PetscAssume(x != 0); 705 if (x == 0) { 706 x += 10; 707 } else { 708 popen("rm -rf /", "w"); 709 } 710 .ve 711 712 Even though `x` is demonstrably `0` the compiler may opt to\: 713 714 - emit an unconditional `popen("rm -rf /", "w")` 715 - ignore `PetscAssume()` altogether and emit the correct path of `x += 10` 716 - reformat the primary disk partition 717 718 .seealso: `PetscAssert()` 719 M*/ 720 #if PETSC_CPP_VERSION >= 23 721 #define PetscAssume(...) [[assume(__VA_ARGS__)]] 722 #elif defined(_MSC_VER) // msvc 723 #define PetscAssume(...) __assume(__VA_ARGS__) 724 #elif defined(__clang__) && PetscHasBuiltin(__builtin_assume) // clang 725 #define PetscAssume(...) \ 726 do { \ 727 _Pragma("clang diagnostic push"); \ 728 _Pragma("clang diagnostic ignored \"-Wassume\""); \ 729 __builtin_assume(__VA_ARGS__); \ 730 _Pragma("clang diagnostic pop"); \ 731 } while (0) 732 #else // gcc (and really old clang) 733 // gcc does not have its own __builtin_assume() intrinsic. One could fake it via 734 // 735 // if (PetscUnlikely(!cond)) PetscUnreachable(); 736 // 737 // but this it unsavory because the side effects of cond are not guaranteed to be 738 // discarded. Though in most circumstances gcc will optimize out the if (because any evaluation 739 // for which cond is false would be undefined results in undefined behavior anyway) it cannot 740 // always do so. This is especially the case for opaque or non-inline function calls: 741 // 742 // extern int bar(int); 743 // 744 // int foo(int x) { 745 // PetscAssume(bar(x) == 2); 746 // if (bar(x) == 2) { 747 // return 1; 748 // } else { 749 // return 0; 750 // } 751 // } 752 // 753 // Here gcc would (if just using builtin_expect()) emit 2 calls to bar(). Note we still have 754 // cond "tested" in the condition, but this is done to silence unused-but-set variable warnings 755 #define PetscAssume(...) \ 756 do { \ 757 if (0 && (__VA_ARGS__)) PetscUnreachable(); \ 758 } while (0) 759 #endif 760 761 /*MC 762 PetscExpand - Expand macro argument 763 764 Synopsis: 765 #include <petscmacros.h> 766 <macro-expansion> PetscExpand(x) 767 768 Input Parameter: 769 . x - The preprocessor token to expand 770 771 Level: beginner 772 773 .seealso: `PetscStringize()`, `PetscConcat()` 774 M*/ 775 #define PetscExpand_(...) __VA_ARGS__ 776 #define PetscExpand(...) PetscExpand_(__VA_ARGS__) 777 778 /*MC 779 PetscStringize - Stringize a token 780 781 Synopsis: 782 #include <petscmacros.h> 783 const char* PetscStringize(x) 784 785 No Fortran Support 786 787 Input Parameter: 788 . x - The token you would like to stringize 789 790 Output Parameter: 791 . <return-value> - The string representation of `x` 792 793 Level: beginner 794 795 Note: 796 `PetscStringize()` expands `x` before stringizing it, if you do not wish to do so, use 797 `PetscStringize_()` instead. 798 799 Example Usage: 800 .vb 801 #define MY_OTHER_VAR hello there 802 #define MY_VAR MY_OTHER_VAR 803 804 PetscStringize(MY_VAR) -> "hello there" 805 PetscStringize_(MY_VAR) -> "MY_VAR" 806 807 int foo; 808 PetscStringize(foo) -> "foo" 809 PetscStringize_(foo) -> "foo" 810 .ve 811 812 .seealso: `PetscConcat()`, `PetscExpandToNothing()`, `PetscExpand()` 813 M*/ 814 #define PetscStringize_(...) #__VA_ARGS__ 815 #define PetscStringize(...) PetscStringize_(__VA_ARGS__) 816 817 /*MC 818 PetscConcat - Concatenate two tokens 819 820 Synopsis: 821 #include <petscmacros.h> 822 <macro-expansion> PetscConcat(x, y) 823 824 No Fortran Support 825 826 Input Parameters: 827 + x - First token 828 - y - Second token 829 830 Level: beginner 831 832 Note: 833 `PetscConcat()` will expand both arguments before pasting them together, use `PetscConcat_()` 834 if you don't want to expand them. 835 836 Example usage: 837 .vb 838 PetscConcat(hello,there) -> hellothere 839 840 #define HELLO hello 841 PetscConcat(HELLO,there) -> hellothere 842 PetscConcat_(HELLO,there) -> HELLOthere 843 .ve 844 845 .seealso: `PetscStringize()`, `PetscExpand()` 846 M*/ 847 #define PetscConcat_(x, y) x##y 848 #define PetscConcat(x, y) PetscConcat_(x, y) 849 850 #define PETSC_INTERNAL_COMPL_0 1 851 #define PETSC_INTERNAL_COMPL_1 0 852 853 /*MC 854 PetscCompl - Expands to the integer complement of its argument 855 856 Synopsis: 857 #include <petscmacros.h> 858 int PetscCompl(b) 859 860 No Fortran Support 861 862 Input Parameter: 863 . b - Preprocessor variable, must expand to either integer literal 0 or 1 864 865 Output Parameter: 866 . <return-value> - Either integer literal 0 or 1 867 868 Level: beginner 869 870 Notes: 871 Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to 872 0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its 873 argument before returning the complement. 874 875 This macro can be useful for negating `PetscDefined()` inside macros e.g. 876 .vb 877 #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO)) 878 .ve 879 880 Example usage: 881 .vb 882 #define MY_VAR 1 883 PetscCompl(MY_VAR) -> 0 884 885 #undef MY_VAR 886 #define MY_VAR 0 887 PetscCompl(MY_VAR) -> 1 888 .ve 889 890 .seealso: `PetscConcat()`, `PetscDefined()` 891 M*/ 892 #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_, PetscExpand(b)) 893 894 /*MC 895 PetscDefined - Determine whether a boolean macro is defined 896 897 Synopsis: 898 #include <petscmacros.h> 899 int PetscDefined(def) 900 901 No Fortran Support 902 903 Input Parameter: 904 . def - PETSc-style preprocessor variable (without PETSC_ prepended!) 905 906 Output Parameter: 907 . <return-value> - Either integer literal 0 or 1 908 909 Level: intermediate 910 911 Notes: 912 `PetscDefined()` returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to 913 integer literal 1. In all other cases, `PetscDefined()` returns integer literal 0. Therefore 914 this macro should not be used if its argument may be defined to a non-empty value other than 915 1. 916 917 The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to 918 add custom checks in user code, one should use `PetscDefined_()`. 919 .vb 920 #define FooDefined(d) PetscDefined_(PetscConcat(FOO_, d)) 921 .ve 922 923 Developer Notes: 924 Getting something that works in C and CPP for an arg that may or may not be defined is 925 tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define, 926 insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks 927 the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair, 928 and when the last step cherry picks the 2nd arg, we get a zero. 929 930 Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a 931 nonconforming implementation of variadic macros. 932 933 Example Usage: 934 Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG 935 is defined then 936 937 .vb 938 #if PetscDefined(USE_DEBUG) 939 foo(); 940 #else 941 bar(); 942 #endif 943 944 // or alternatively within normal code 945 if (PetscDefined(USE_DEBUG)) { 946 foo(); 947 } else { 948 bar(); 949 } 950 .ve 951 952 is equivalent to 953 954 .vb 955 #if defined(PETSC_USE_DEBUG) 956 # if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro 957 foo(); 958 # elif PETSC_USE_DEBUG == 1 959 foo(); 960 # else 961 bar(); 962 # endif 963 #else 964 bar(); 965 #endif 966 .ve 967 968 .seealso: `PetscHasAttribute()`, `PetscUnlikely()`, `PetscLikely()`, `PetscConcat()`, 969 `PetscExpandToNothing()`, `PetscCompl()` 970 M*/ 971 #define PetscDefined_arg_1 shift, 972 #define PetscDefined_arg_ shift, 973 #define PetscDefined__take_second_expanded(ignored, val, ...) val 974 #define PetscDefined__take_second_expand(args) PetscDefined__take_second_expanded args 975 #define PetscDefined__take_second(...) PetscDefined__take_second_expand((__VA_ARGS__)) 976 #define PetscDefined__(arg1_or_junk) PetscDefined__take_second(arg1_or_junk 1, 0, at_) 977 #define PetscDefined_(value) PetscDefined__(PetscConcat_(PetscDefined_arg_, value)) 978 #define PetscDefined(def) PetscDefined_(PetscConcat(PETSC_, def)) 979 980 /*MC 981 PetscUnlikelyDebug - Hints the compiler that the given condition is usually false, eliding 982 the check in optimized mode 983 984 Synopsis: 985 #include <petscmacros.h> 986 bool PetscUnlikelyDebug(bool cond) 987 988 Not Collective; No Fortran Support 989 990 Input Parameter: 991 . cond - Boolean expression 992 993 Level: advanced 994 995 Note: 996 This returns the same truth value, it is only a hint to compilers that the result of `cond` is 997 likely to be false. When PETSc is compiled in optimized mode this will always return 998 false. Additionally, `cond` is guaranteed to not be evaluated when PETSc is compiled in 999 optimized mode. 1000 1001 Example usage: 1002 This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG) 1003 is true. So 1004 1005 .vb 1006 if (PetscUnlikelyDebug(cond)) { 1007 foo(); 1008 } else { 1009 bar(); 1010 } 1011 .ve 1012 1013 is equivalent to 1014 1015 .vb 1016 if (PetscDefined(USE_DEBUG)) { 1017 if (PetscUnlikely(cond)) { 1018 foo(); 1019 } else { 1020 bar(); 1021 } 1022 } else { 1023 bar(); 1024 } 1025 .ve 1026 1027 .seealso: `PetscUnlikely()`, `PetscLikely()`, `PetscCall()`, `SETERRQ` 1028 M*/ 1029 #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond)) 1030 1031 #if defined(PETSC_CLANG_STATIC_ANALYZER) 1032 // silence compiler warnings when using -pedantic, this is only used by the linter and it cares 1033 // not what ISO C allows 1034 #define PetscMacroReturns_(retexpr, ...) \ 1035 __extension__({ \ 1036 __VA_ARGS__; \ 1037 retexpr; \ 1038 }) 1039 #else 1040 #define PetscMacroReturns_(retexpr, ...) \ 1041 retexpr; \ 1042 do { \ 1043 __VA_ARGS__; \ 1044 } while (0) 1045 #endif 1046 1047 /*MC 1048 PetscExpandToNothing - Expands to absolutely nothing 1049 1050 Synopsis: 1051 #include <petscmacros.h> 1052 void PetscExpandToNothing(...) 1053 1054 No Fortran Support 1055 1056 Input Parameter: 1057 . __VA_ARGS__ - Anything at all 1058 1059 Level: beginner 1060 1061 Note: 1062 Must have at least 1 parameter. 1063 1064 Example usage: 1065 .vb 1066 PetscExpandToNothing(a,b,c) -> *nothing* 1067 .ve 1068 1069 .seealso: `PetscConcat()`, `PetscDefined()`, `PetscStringize()`, `PetscExpand()` 1070 M*/ 1071 #define PetscExpandToNothing(...) 1072 1073 /*MC 1074 PetscMacroReturns - Define a macro body that returns a value 1075 1076 Synopsis: 1077 #include <petscmacros.h> 1078 return_type PetscMacroReturns(return_type retexpr, ...) 1079 1080 Input Parameters: 1081 + retexpr - The value or expression that the macro should return 1082 - __VA_ARGS__ - The body of the macro 1083 1084 Level: intermediate 1085 1086 Notes: 1087 Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the 1088 body of the macro and should not depend on values produced as a result of the expression. The 1089 user should not assume that the result of this macro is equivalent to a single logical source 1090 line. It is not portable to use macros defined using this one in conditional or loop bodies 1091 without enclosing them in curly braces\: 1092 1093 .vb 1094 #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0 1095 1096 int err,x = 10; 1097 1098 if (...) err = FOO(x); // ERROR, body of FOO() executed outside the if statement 1099 if (...) { err = FOO(x); } // OK 1100 1101 for (...) err = FOO(x); // ERROR, body of FOO() executed outside the loop 1102 for (...) { err = FOO(x); } // OK 1103 .ve 1104 1105 It is also not portable to use this macro directly inside function call, conditional, loop, 1106 or switch statements\: 1107 1108 .vb 1109 extern void bar(int); 1110 1111 int ret = FOO(x); 1112 1113 bar(FOO(x)); // ERROR, may not compile 1114 bar(ret); // OK 1115 1116 if (FOO(x)) // ERROR, may not compile 1117 if (ret) // OK 1118 .ve 1119 1120 Example usage: 1121 .vb 1122 #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10) 1123 1124 int x = 10; 1125 int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20 1126 1127 // multiline macros allowed, but must declare with line continuation as usual 1128 #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \ 1129 if (arg1 > 10) { \ 1130 puts("big int!"); \ 1131 } else { \ 1132 return 7355608; \ 1133 } \ 1134 ) 1135 1136 // if retexpr contains commas, must enclose it with braces 1137 #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...) 1138 #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...) 1139 1140 int x = 10; 1141 int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0 1142 int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20 1143 .ve 1144 1145 .seealso: `PetscExpand()`, `PetscConcat()`, `PetscStringize()` 1146 M*/ 1147 #define PetscMacroReturns(retexpr, ...) PetscMacroReturns_(retexpr, __VA_ARGS__) 1148 1149 #define PetscMacroReturnStandard(...) PetscMacroReturns(PETSC_SUCCESS, __VA_ARGS__) 1150 1151 /*MC 1152 PETSC_STATIC_ARRAY_LENGTH - Return the length of a static array 1153 1154 Synopsis: 1155 #include <petscmacros.h> 1156 size_t PETSC_STATIC_ARRAY_LENGTH(a) 1157 1158 Input Parameter: 1159 . a - a static array of any type 1160 1161 Output Parameter: 1162 . <return-value> - the length of the array 1163 1164 Example: 1165 .vb 1166 PetscInt a[22]; 1167 size_t sa = PETSC_STATIC_ARRAY_LENGTH(a) 1168 .ve 1169 `sa` will have a value of 22 1170 1171 Level: intermediate 1172 M*/ 1173 #if PETSC_CPP_VERSION >= 14 1174 #include <cstddef> 1175 #include <type_traits> 1176 1177 template <typename T> 1178 static inline constexpr std::size_t PETSC_STATIC_ARRAY_LENGTH(const T &) noexcept 1179 { 1180 static_assert(std::is_array<T>::value, ""); 1181 return std::extent<T, std::rank<T>::value - 1>::value; 1182 } 1183 #else 1184 #define PETSC_STATIC_ARRAY_LENGTH(...) (sizeof(__VA_ARGS__) / sizeof(__VA_ARGS__)[0]) 1185 #endif 1186 1187 /* 1188 These macros allow extracting out the first argument or all but the first argument from a macro __VAR_ARGS__ INSIDE another macro. 1189 1190 Example usage: 1191 1192 #define mymacro(obj,...) { 1193 PETSC_FIRST_ARG((__VA_ARGS__,unused)); 1194 f(22 PETSC_REST_ARG(__VA_ARGS__)); 1195 } 1196 1197 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 1198 1199 Reference: 1200 https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick 1201 */ 1202 #define PETSC_FIRST_ARG_(N, ...) N 1203 #define PETSC_FIRST_ARG(args) PETSC_FIRST_ARG_ args 1204 #define PETSC_SELECT_16TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16 1205 #define PETSC_NUM(...) PETSC_SELECT_16TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) 1206 #define PETSC_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__ 1207 #define PETSC_REST_HELPER_ONE(first) 1208 #define PETSC_REST_HELPER2(qty, ...) PETSC_REST_HELPER_##qty(__VA_ARGS__) 1209 #define PETSC_REST_HELPER(qty, ...) PETSC_REST_HELPER2(qty, __VA_ARGS__) 1210 #define PETSC_REST_ARG(...) PETSC_REST_HELPER(PETSC_NUM(__VA_ARGS__), __VA_ARGS__) 1211 1212 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(name, ...) \ 1213 _Pragma(PetscStringize(name diagnostic push)) \ 1214 _Pragma(PetscStringize(name diagnostic ignored __VA_ARGS__)) 1215 1216 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(name) _Pragma(PetscStringize(name diagnostic pop)) 1217 1218 #if defined(__clang__) 1219 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(clang, __VA_ARGS__) 1220 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END() PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(clang) 1221 #elif defined(__GNUC__) || defined(__GNUG__) 1222 // gcc >= 4.6.0 1223 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600 1224 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(GCC, __VA_ARGS__) 1225 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END() PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(GCC) 1226 #endif 1227 #endif 1228 1229 #ifndef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN 1230 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) 1231 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END(...) 1232 // only undefine these if they are not used 1233 #undef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_ 1234 #undef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_ 1235 #endif 1236 1237 /* OpenMP support */ 1238 #if defined(_OPENMP) 1239 #if defined(_MSC_VER) 1240 #define PetscPragmaOMP(...) __pragma(__VA_ARGS__) 1241 #else 1242 #define PetscPragmaOMP(...) _Pragma(PetscStringize(omp __VA_ARGS__)) 1243 #endif 1244 #endif 1245 1246 #ifndef PetscPragmaOMP 1247 #define PetscPragmaOMP(...) 1248 #endif 1249 1250 /* PetscPragmaSIMD - from CeedPragmaSIMD */ 1251 #if defined(__NEC__) 1252 #define PetscPragmaSIMD _Pragma("_NEC ivdep") 1253 #elif defined(__INTEL_COMPILER) && !defined(_WIN32) 1254 #define PetscPragmaSIMD _Pragma("vector") 1255 #elif defined(__GNUC__) 1256 #if __GNUC__ >= 5 && !defined(__PGI) 1257 #define PetscPragmaSIMD _Pragma("GCC ivdep") 1258 #endif 1259 #elif defined(_OPENMP) && _OPENMP >= 201307 1260 #define PetscPragmaSIMD PetscPragmaOMP(simd) 1261 #elif defined(PETSC_HAVE_CRAY_VECTOR) 1262 #define PetscPragmaSIMD _Pragma("_CRI ivdep") 1263 #endif 1264 1265 #ifndef PetscPragmaSIMD 1266 #define PetscPragmaSIMD 1267 #endif 1268 1269 #include <petsc/private/petscadvancedmacros.h> 1270 1271 #define PetscConcat6_(a, b, c, d, e, f) a##b##c##d##e##f 1272 #define PetscConcat6(a, b, c, d, e, f) PetscConcat6_(a, b, c, d, e, f) 1273 1274 #define PETSC_DEPRECATED_IDENTIFIER_(__PETSC_DEPRECATION_MACRO__, __SILENCE_MACRO__, major, minor, subminor, replacement, ...) \ 1275 PetscIfPetscDefined(__SILENCE_MACRO__, PetscExpandToNothing, \ 1276 __PETSC_DEPRECATION_MACRO__)(PetscStringize(Use replacement (since version major.minor.subminor) instead. Silence this warning (as well as all others for this version) by defining PetscConcat_(PETSC_, __SILENCE_MACRO__). __VA_ARGS__)) 1277 1278 #define PETSC_DEPRECATED_IDENTIFIER(__PETSC_DEPRECATION_MACRO__, major, minor, subminor, ...) \ 1279 PETSC_DEPRECATED_IDENTIFIER_(__PETSC_DEPRECATION_MACRO__, PetscConcat6(SILENCE_DEPRECATION_WARNINGS_, major, _, minor, _, subminor), major, minor, subminor, __VA_ARGS__) 1280 1281 #define PETSC_DEPRECATED_OBJECT(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_OBJECT_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1282 #define PETSC_DEPRECATED_FUNCTION(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_FUNCTION_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1283 #define PETSC_DEPRECATED_TYPEDEF(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_TYPEDEF_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1284 #define PETSC_DEPRECATED_ENUM(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_ENUM_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1285 #define PETSC_DEPRECATED_MACRO(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_MACRO_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1286