-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathExceptions.h
146 lines (130 loc) · 5.99 KB
/
Exceptions.h
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// ---------------------------------------------------------------------
//
// Copyright (c) 2017-2025 The Regents of the University of Michigan and DFT-FE
// authors.
//
// This file is part of the DFT-FE code.
//
// The DFT-FE code is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the DFT-FE distribution.
//
// ---------------------------------------------------------------------
/*
* @author Bikash Kanungo
*/
#ifndef dftfeExceptions_h
#define dftfeExceptions_h
#include <string>
#include <stdexcept>
/**
@brief provides an interface for exception handling.
It two overrides on the assert(expr) function in C/C++ and two wrappers on
std::exception.
The overrides on assert(expr) are useful for debug mode testing. That is,
you want the assert to be executed *only in debug mode* and not in release
mode (i.e., if NDEBUG is defined). The two assert overrides are
1. DFTFE_Assert(expr): same as std::assert(expr). Throws an assert
if expr is false
2. DFTFE_AssertWithMsg(expr,msg): same as above but takes an
additional message in the form of string to display if expr is false.
It also provides two preprocessor flags, DFTFE_DISABLE_ASSERT and
DFTFE_ENABLE_ASSERT, that you can set to override the NDEBUG flag in a
particular source file. This is provided to allow selective enabling or
disabling of Assert and AssertWithMsg without any relation to whether NDEBUG
is defined or not (NDEBUG is typically defined globally for all files
through compiler options).
For example, if in a file you have
#define DFTFE_DISABLE_ASSERT
#include "Exceptions.h"
then it would disable all calls to Assert or AssertWithMsg in that file,
regardless of whether NDEBUG is defined. Also, it has no bearing on
std::assert (i.e., any calls to std::assert in that file will still be
governed by NDEBUG). Similarly, if in a file you have
#define
DFTFE_ENABLE_ASSERT
#include "Exceptions.h"
then it would enable all calls to Assert or AssertWithMsg in that file,
regardless of whether NDEBUG is defined.
Also, it has no bearning on std::assert (i.e., any calls
to std::assert in that file will still be governed by NDEBUG)
It also provides two wrappers on std::exception and its derived classes
(e.g., std::runtime_error, std::domain_error, etc.) The two wrappers are:
1. dftfe::utils::throwException(expr,msg): a generic exception handler
which throws an optional message (msg) if expr evaluates to false. It
combines std::exception with an additional messgae. (Note: the
std::exception has no easy way of taking in a message).
2. dftfe::utils::throwException<T>(expr, msg): similar to the above, but
takes a specific derived class of std::exception handler as a template
parameter. The derived std::exception must have a constructor that takes in
a string. For the ease of the user, we have typedef-ed some commonly used
derived classes of std::exception. A user can use the typedefs as the
template parameter instead. Available typedefs LogicError - std::logic_error
InvalidArgument - std::invalid_argument
DomainError - std::domain_error
LengthError - std::length_error
OutOfRangeError - std::out_of_range
FutureError - std::future_error
RuntimeError - std::runtime_error
OverflowError - std::overflow_error
UnderflowError - std::underflow_error
*/
#undef DFTFE_Assert
#undef DFTFE_AssertWithMsg
#if defined(DFTFE_DISABLE_ASSERT) || \
(!defined(DFTFE_ENABLE_ASSERT) && defined(NDEBUG))
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
# define DFTFE_Assert(expr) ((void)0)
# define DFTFE_AssertWithMsg(expr, msg) ((void)0)
#elif defined(DFTFE_ENABLE_ASSERT) && defined(NDEBUG)
# undef NDEBUG // disabling NDEBUG to forcibly enable assert for sources that
// set DFTFE_ENABLE_ASSERT even when in release mode (with
// NDEBUG)
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
# define DFTFE_Assert(expr) assert(expr)
# define DFTFE_AssertWithMsg(expr, msg) assert((expr) && (msg))
#else
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
# define DFTFE_Assert(expr) assert(expr)
# define DFTFE_AssertWithMsg(expr, msg) assert((expr) && (msg))
#endif
#ifdef DFTFE_WITH_DEVICE_LANG_CUDA
# include <DeviceExceptions.cu.h>
#elif DFTFE_WITH_DEVICE_LANG_HIP
# include <DeviceExceptions.hip.h>
#endif
#define MPICHECK(cmd) \
do \
{ \
int e = cmd; \
if (e != MPI_SUCCESS) \
{ \
printf("Failed: MPI error %s:%d '%d'\n", __FILE__, __LINE__, e); \
exit(EXIT_FAILURE); \
} \
} \
while (0)
namespace dftfe
{
namespace utils
{
typedef std::logic_error LogicError;
typedef std::invalid_argument InvalidArgument;
typedef std::domain_error DomainError;
typedef std::length_error LengthError;
typedef std::out_of_range OutOfRangeError;
typedef std::runtime_error RuntimeError;
typedef std::overflow_error OverflowError;
typedef std::underflow_error UnderflowError;
void
throwException(bool condition, std::string msg = "");
template <class T>
void
throwException(bool condition, std::string msg = "");
} // namespace utils
} // namespace dftfe
#include "Exceptions.t.cc"
#endif // dftfeExceptions_h