1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
/**
** \file misc/contract.hh
** \brief Replacement for cassert.
**/
#pragma once
// Use GCC magic bits to specify we cannot return from these functions
#ifndef __attribute__
# if !defined __GNUC__
# define __attribute__(Spec) /* empty */
# endif
#endif
[[noreturn]] void __Terminate(const char*, int, const char*);
#define die(Reason) __Terminate(__FILE__, __LINE__, Reason)
#define unreachable() die("unreachable code reached")
#ifdef NDEBUG
// This a trick use to disable assertion and co in the project. We need a stream
// in a 'else' to keep the code syntactically correct. However we do not want
// to print anything. So the 'if' is always true and does nothing.
// 'std::cerr' << "" is here to avoid warnings.
# define __TestCondition \
if (true) \
{ \
; \
} \
else \
std::cerr << ""
# define assertion(Expr) __TestCondition
# define invariant(Expr) __TestCondition
# define precondition(Expr) __TestCondition
# define postcondition(Expr) __TestCondition
#else // NDEBUG
# define __TestCondition(CondType, Expr) \
if (Expr) \
{ \
; \
} \
else \
Contract(#CondType, #Expr, __FILE__, __LINE__)
# define assertion(Expr) __TestCondition(Assertion, Expr)
# define invariant(Expr) __TestCondition(Invariant, Expr)
# define precondition(Expr) __TestCondition(Precondition, Expr)
# define postcondition(Expr) __TestCondition(Postcondition, Expr)
#endif // ! NDEBUG
class Contract
{
public:
Contract(const char* condType,
const char* condText,
const char* fileName,
int fileLine);
[[noreturn]] ~Contract();
const char* condType;
const char* condText;
const char* fileName;
int fileLine;
};
#include <misc/contract.hxx>
|