RCFProto

- Main Page
- Classes
- Files

- File List

All Classes Functions Typedefs
Assert.hpp
1
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18
19 #ifndef INCLUDE_UTIL_ASSERT_HPP
20 #define INCLUDE_UTIL_ASSERT_HPP
21
22 #include <cassert>
23 #include <exception>
24 #include <iostream>
25
26 #include <boost/current_function.hpp>
27
28 #include "Throw.hpp"
29 #include "VariableArgMacro.hpp"
30
31 #if defined(_MSC_VER) && !defined(NDEBUG)
32 #include <crtdbg.h>
33 #endif
34
35 namespace util {
36
37 class AssertFunctor : public VariableArgMacroFunctor
38 {
39 public:
40
41 AssertFunctor() : mExpr(NULL)
42 {
43 }
44
45 AssertFunctor(const char * expr) : mExpr(expr)
46 {
47 }
48
49 #if defined(_MSC_VER) && !defined(NDEBUG)
50 #pragma warning(push)
51 #pragma warning(disable: 4995) // 'sprintf': name was marked as #pragma deprecated
52 #pragma warning(disable: 4996) // 'sprintf': This function or variable may be unsafe.
53
54 ~AssertFunctor()
55 {
56 const char * msg =
57 "%s\n"
58 "Values: %s\n"
59 "Function: %s";
60
61 std::string values(mArgs->str(), static_cast<std::size_t>(mArgs->tellp()));
62
63 char szBuffer[512] = {0};
64 sprintf(szBuffer, "%s(%d): Assert failed. Expression: %s.\n", mFile, mLine, mExpr);
65 OutputDebugStringA(szBuffer);
66 std::cout << szBuffer;
67 int ret = _CrtDbgReport(_CRT_ASSERT, mFile, mLine, "", msg, mExpr, values.c_str(), mFunc);
68 if (ret == 1)
69 {
70 // __debugbreak() is more likely to give a proper call stack.
71 //DebugBreak();
72 __debugbreak();
73 }
74 }
75
76 #pragma warning(pop)
77 #else
78
79 ~AssertFunctor()
80 {
81 std::string values(mArgs->str(), static_cast<std::size_t>(mArgs->tellp()));
82
83 std::cout
84 << mFile << ":" << mLine
85 << ": Assertion failed. " << mExpr
86 << " . Values: " << values << std::endl;
87
88 assert(0 && "See line above for assertion details.");
89 }
90
91 #endif
92
93 const char * mExpr;
94 };
95
96 class VarArgAbort
97 {
98 public:
99 VarArgAbort()
100 {
101 abort();
102 }
103
104 template<typename T>
105 VarArgAbort &operator()(const T &)
106 {
107 return *this;
108 }
109 };
110
111
112 #if 0
113 #define UTIL_ASSERT_DEBUG(cond, e, logName, logLevel) \
114 if (cond) ; \
115 else util::VarArgAssert(__FILE__, __LINE__, #cond)
116 #endif
117
118 #ifdef _MSC_VER
119 #pragma warning( push )
120 #pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list
121 #endif
122
123 #if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
124 #define UTIL_ASSERT_DEBUG_GCC_33_HACK (const util::VariableArgMacro<util::ThrowFunctor> &)
125 #else
126 #define UTIL_ASSERT_DEBUG_GCC_33_HACK
127 #endif
128
129 DECLARE_VARIABLE_ARG_MACRO( UTIL_ASSERT_DEBUG, util::AssertFunctor );
130 #define UTIL_ASSERT_DEBUG(expr, e, logName, logLevel) \
131 if (expr); \
132 else\
133 UTIL_ASSERT_DEBUG_GCC_33_HACK \
134 util::VariableArgMacro<util::AssertFunctor>(#expr) \
135 .init( \
136 "", \
137 "", \
138 __FILE__, \
139 __LINE__, \
140 BOOST_CURRENT_FUNCTION) \
141 .cast( (util::VariableArgMacro<util::AssertFunctor> *) NULL) \
142 .UTIL_ASSERT_DEBUG_A
143
144
145
146 #define UTIL_ASSERT_DEBUG_A(x) UTIL_ASSERT_DEBUG_OP(x, B)
147 #define UTIL_ASSERT_DEBUG_B(x) UTIL_ASSERT_DEBUG_OP(x, A)
148 #define UTIL_ASSERT_DEBUG_OP(x, next) UTIL_ASSERT_DEBUG_A.notify_((x), #x).UTIL_ASSERT_DEBUG_ ## next
149
150 #ifdef _MSC_VER
151 #pragma warning( pop )
152 #endif
153
154
155
156
157 #ifdef RCF_ALWAYS_ABORT_ON_ASSERT
158
159 #define UTIL_ASSERT_RELEASE(cond, e, logName, logLevel) \
160 if (cond) ; \
161 else util::VarArgAbort()
162
163 #else
164
165 #define UTIL_ASSERT_RELEASE(cond, e, logName, logLevel) \
166 if (cond) ; \
167 else UTIL_THROW(e, logName, logLevel)(cond)
168
169 #endif
170
171 #define UTIL_ASSERT_NULL(cond, E) \
172 DUMMY_VARIABLE_ARG_MACRO()
173
174 #ifdef NDEBUG
175 #define UTIL_ASSERT UTIL_ASSERT_RELEASE
176 #else
177 #define UTIL_ASSERT UTIL_ASSERT_DEBUG
178 #endif
179
180 } // namespace util
181
182 #endif