0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / Standard / Standard_Assert.hxx
CommitLineData
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
70inline 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
162template <bool condition>
163struct Standard_Static_Assert { };
164
165//! Static assert -- specialization for condition being true
166template <>
167struct 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