13
13
#include < string>
14
14
15
15
namespace power_grid_model {
16
- namespace detail {
17
- inline auto to_string (std::floating_point auto x) {
18
- std::ostringstream sstr{}; // NOLINT(misc-const-correctness) // https://github.com/llvm/llvm-project/issues/57297
19
- sstr << x;
20
- return sstr.str ();
21
- }
22
- inline auto to_string (std::integral auto x) { return std::to_string (x); }
23
- } // namespace detail
24
-
25
16
class PowerGridError : public std ::exception {
26
17
public:
27
- void append_msg (std::string_view msg) { msg_ = std::format (" {}{}" , msg_, msg); }
28
18
char const * what () const noexcept final { return msg_.c_str (); }
29
19
20
+ protected:
21
+ PowerGridError () = default ;
22
+ PowerGridError (std::string msg) : msg_{std::move (msg)} {}
23
+
24
+ void append_msg (std::string_view msg) { msg_ = std::format (" {} {}" , msg_, msg); }
25
+
30
26
private:
31
27
std::string msg_;
32
28
};
@@ -38,203 +34,171 @@ class InvalidArguments : public PowerGridError {
38
34
std::string value;
39
35
};
40
36
41
- template <std::same_as<TypeValuePair>... Options> InvalidArguments (std::string_view error_msg) {
42
- append_msg (error_msg);
43
- }
37
+ template <std::same_as<TypeValuePair>... Options>
38
+ InvalidArguments (std::string error_msg) : PowerGridError{std::move (error_msg)} {}
44
39
45
40
template <std::same_as<TypeValuePair>... Options>
46
- InvalidArguments (std::string_view method, std::string_view arguments) {
47
- append_msg (std::format (" {} is not implemented for {}!\n " , method, arguments));
48
- }
41
+ InvalidArguments (std::string_view method, std::string_view arguments)
42
+ : PowerGridError{std::format (" {} is not implemented for {}!\n " , method, arguments)} {}
49
43
50
44
template <class ... Options>
51
- requires (std::same_as<std::remove_cvref_t <Options>, TypeValuePair> && ...)
45
+ requires (( std::same_as<std::remove_cvref_t <Options>, TypeValuePair> && ...) && sizeof ...(Options) > 0 )
52
46
InvalidArguments (std::string_view method, Options const &... options)
53
47
: InvalidArguments{method, " the following combination of options" } {
54
- (append_msg (std::format (" {}: {}\n " , options.name , options.value )), ...);
48
+ (append_msg (std::format (" {}: {}\n " , options.name , options.value )), ...);
55
49
}
56
50
};
57
51
58
52
class MissingCaseForEnumError : public InvalidArguments {
59
53
public:
60
54
template <typename T>
61
55
MissingCaseForEnumError (std::string_view method, T const & value)
62
- : InvalidArguments{method,
63
- std::format (" {} #{}" , typeid (T).name (), detail::to_string (static_cast <IntS>(value)))} {}
56
+ : InvalidArguments{method, std::format (" {} #{:d}" , typeid (T).name (), static_cast <IntS>(value))} {}
64
57
};
65
58
66
59
class ConflictVoltage : public PowerGridError {
67
60
public:
68
- ConflictVoltage (ID id, ID id1, ID id2, double u1, double u2) {
69
- append_msg (std::format (
70
- " Conflicting voltage for line {}\n voltage at from node {} is {}\n voltage at to node {} is {}\n " ,
71
- detail::to_string (id), detail::to_string (id1), detail::to_string (u1), detail::to_string (id2),
72
- detail::to_string (u2)));
73
- }
61
+ ConflictVoltage (ID id, ID id1, ID id2, double u1, double u2)
62
+ : PowerGridError{std::format (
63
+ " Conflicting voltage for line {}\n voltage at from node {} is {}\n voltage at to node {} is {}\n " , id,
64
+ id1, u1, id2, u2)} {}
74
65
};
75
66
76
67
class InvalidBranch : public PowerGridError {
77
68
public:
78
- InvalidBranch (ID branch_id, ID node_id) {
79
- append_msg (std::format (" Branch {} has the same from- and to-node {},\n This is not allowed!\n " ,
80
- detail::to_string (branch_id), detail::to_string (node_id)));
81
- }
69
+ InvalidBranch (ID branch_id, ID node_id)
70
+ : PowerGridError{std::format (" Branch {} has the same from- and to-node {},\n This is not allowed!\n " , branch_id,
71
+ node_id)} {}
82
72
};
83
73
84
74
class InvalidBranch3 : public PowerGridError {
85
75
public:
86
- InvalidBranch3 (ID branch3_id, ID node_1_id, ID node_2_id, ID node_3_id) {
87
- append_msg (std::format (
88
- " Branch3 {} is connected to the same node at least twice. Node 1/2/3: {}/{}/{},\n This is not allowed!\n " ,
89
- detail::to_string (branch3_id), detail::to_string (node_1_id), detail::to_string (node_2_id),
90
- detail::to_string (node_3_id)));
91
- }
76
+ InvalidBranch3 (ID branch3_id, ID node_1_id, ID node_2_id, ID node_3_id)
77
+ : PowerGridError{std::format (
78
+ " Branch3 {} is connected to the same node at least twice. Node 1/2/3: {}/{}/{},\n This is not allowed!\n " ,
79
+ branch3_id, node_1_id, node_2_id, node_3_id)} {}
92
80
};
93
81
94
82
class InvalidTransformerClock : public PowerGridError {
95
83
public:
96
- InvalidTransformerClock (ID id, IntS clock) {
97
- append_msg (std::format (" Invalid clock for transformer {}, clock {}\n " , detail::to_string (id),
98
- detail::to_string (clock)));
99
- }
84
+ InvalidTransformerClock (ID id, IntS clock)
85
+ : PowerGridError{std::format (" Invalid clock for transformer {}, clock {}\n " , id, clock)} {}
100
86
};
101
87
102
88
class SparseMatrixError : public PowerGridError {
103
89
public:
104
- SparseMatrixError (Idx err, std::string_view msg = " " ) {
105
- append_msg (
106
- std::format (" Sparse matrix error with error code #{} (possibly singular)\n " , detail::to_string (err)));
107
- if (!msg.empty ()) {
108
- append_msg (std::format (" {}\n " , msg));
109
- }
110
- append_msg (" If you get this error from state estimation, " );
111
- append_msg (" it usually means the system is not fully observable, i.e. not enough measurements." );
112
- }
113
- SparseMatrixError () {
114
- append_msg (" Sparse matrix error, possibly singular matrix!\n "
115
- " If you get this error from state estimation, "
116
- " it might mean the system is not fully observable, i.e. not enough measurements.\n "
117
- " It might also mean that you are running into a corner case where PGM cannot resolve yet."
118
- " See https://github.com/PowerGridModel/power-grid-model/issues/864." );
119
- }
90
+ SparseMatrixError (Idx err, std::string_view msg = " " )
91
+ : PowerGridError{std::format (
92
+ " Sparse matrix error with error code #{} (possibly singular)\n {}If you get this error from state "
93
+ " estimation, it usually means the system is not fully observable, i.e. not enough measurements." ,
94
+ err, msg.empty () ? " " : std::format (" {}\n " , msg))} {}
95
+ SparseMatrixError ()
96
+ : PowerGridError{" Sparse matrix error, possibly singular matrix!\n "
97
+ " If you get this error from state estimation, "
98
+ " it might mean the system is not fully observable, i.e. not enough measurements.\n "
99
+ " It might also mean that you are running into a corner case where PGM cannot resolve yet."
100
+ " See https://github.com/PowerGridModel/power-grid-model/issues/864." } {}
120
101
};
121
102
122
103
class NotObservableError : public PowerGridError {
123
104
public:
124
- NotObservableError (std::string_view msg = " " ) {
125
- append_msg (" Not enough measurements available for state estimation.\n " );
126
- if (!msg.empty ()) {
127
- append_msg (std::format (" {}\n " , msg));
128
- }
129
- }
105
+ NotObservableError () : PowerGridError{" Not enough measurements available for state estimation.\n " } {}
106
+ NotObservableError (std::string_view msg)
107
+ : PowerGridError{std::format (" Not enough measurements available for state estimation.\n {}\n " , msg)} {}
130
108
};
131
109
132
110
class IterationDiverge : public PowerGridError {
133
111
public:
134
- IterationDiverge () = default ;
135
- IterationDiverge (Idx num_iter, double max_dev, double err_tol) {
136
- append_msg (
137
- std::format (" Iteration failed to converge after {} iterations! Max deviation: {}, error tolerance: {}.\n " ,
138
- detail::to_string (num_iter), detail::to_string (max_dev), detail::to_string (err_tol)));
139
- }
112
+ IterationDiverge (std::string msg) : PowerGridError{std::move (msg)} {}
113
+ IterationDiverge (Idx num_iter, double max_dev, double err_tol)
114
+ : PowerGridError{
115
+ std::format (" Iteration failed to converge after {} iterations! Max deviation: {}, error tolerance: {}.\n " ,
116
+ num_iter, max_dev, err_tol)} {}
140
117
};
141
118
142
119
class MaxIterationReached : public IterationDiverge {
143
120
public:
144
- MaxIterationReached (std::string const & msg = " " ) {
145
- append_msg (std::format (" Maximum number of iterations reached {}\n " , msg));
146
- }
121
+ MaxIterationReached (std::string_view msg = " " )
122
+ : IterationDiverge{std::format (" Maximum number of iterations reached! {}\n " , msg)} {}
147
123
};
148
124
149
125
class ConflictID : public PowerGridError {
150
126
public:
151
- explicit ConflictID (ID id) { append_msg ( std::format (" Conflicting id detected: {}\n " , detail::to_string ( id))); }
127
+ explicit ConflictID (ID id) : PowerGridError{ std::format (" Conflicting id detected: {}\n " , id)} { }
152
128
};
153
129
154
130
class IDNotFound : public PowerGridError {
155
131
public:
156
- explicit IDNotFound (ID id) { append_msg ( std::format (" The id cannot be found: {}\n " , detail::to_string ( id))); }
132
+ explicit IDNotFound (ID id) : PowerGridError{ std::format (" The id cannot be found: {}\n " , id)} { }
157
133
};
158
134
class Idx2DNotFound : public PowerGridError {
159
135
public:
160
- explicit Idx2DNotFound (Idx2D id) {
161
- append_msg (std::format (" The idx 2d cannot be found: {{{}, {}}}.\n " , detail::to_string (id.group ),
162
- detail::to_string (id.pos )));
163
- }
136
+ explicit Idx2DNotFound (Idx2D id)
137
+ : PowerGridError{std::format (" The idx 2d cannot be found: {{{}, {}}}.\n " , id.group , id.pos )} {}
164
138
};
165
139
166
140
class InvalidMeasuredObject : public PowerGridError {
167
141
public:
168
- InvalidMeasuredObject (std::string_view object, std::string_view sensor) {
169
- append_msg (std::format (" {} measurement is not supported for object of type {}" , sensor, object));
170
- }
142
+ InvalidMeasuredObject (std::string_view object, std::string_view sensor)
143
+ : PowerGridError{std::format (" {} measurement is not supported for object of type {}" , sensor, object)} {}
171
144
};
172
145
173
146
class InvalidMeasuredTerminalType : public PowerGridError {
174
147
public:
175
- InvalidMeasuredTerminalType (MeasuredTerminalType const terminal_type, std::string_view sensor) {
176
- append_msg (std::format (" {} measurement is not supported for object of type {}" , sensor,
177
- detail::to_string (static_cast <IntS>(terminal_type))));
178
- }
148
+ InvalidMeasuredTerminalType (MeasuredTerminalType const terminal_type, std::string_view sensor)
149
+ : PowerGridError{std::format (" {} measurement is not supported for object of type {}" , sensor,
150
+ static_cast <IntS>(terminal_type))} {}
179
151
};
180
152
181
153
class InvalidRegulatedObject : public PowerGridError {
182
154
public:
183
- InvalidRegulatedObject (std::string_view object, std::string_view regulator) {
184
- append_msg (std::format (" {} regulator is not supported for object of type {}" , regulator, object));
185
- }
186
- InvalidRegulatedObject (ID id, std::string_view regulator) {
187
- append_msg (
188
- std::format (" {} regulator is not supported for object with ID {}" , regulator, detail::to_string (id)));
189
- }
155
+ InvalidRegulatedObject (std::string_view object, std::string_view regulator)
156
+ : PowerGridError{std::format (" {} regulator is not supported for object of type {}" , regulator, object)} {}
157
+ InvalidRegulatedObject (ID id, std::string_view regulator)
158
+ : PowerGridError{std::format (" {} regulator is not supported for object with ID {}" , regulator, id)} {}
190
159
};
191
160
192
161
class DuplicativelyRegulatedObject : public PowerGridError {
193
162
public:
194
- DuplicativelyRegulatedObject () {
195
- append_msg (" There are objects regulated by more than one regulator. Maximum one regulator is allowed." );
196
- }
163
+ DuplicativelyRegulatedObject ()
164
+ : PowerGridError{" There are objects regulated by more than one regulator. Maximum one regulator is allowed." } {}
197
165
};
198
166
199
167
class AutomaticTapCalculationError : public PowerGridError {
200
168
public:
201
- AutomaticTapCalculationError (ID id) {
202
- append_msg (
203
- std::format (" Automatic tap changing regulator with tap_side at LV side is not supported. Found at id {}" ,
204
- detail::to_string (id)));
205
- }
169
+ AutomaticTapCalculationError (ID id)
170
+ : PowerGridError{std::format (
171
+ " Automatic tap changing regulator with tap_side at LV side is not supported. Found at id {}" , id)} {}
206
172
};
207
173
208
174
class AutomaticTapInputError : public PowerGridError {
209
175
public:
210
- AutomaticTapInputError (std::string_view msg) {
211
- append_msg (std::format (" Automatic tap changer has invalid configuration. {}" , msg));
212
- }
176
+ AutomaticTapInputError (std::string_view msg)
177
+ : PowerGridError{std::format (" Automatic tap changer has invalid configuration. {}" , msg)} {}
213
178
};
214
179
215
180
class IDWrongType : public PowerGridError {
216
181
public:
217
- explicit IDWrongType (ID id) {
218
- append_msg (std::format (" Wrong type for object with id {}\n " , detail::to_string (id)));
219
- }
182
+ explicit IDWrongType (ID id) : PowerGridError{std::format (" Wrong type for object with id {}\n " , id)} {}
220
183
};
221
184
222
185
class ConflictingAngleMeasurementType : public PowerGridError {
223
186
public:
224
- ConflictingAngleMeasurementType (std::string_view msg) {
225
- append_msg (std::format (" Conflicting angle measurement type. {}" , msg));
226
- }
187
+ ConflictingAngleMeasurementType (std::string_view msg)
188
+ : PowerGridError{std::format (" Conflicting angle measurement type. {}" , msg)} {}
227
189
};
228
190
229
191
class CalculationError : public PowerGridError {
230
192
public:
231
- explicit CalculationError (std::string_view msg) { append_msg (msg); }
193
+ explicit CalculationError (std::string msg) : PowerGridError{ std::move (msg)} { }
232
194
};
233
195
234
196
class BatchCalculationError : public CalculationError {
235
197
public:
236
- BatchCalculationError (std::string_view msg, IdxVector failed_scenarios, std::vector<std::string> err_msgs)
237
- : CalculationError(msg), failed_scenarios_{std::move (failed_scenarios)}, err_msgs_(std::move(err_msgs)) {}
198
+ BatchCalculationError (std::string msg, IdxVector failed_scenarios, std::vector<std::string> err_msgs)
199
+ : CalculationError{std::move (msg)},
200
+ failed_scenarios_{std::move (failed_scenarios)},
201
+ err_msgs_ (std::move(err_msgs)) {}
238
202
239
203
IdxVector const & failed_scenarios () const { return failed_scenarios_; }
240
204
@@ -247,46 +211,40 @@ class BatchCalculationError : public CalculationError {
247
211
248
212
class InvalidCalculationMethod : public CalculationError {
249
213
public:
250
- InvalidCalculationMethod () : CalculationError( " The calculation method is invalid for this calculation!" ) {}
214
+ InvalidCalculationMethod () : CalculationError{ " The calculation method is invalid for this calculation!" } {}
251
215
};
252
216
253
217
class InvalidShortCircuitType : public PowerGridError {
254
218
public:
255
- explicit InvalidShortCircuitType (FaultType short_circuit_type) {
256
- append_msg (std::format (" The short circuit type ({}) is invalid!\n " ,
257
- detail::to_string (static_cast <IntS>(short_circuit_type))));
258
- }
259
- InvalidShortCircuitType (bool sym, FaultType short_circuit_type) {
260
- append_msg (std::format (" The short circuit type ({}) does not match the calculation type (symmetric={})\n " ,
261
- detail::to_string (static_cast <IntS>(short_circuit_type)),
262
- detail::to_string (static_cast <int >(sym))));
263
- }
219
+ explicit InvalidShortCircuitType (FaultType short_circuit_type)
220
+ : PowerGridError{
221
+ std::format (" The short circuit type ({}) is invalid!\n " , static_cast <IntS>(short_circuit_type))} {}
222
+ InvalidShortCircuitType (bool sym, FaultType short_circuit_type)
223
+ : PowerGridError{std::format (" The short circuit type ({}) does not match the calculation type (symmetric={})\n " ,
224
+ static_cast <IntS>(short_circuit_type), static_cast <int >(sym))} {}
264
225
};
265
226
266
227
class InvalidShortCircuitPhases : public PowerGridError {
267
228
public:
268
- InvalidShortCircuitPhases (FaultType short_circuit_type, FaultPhase short_circuit_phases) {
269
- append_msg (std::format (" The short circuit phases ({}) do not match the short circuit type ({})\n " ,
270
- detail::to_string (static_cast <IntS>(short_circuit_phases)),
271
- detail::to_string (static_cast <IntS>(short_circuit_type))));
272
- }
229
+ InvalidShortCircuitPhases (FaultType short_circuit_type, FaultPhase short_circuit_phases)
230
+ : PowerGridError{std::format (" The short circuit phases ({}) do not match the short circuit type ({})\n " ,
231
+ static_cast <IntS>(short_circuit_phases), static_cast <IntS>(short_circuit_type))} {}
273
232
};
274
233
275
234
class InvalidShortCircuitPhaseOrType : public PowerGridError {
276
235
public:
277
- InvalidShortCircuitPhaseOrType () {
278
- append_msg (" During one calculation the short circuit types phases should be similar for all faults\n " );
279
- }
236
+ InvalidShortCircuitPhaseOrType ()
237
+ : PowerGridError{" During one calculation the short circuit types phases should be similar for all faults\n " } {}
280
238
};
281
239
282
240
class SerializationError : public PowerGridError {
283
241
public:
284
- explicit SerializationError (std::string_view msg) { append_msg (msg); }
242
+ explicit SerializationError (std::string msg) : PowerGridError{ std::move (msg)} { }
285
243
};
286
244
287
245
class DatasetError : public PowerGridError {
288
246
public:
289
- explicit DatasetError (std::string_view msg) { append_msg ( std::format (" Dataset error: {}" , msg)); }
247
+ explicit DatasetError (std::string_view msg) : PowerGridError{ std::format (" Dataset error: {}" , msg)} { }
290
248
};
291
249
292
250
class ExperimentalFeature : public InvalidArguments {
@@ -295,25 +253,24 @@ class ExperimentalFeature : public InvalidArguments {
295
253
296
254
class NotImplementedError : public PowerGridError {
297
255
public:
298
- NotImplementedError () { append_msg ( " Function not yet implemented" ); }
256
+ NotImplementedError () : PowerGridError{ " Function not yet implemented" } { }
299
257
};
300
258
301
259
class UnreachableHit : public PowerGridError {
302
260
public:
303
- UnreachableHit (std::string_view method, std::string_view reason_for_assumption) {
304
- append_msg ( std::format ( " Unreachable code hit when executing {}. \n The following assumption for unreachability "
305
- " was not met: {}.\n This may be a bug in the library \n " ,
306
- method, reason_for_assumption));
307
- }
261
+ UnreachableHit (std::string_view method, std::string_view reason_for_assumption)
262
+ : PowerGridError{
263
+ std::format ( " Unreachable code hit when executing {}.\n The following assumption for unreachability "
264
+ " was not met: {}. \n This may be a bug in the library \n " ,
265
+ method, reason_for_assumption)} { }
308
266
};
309
267
310
268
class TapSearchStrategyIncompatibleError : public InvalidArguments {
311
269
public:
312
270
template <typename T1, typename T2>
313
271
TapSearchStrategyIncompatibleError (std::string_view method, T1 const & value1, T2 const & value2)
314
- : InvalidArguments{method, std::format (" {} #{} and {} #{}" , typeid (T1).name (),
315
- detail::to_string (static_cast <IntS>(value1)), typeid (T2).name (),
316
- detail::to_string (static_cast <IntS>(value2)))} {}
272
+ : InvalidArguments{method, std::format (" {} #{} and {} #{}" , typeid (T1).name (), static_cast <IntS>(value1),
273
+ typeid (T2).name (), static_cast <IntS>(value2))} {}
317
274
};
318
275
319
276
} // namespace power_grid_model
0 commit comments