-
Notifications
You must be signed in to change notification settings - Fork 1
/
error_or.h
134 lines (103 loc) · 3.5 KB
/
error_or.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
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// A class that holds an error or the return value after running a function.
#ifndef ARDUINO_ERROR_ERROR_OR_H
#define ARDUINO_ERROR_ERROR_OR_H
#include <stdlib.h>
#ifdef NATIVE_BUILD
#include <ostream>
#include "error.h"
#include "gmock/gmock.h"
#else // NATIVE_BUILD
#include <Error.h>
#endif // NATIVE_BUILD
namespace error {
// An object that exclusively holds either an error code, or the return value.
template <typename T> class ErrorOr {
public:
// Creates an ErrorOr instance that will hold the provided error and no value.
// If the provided Error holds canonical Error::OK, it will be changed to
// Error::UNKNOWN to keep the guarantee that this objects holds either an
// error or a value.
ErrorOr(Error error);
ErrorOr(Error::Code error_code);
// Creates an ErrorOr instance with the canonical error code Error::UNKNOWN.
ErrorOr();
// Creates an ErrorOr instance with the provided value.
// When created using this constructor, calls to Ok() will return true and
// calls to GetError() will return an error with the canonical code Error::OK.
// Calls to ValueOrDie() will return the value.
ErrorOr(T value);
~ErrorOr();
// Determines if the operation succeeded, in which case this object holds the
// promised return value.
bool Ok() const;
// Returns the error stored in this object.
const Error &GetError() const;
// Returns the value or dies if called when the object contains an error.
const T &ValueOrDie() const;
T &ValueOrDie();
private:
Error error_;
T value_;
};
//
// Implementation details of the ErrorOr class.
//
template <typename T> inline ErrorOr<T>::ErrorOr(Error error) : error_(error) {
if (error_.Ok()) {
error_ = Error(Error::UNKNOWN);
}
}
template <typename T> inline ErrorOr<T>::ErrorOr() : ErrorOr(Error::UNKNOWN) {}
template <typename T>
inline ErrorOr<T>::ErrorOr(Error::Code error_code)
: ErrorOr(Error(error_code)) {}
template <typename T>
inline ErrorOr<T>::ErrorOr(T value) : error_(Error(Error::OK)), value_(value) {}
template <typename T> inline ErrorOr<T>::~ErrorOr() {}
template <typename T> inline bool ErrorOr<T>::Ok() const { return error_.Ok(); }
template <typename T> inline const Error &ErrorOr<T>::GetError() const {
return error_;
}
template <typename T> inline const T &ErrorOr<T>::ValueOrDie() const {
if (!Ok()) {
abort();
}
return value_;
}
template <typename T> inline T &ErrorOr<T>::ValueOrDie() {
if (!Ok()) {
abort();
}
return value_;
}
#ifdef NATIVE_BUILD
// Prints a human readable representation of ErrorOr for use in tests.
template <typename T>
void PrintTo(const ErrorOr<T> &error_or, ::std::ostream *os) {
*os << "ErrorOr<T>(";
if (error_or.Ok()) {
*os << "with value " << testing::PrintToString(error_or.ValueOrDie())
<< ")";
} else {
*os << "with error " << testing::PrintToString(error_or.GetError());
*os << ")";
}
}
#endif
} // namespace
#endif // ARDUINO_ERROR_ERROR_OR_H