Apache Mesos
check.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_CHECK_HPP__
14 #define __STOUT_CHECK_HPP__
15 
16 #include <ostream>
17 #include <sstream>
18 #include <string>
19 
20 #include <glog/logging.h>
21 
22 #include <stout/abort.hpp>
23 #include <stout/error.hpp>
24 #include <stout/none.hpp>
25 #include <stout/option.hpp>
26 #include <stout/some.hpp>
27 
28 
29 template <typename T>
30 class Result;
31 
32 template <typename T, typename E>
33 class Try;
34 
35 
36 // A generic macro to facilitate definitions of CHECK_*, akin to CHECK.
37 // This appends the error if possible to the end of the log message,
38 // so there's no need to append the error message explicitly.
39 // To define a new CHECK_*, provide the name, the function that performs the
40 // check, and the expression. See below for examples (e.g. CHECK_SOME).
41 #define CHECK_STATE(name, check, expression) \
42  for (const Option<Error> _error = check(expression); _error.isSome();) \
43  _CheckFatal(__FILE__, \
44  __LINE__, \
45  #name, \
46  #expression, \
47  _error.get()).stream()
48 
49 
50 #define CHECK_SOME(expression) \
51  CHECK_STATE(CHECK_SOME, _check_some, expression)
52 
53 
54 #define CHECK_NONE(expression) \
55  CHECK_STATE(CHECK_NONE, _check_none, expression)
56 
57 
58 #define CHECK_ERROR(expression) \
59  CHECK_STATE(CHECK_ERROR, _check_error, expression)
60 
61 
62 // A private helper for CHECK_NOTNONE which is similar to the
63 // CHECK_NOTNULL provided by glog.
64 template <typename T>
66  const char* file,
67  int line,
68  const char* message,
69  Option<T>&& t) {
70  if (t.isNone()) {
71  google::LogMessageFatal(file, line, new std::string(message));
72  }
73  return std::move(t).get();
74 }
75 
76 
77 template <typename T>
79  const char* file,
80  int line,
81  const char* message,
82  Option<T>& t) {
83  if (t.isNone()) {
84  google::LogMessageFatal(file, line, new std::string(message));
85  }
86  return t.get();
87 }
88 
89 
90 template <typename T>
91 const T& _check_not_none(
92  const char* file,
93  int line,
94  const char* message,
95  const Option<T>& t) {
96  if (t.isNone()) {
97  google::LogMessageFatal(file, line, new std::string(message));
98  }
99  return t.get();
100 }
101 
102 
103 #define CHECK_NOTNONE(expression) \
104  _check_not_none( \
105  __FILE__, \
106  __LINE__, \
107  "'" #expression "' Must be SOME", \
108  (expression))
109 
110 
111 // A private helper for CHECK_NOTERROR which is similar to the
112 // CHECK_NOTNULL provided by glog.
113 template <typename T, typename E>
115  const char* file,
116  int line,
117  const char* message,
118  Try<T, E>&& t) {
119  if (t.isError()) {
120  google::LogMessageFatal(
121  file,
122  line,
123  new std::string(
124  std::string(message) + ": " + Error(t.error()).message));
125  }
126  return std::move(t).get();
127 }
128 
129 
130 template <typename T, typename E>
132  const char* file,
133  int line,
134  const char* message,
135  Try<T, E>& t) {
136  if (t.isError()) {
137  google::LogMessageFatal(
138  file,
139  line,
140  new std::string(
141  std::string(message) + ": " + Error(t.error()).message));
142  }
143  return t.get();
144 }
145 
146 
147 template <typename T, typename E>
149  const char* file,
150  int line,
151  const char* message,
152  const Try<T, E>& t) {
153  if (t.isError()) {
154  google::LogMessageFatal(
155  file,
156  line,
157  new std::string(
158  std::string(message) + ": " + Error(t.error()).message));
159  }
160  return t.get();
161 }
162 
163 
164 #define CHECK_NOTERROR(expression) \
165  _check_not_error( \
166  __FILE__, \
167  __LINE__, \
168  "'" #expression "' Must be SOME", \
169  (expression))
170 
171 
172 // Private structs/functions used for CHECK_*.
173 
174 template <typename T>
176 {
177  if (o.isNone()) {
178  return Error("is NONE");
179  } else {
180  CHECK(o.isSome());
181  return None();
182  }
183 }
184 
185 
186 template <typename T, typename E>
188 {
189  if (t.isError()) {
190  return Error(t.error());
191  } else {
192  CHECK(t.isSome());
193  return None();
194  }
195 }
196 
197 
198 template <typename T>
200 {
201  if (r.isError()) {
202  return Error(r.error());
203  } else if (r.isNone()) {
204  return Error("is NONE");
205  } else {
206  CHECK(r.isSome());
207  return None();
208  }
209 }
210 
211 
212 template <typename T>
214 {
215  if (o.isSome()) {
216  return Error("is SOME");
217  } else {
218  CHECK(o.isNone());
219  return None();
220  }
221 }
222 
223 
224 template <typename T>
226 {
227  if (r.isError()) {
228  return Error("is ERROR");
229  } else if (r.isSome()) {
230  return Error("is SOME");
231  } else {
232  CHECK(r.isNone());
233  return None();
234  }
235 }
236 
237 
238 template <typename T, typename E>
240 {
241  if (t.isSome()) {
242  return Error("is SOME");
243  } else {
244  CHECK(t.isError());
245  return None();
246  }
247 }
248 
249 
250 template <typename T>
252 {
253  if (r.isNone()) {
254  return Error("is NONE");
255  } else if (r.isSome()) {
256  return Error("is SOME");
257  } else {
258  CHECK(r.isError());
259  return None();
260  }
261 }
262 
263 
265 {
266  _CheckFatal(const char* _file,
267  int _line,
268  const char* type,
269  const char* expression,
270  const Error& error)
271  : file(_file),
272  line(_line)
273  {
274  out << type << "(" << expression << "): " << error.message << " ";
275  }
276 
278  {
279  google::LogMessageFatal(file.c_str(), line).stream() << out.str();
280  }
281 
282  std::ostream& stream()
283  {
284  return out;
285  }
286 
287  const std::string file;
288  const int line;
289  std::ostringstream out;
290 };
291 
292 #endif // __STOUT_CHECK_HPP__
std::ostream & stream()
Definition: check.hpp:282
bool isNone() const
Definition: result.hpp:112
Option< Error > _check_some(const Option< T > &o)
Definition: check.hpp:175
Definition: errorbase.hpp:35
Definition: option.hpp:28
T & get()&
Definition: try.hpp:73
const int line
Definition: check.hpp:288
Definition: check.hpp:33
const std::string file
Definition: check.hpp:287
static Result< T > error(const std::string &message)
Definition: result.hpp:53
~_CheckFatal()
Definition: check.hpp:277
Definition: check.hpp:30
bool isSome() const
Definition: option.hpp:115
URI file(const std::string &path)
Creates a file URI with the given path on the local host.
Definition: file.hpp:33
Definition: check.hpp:264
_CheckFatal(const char *_file, int _line, const char *type, const char *expression, const Error &error)
Definition: check.hpp:266
Option< Error > _check_none(const Option< T > &o)
Definition: check.hpp:213
bool isSome() const
Definition: try.hpp:70
const T & get() const &
Definition: option.hpp:118
static Try error(const E &e)
Definition: try.hpp:42
const std::string message
Definition: errorbase.hpp:45
Definition: none.hpp:27
bool isError() const
Definition: try.hpp:71
std::string error(const std::string &msg, uint32_t code)
Try< uint32_t > type(const std::string &path)
bool isNone() const
Definition: option.hpp:116
bool isSome() const
Definition: result.hpp:111
bool isError() const
Definition: result.hpp:113
Option< Error > _check_error(const Try< T, E > &t)
Definition: check.hpp:239
std::ostringstream out
Definition: check.hpp:289
T && _check_not_none(const char *file, int line, const char *message, Option< T > &&t)
Definition: check.hpp:65
T && _check_not_error(const char *file, int line, const char *message, Try< T, E > &&t)
Definition: check.hpp:114