LCOV - code coverage report
Current view: top level - src/Utility - PAssert.h (source / functions) Coverage Total Hit
Test: report.info Lines: 0.0 % 10 0
Test Date: 2025-05-21 10:57:37 Functions: 0.0 % 7 0
Branches: 0.0 % 64 0

             Branch data     Line data    Source code
       1                 :             : /***************************************************************************
       2                 :             :  *
       3                 :             :  * The IPPL Framework
       4                 :             :  *
       5                 :             :  ***************************************************************************/
       6                 :             : 
       7                 :             : #ifndef PASSERT_H
       8                 :             : #define PASSERT_H
       9                 :             : #include <exception>
      10                 :             : #include <stdexcept>
      11                 :             : #include <string>
      12                 :             : 
      13                 :             : #include "Utility/IpplInfo.h"
      14                 :             : //////////////////////////////////////////////////////////////////////
      15                 :             : //
      16                 :             : // This is a compile time assert.
      17                 :             : // That is, if you say:
      18                 :             : //   CTAssert<true>::test();
      19                 :             : // it compiles just fine and inserts no code.
      20                 :             : // If you say:
      21                 :             : //   CTAssert<false>::test();
      22                 :             : // you get a compile error that it can't find CTAssert<false>::test().
      23                 :             : //
      24                 :             : // The template argument can of course be a calculation of const bools
      25                 :             : // that are known at compile time.
      26                 :             : //
      27                 :             : //////////////////////////////////////////////////////////////////////
      28                 :             : 
      29                 :             : template <bool B>
      30                 :             : struct IpplCTAssert {};
      31                 :             : 
      32                 :             : template <>
      33                 :             : struct IpplCTAssert<true> {
      34                 :             :     static void test() {}
      35                 :             : };
      36                 :             : 
      37                 :             : #if defined(NOCTAssert)
      38                 :             : #define CTAssert(c)
      39                 :             : #else
      40                 :             : #define CTAssert(c) IpplCTAssert<(c)>::test()
      41                 :             : #endif
      42                 :             : 
      43                 :             : //===========================================================================//
      44                 :             : // class assertion - exception notification class for assertions
      45                 :             : 
      46                 :             : // This class should really be derived from std::runtime_error, but
      47                 :             : // unfortunately we don't have good implementation of the library standard
      48                 :             : // yet, on compilers other than KCC.  So, this class will keep with the
      49                 :             : // "what" method evidenced in the standard, but dispense with inheriting from
      50                 :             : // classes for which we don't have implementations...
      51                 :             : //===========================================================================//
      52                 :             : 
      53                 :             : class assertion : public std::runtime_error {
      54                 :             :     char* msg;
      55                 :             : 
      56                 :             : public:
      57                 :             :     assertion(const char* cond, const char* file, int line);
      58                 :             : 
      59                 :             :     assertion(const char* m);
      60                 :             : 
      61                 :             :     assertion(const assertion& a);
      62                 :             : 
      63         [ #  # ]:           0 :     ~assertion() throw() { delete[] msg; }
      64                 :             : 
      65                 :             :     assertion& operator=(const assertion& a);
      66                 :             : 
      67                 :             :     using std::runtime_error::what;
      68                 :             : 
      69                 :           0 :     virtual const char* what() { return msg; };
      70                 :             : };
      71                 :             : 
      72                 :             : //---------------------------------------------------------------------------//
      73                 :             : // Now we define a run time assertion mechanism.  We will call it "PAssert",
      74                 :             : // to reflect the idea that this is for use in IPPL per se, recognizing that
      75                 :             : // there are numerous other assertion facilities in use in client codes.
      76                 :             : //---------------------------------------------------------------------------//
      77                 :             : 
      78                 :             : // These are the functions that will be called in the assert macros.
      79                 :             : void toss_cookies(const char* cond, const char* file, int line);
      80                 :             : template <class S, class T>
      81                 :           0 : void toss_cookies(const char* cond, const char* astr, const char* bstr, S a, T b, const char* file,
      82                 :             :                   int line) {
      83   [ #  #  #  #  :           0 :     std::string what = "Assertion '" + std::string(cond) + "' failed. \n";
                   #  # ]
      84   [ #  #  #  #  :           0 :     what += std::string(astr) + " = " + std::to_string(a) + ", ";
          #  #  #  #  #  
           # ][ #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      85   [ #  #  #  #  :           0 :     what += std::string(bstr) + " = " + std::to_string(b) + "\n";
          #  #  #  #  #  
           # ][ #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      86         [ #  # ]:           0 :     what += "in \n";
      87   [ #  #  #  #  :           0 :     what += std::string(file) + ", line  " + std::to_string(line);
             #  #  #  # ]
      88                 :             : 
      89         [ #  # ]:           0 :     throw std::runtime_error(what);
      90                 :           0 : }
      91                 :             : void insist(const char* cond, const char* msg, const char* file, int line);
      92                 :             : 
      93                 :             : //---------------------------------------------------------------------------//
      94                 :             : // The PAssert macro is intended to be used for validating preconditions
      95                 :             : // which must be true in order for following code to be correct, etc.  For
      96                 :             : // example, PAssert( x > 0. ); y = sqrt(x);  If the assertion fails, the code
      97                 :             : // should just bomb.  Philosophically, it should be used to feret out bugs in
      98                 :             : // preceding code, making sure that prior results are within reasonable
      99                 :             : // bounds before proceeding to use those results in further computation, etc.
     100                 :             : //---------------------------------------------------------------------------//
     101                 :             : 
     102                 :             : #ifdef NOPAssert
     103                 :             : #define PAssert(c)
     104                 :             : #define PAssert_EQ(a, b)
     105                 :             : #define PAssert_NE(a, b)
     106                 :             : #define PAssert_LT(a, b)
     107                 :             : #define PAssert_LE(a, b)
     108                 :             : #define PAssert_GT(a, b)
     109                 :             : #define PAssert_GE(a, b)
     110                 :             : #else
     111                 :             : #ifdef __HIP_PLATFORM_AMD__      // toss_cookies are not supported so just do a no-operation
     112                 :             : #define PAssert(c)
     113                 :             : #define PAssert_CMP(cmp, a, b)
     114                 :             : #else
     115                 :             : #define PAssert(c) \
     116                 :             :     if (!(c))      \
     117                 :             :         toss_cookies(#c, __FILE__, __LINE__);
     118                 :             : #define PAssert_CMP(cmp, a, b) \
     119                 :             :     if (!(cmp))                \
     120                 :             :         toss_cookies(#cmp, #a, #b, a, b, __FILE__, __LINE__);
     121                 :             : #endif
     122                 :             : #define PAssert_EQ(a, b) PAssert_CMP(a == b, a, b)
     123                 :             : #define PAssert_NE(a, b) PAssert_CMP(a != b, a, b)
     124                 :             : #define PAssert_LT(a, b) PAssert_CMP(a < b, a, b)
     125                 :             : #define PAssert_LE(a, b) PAssert_CMP(a <= b, a, b)
     126                 :             : #define PAssert_GT(a, b) PAssert_CMP(a > b, a, b)
     127                 :             : #define PAssert_GE(a, b) PAssert_CMP(a >= b, a, b)
     128                 :             : #endif
     129                 :             : 
     130                 :             : //---------------------------------------------------------------------------//
     131                 :             : // The PInsist macro is akin to the PAssert macro, but it provides the
     132                 :             : // opportunity to specify an instructive message.  The idea here is that you
     133                 :             : // should use Insist for checking things which are more or less under user
     134                 :             : // control.  If the user makes a poor choice, we "insist" that it be
     135                 :             : // corrected, providing a corrective hint.
     136                 :             : //---------------------------------------------------------------------------//
     137                 :             : 
     138                 :             : #define PInsist(c, m) \
     139                 :             :     if (!(c))         \
     140                 :             :         insist(#c, m, __FILE__, __LINE__);
     141                 :             : 
     142                 :             : //---------------------------------------------------------------------------//
     143                 :             : // NOTE:  We provide a way to eliminate assertions, but not insistings.  The
     144                 :             : // idea is that PAssert is used to perform sanity checks during program
     145                 :             : // development, which you might want to eliminate during production runs for
     146                 :             : // performance sake.  PInsist is used for things which really really must be
     147                 :             : // true, such as "the file must've been opened", etc.  So, use PAssert for
     148                 :             : // things which you want taken out of production codes (like, the check might
     149                 :             : // inhibit inlining or something like that), but use PInsist for those things
     150                 :             : // you want checked even in a production code.
     151                 :             : //---------------------------------------------------------------------------//
     152                 :             : 
     153                 :             : #endif  // PASSERT_H
     154                 :             : 
     155                 :             : // vi: set et ts=4 sw=4 sts=4:
     156                 :             : // Local Variables:
     157                 :             : // mode:c
     158                 :             : // c-basic-offset: 4
     159                 :             : // indent-tabs-mode: nil
     160                 :             : // require-final-newline: nil
     161                 :             : // End:
        

Generated by: LCOV version 2.0-1