Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2001-03-20 |
2 | // Created by: Andrey BETENEV | |
973c2be1 | 3 | // Copyright (c) 2001-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
11 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
91a16bc7 K |
15 | |
16 | #ifndef Standard_Assert_HeaderFile | |
17 | #define Standard_Assert_HeaderFile | |
18 | ||
19 | #include <Standard_ProgramError.hxx> | |
20 | ||
21 | //!@file | |
22 | //! This header file defines a set of ASSERT macros intended for use | |
23 | //! in algorithms for debugging purposes and as a tool to organise | |
24 | //! checks for abnormal situations in the uniform way. | |
25 | //! | |
26 | //! In contrast to C assert() function that terminates the process, these | |
27 | //! macros provide choice of the action to be performed if assert failed, | |
28 | //! thus allowing execution to continue when possible. | |
29 | //! Except for the message for developer that appears only in Debug mode, | |
30 | //! the macros behave in the same way in both Release and Debug modes. | |
31 | //! | |
32 | //! | |
33 | //! The ASSERT macros differ in the way they react on a wrong situation: | |
34 | //! - Standard_ASSERT_RAISE: raises exception Standard_ProgramError | |
35 | //! - Standard_ASSERT_RETURN: returns specified value (last argument may | |
36 | //! be left empty to return void) | |
37 | //! - Standard_ASSERT_SKIP: does nothing | |
38 | //! - Standard_ASSERT_VOID: does nothing; even does not evaluate first arg | |
39 | //! when in Release mode | |
40 | //! - Standard_ASSERT_INVOKE: causes unconditional assert | |
41 | //! - Standard_ASSERT: base macro (used by other macros); | |
42 | //! does operation indicated in argument "todo" | |
43 | //! | |
44 | //! The assertion is assumed to fail if the first argument is | |
45 | //! evaluated to zero (false). | |
46 | //! The first argument is evaluated by all macros except Standard_ASSERT_VOID | |
47 | //! which does not evaluate first argument when in Release mode. | |
0797d9d3 | 48 | //! The mode is triggered by preprocessor macro _DEBUG: if it is defined, |
91a16bc7 K |
49 | //! Debug mode is assumed, Release otherwise. |
50 | //! | |
51 | //! In debug mode, if condition is not satisfied the macros call | |
52 | //! Standard_ASSERT_INVOKE_ which: | |
53 | //! - on Windows (under VC++), stops code execution and prompts to attach | |
54 | //! debugger to the process immediately. | |
55 | //! - on POSIX systems, prints message to cerr and raises signal SIGTRAP to stop | |
56 | //! execution when under debugger (may terminate the process if not under debugger). | |
57 | //! | |
58 | //! The second argument (message) should be string constant ("..."). | |
59 | //! | |
8b381bc3 | 60 | //! The Standard_STATIC_ASSERT macro is to be used for compile time checks. |
61 | //! To use this macro, write: | |
62 | //! | |
63 | //! Standard_STATIC_ASSERT(const_expression); | |
64 | //! | |
65 | //! If const_expression is false, a compiler error occurs. | |
66 | //! | |
91a16bc7 K |
67 | //! The macros are formed as functions and require semicolon at the end. |
68 | ||
69 | // Stub function used to make macros complete C++ operator | |
70 | inline void Standard_ASSERT_DO_NOTHING() {} | |
71 | ||
72 | // User messages are activated in debug mode only | |
0797d9d3 | 73 | #ifdef _DEBUG |
91a16bc7 | 74 | #if (defined(_WIN32) || defined(__WIN32__)) |
7c65581d | 75 | #if defined(_MSC_VER) || defined(__MINGW64__) |
91a16bc7 K |
76 | // VS-specific intrinsic |
77 | #define Standard_ASSERT_DBGBREAK_() __debugbreak() | |
78 | #else | |
79 | // WinAPI function | |
80 | #include <windows.h> | |
81 | #define Standard_ASSERT_DBGBREAK_() DebugBreak() | |
82 | #endif | |
83 | #else | |
84 | // POSIX systems | |
85 | #include <signal.h> | |
86 | #define Standard_ASSERT_DBGBREAK_() raise(SIGTRAP) | |
87 | #endif | |
88 | ||
0797d9d3 | 89 | #if defined(_MSC_VER) |
91a16bc7 K |
90 | #include <crtdbg.h> |
91 | // use debug CRT built-in function that show up message box to user | |
92 | // with formatted assert description and 3 possible actions | |
93 | inline Standard_Boolean Standard_ASSERT_REPORT_ (const char* theFile, | |
94 | const int theLine, | |
95 | const char* theExpr, | |
96 | const char* theDesc) | |
97 | { | |
98 | // 1 means user pressed Retry button | |
99 | return _CrtDbgReport (_CRT_ASSERT, theFile, theLine, NULL, | |
100 | "%s\n(Condition: \"%s\")\n", theDesc, theExpr) == 1; | |
101 | } | |
102 | #else | |
103 | // just log assertion description into standard error stream | |
104 | inline Standard_Boolean Standard_ASSERT_REPORT_ (const char* theFile, | |
105 | const int theLine, | |
106 | const char* theExpr, | |
107 | const char* theDesc) | |
108 | { | |
109 | std::cerr << "ERROR: statement '" << theExpr << "' is not TRUE!\n" | |
110 | << "\nFile: '" << theFile << "'" | |
111 | << "\nLine: " << theLine << "\n"; | |
112 | if (theDesc != NULL && *theDesc != '\0') | |
113 | std::cerr << "Description: " << theDesc << "\n"; | |
114 | ||
115 | std::cerr << std::flush; | |
116 | return Standard_True; | |
117 | } | |
118 | #endif | |
119 | ||
120 | // report issue and add debug breakpoint or abort execution | |
121 | #define Standard_ASSERT_INVOKE_(theExpr, theDesc) \ | |
122 | if (Standard_ASSERT_REPORT_ (__FILE__, __LINE__, #theExpr, theDesc)) { Standard_ASSERT_DBGBREAK_(); } \ | |
123 | else Standard_ASSERT_DO_NOTHING() | |
124 | ||
125 | // Basic ASSERT macros | |
126 | #define Standard_ASSERT(theExpr, theDesc, theAction) \ | |
127 | if (!(theExpr)) { Standard_ASSERT_INVOKE_(theExpr, theDesc); theAction; } \ | |
128 | else Standard_ASSERT_DO_NOTHING() | |
129 | #define Standard_ASSERT_SKIP(theExpr, theDesc) \ | |
130 | Standard_ASSERT(theExpr, theDesc,) | |
131 | #define Standard_ASSERT_VOID(theExpr, theDesc) \ | |
132 | Standard_ASSERT(theExpr, theDesc,) | |
133 | #else | |
134 | ||
135 | // dummy block | |
136 | #define Standard_ASSERT_INVOKE_(theExpr, theDesc) Standard_ASSERT_DO_NOTHING() | |
137 | ||
138 | // Basic ASSERT macros | |
139 | #define Standard_ASSERT(theExpr, theDesc, theAction) \ | |
140 | if (!(theExpr)) { theAction; } \ | |
141 | else Standard_ASSERT_DO_NOTHING() | |
142 | #define Standard_ASSERT_SKIP(theExpr, theDesc) theExpr | |
143 | #define Standard_ASSERT_VOID(theExpr, theDesc) Standard_ASSERT_DO_NOTHING() | |
144 | ||
145 | #endif | |
146 | ||
147 | //! Raise exception (Standard_ProgramError) with the provided message | |
148 | #define Standard_ASSERT_RAISE(theExpr, theDesc) \ | |
9775fa61 | 149 | Standard_ASSERT(theExpr, theDesc, throw Standard_ProgramError( \ |
91a16bc7 K |
150 | "*** ERROR: ASSERT in file '" __FILE__ "': \n" theDesc " (" #theExpr ")" ) ) |
151 | ||
152 | //! Return from the current function with specified value (empty | |
153 | //! if the function returns void) | |
154 | #define Standard_ASSERT_RETURN(theExpr, theDesc, theReturnValue) \ | |
155 | Standard_ASSERT(theExpr, theDesc, return theReturnValue) | |
156 | ||
157 | //! Raise debug message | |
158 | #define Standard_ASSERT_INVOKE(theDesc) Standard_ASSERT_INVOKE_(always, theDesc) | |
159 | ||
8b381bc3 | 160 | //! Static assert -- |
161 | //! empty default template | |
162 | template <bool condition> | |
163 | struct Standard_Static_Assert { }; | |
164 | ||
165 | //! Static assert -- specialization for condition being true | |
166 | template <> | |
167 | struct Standard_Static_Assert<true> | |
168 | { | |
169 | static void assert_ok() {} | |
170 | }; | |
171 | ||
172 | //! Cause compiler error if argument is not constant expression or | |
173 | //! evaluates to false | |
174 | #define Standard_STATIC_ASSERT(theExpr) \ | |
175 | Standard_Static_Assert<theExpr>::assert_ok(); | |
176 | ||
91a16bc7 K |
177 | #endif // Standard_Assert_HeaderFile |
178 | ||
179 | #ifdef _MSC_VER | |
180 | #pragma once | |
181 | #endif |