HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
result.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved.
4 // Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved.
5 // Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved.
6 // Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 
26 #pragma once
27 
28 #include "hal_core/defines.h"
30 
31 #include <functional>
32 #include <type_traits>
33 #include <variant>
34 
35 namespace hal
36 {
40  namespace result_constructor_type
41  {
45  class OK
46  {
47  };
51  class ER
52  {
53  };
54  } // namespace result_constructor_type
55 
56 #define OK(...) \
57  { \
58  result_constructor_type::OK(), __VA_ARGS__ \
59  }
60 #define ERR(message) \
61  { \
62  result_constructor_type::ER(), Error(__FILE__, __LINE__, message) \
63  }
64 #define ERR_APPEND(prev_error, message) \
65  { \
66  result_constructor_type::ER(), Error(__FILE__, __LINE__, prev_error, message) \
67  }
68 
69  template<typename T>
70  class [[nodiscard]] Result final
71  {
72  public:
74  static_assert(!std::is_same<T, Error>(), "Cannot initialize a Result<Error>.");
75 
76  template<typename... Args, typename U = T, typename std::enable_if_t<std::is_same_v<U, void>, int> = 0>
78  {
79  }
80 
81  template<typename... Args, typename U = T, typename std::enable_if_t<!std::is_same_v<U, void>, int> = 0>
82  Result(result_constructor_type::OK, const T& value) : m_result(value)
83  {
84  }
85 
86  template<typename... Args, typename U = T, typename std::enable_if_t<!std::is_same_v<U, void>, int> = 0>
87  Result(result_constructor_type::OK, std::remove_reference_t<T>&& value) : m_result(std::move(value))
88  {
89  }
90 
91  Result(result_constructor_type::ER, const Error& error) : m_result(error)
92  {
93  }
94 
101  template<typename... Args, typename U = T, typename std::enable_if_t<!std::is_same_v<U, void>, int> = 0>
102  static Result<T> Ok(const T& value)
103  {
104  return OK(value);
105  }
106 
110  template<typename... Args, typename U = T, typename std::enable_if_t<!std::is_same_v<U, void>, int> = 0>
111  static Result<T> Ok(std::remove_reference_t<T>&& value)
112  {
113  return OK(std::move(value));
114  }
115 
122  bool operator==(const Result<T>& other)
123  {
124  return this->m_result == other.m_result;
125  }
126 
133  bool operator!=(const Result<T>& other)
134  {
135  return !(*this == other);
136  }
137 
143  bool is_ok() const
144  {
145  return !is_error();
146  }
147 
153  bool is_error() const
154  {
155  return std::holds_alternative<Error>(m_result);
156  }
157 
165  template<typename U = T, typename std::enable_if_t<!std::is_same_v<U, void>, int> = 0>
166  const T& get() const
167  {
168  return std::get<T>(m_result);
169  }
170 
178  template<typename U = T, typename std::enable_if_t<!std::is_same_v<U, void>, int> = 0>
179  T&& get()
180  {
181  return std::get<T>(std::move(m_result));
182  }
183 
190  const Error& get_error() const
191  {
192  return std::get<Error>(m_result);
193  }
194 
202  {
203  return std::get<Error>(std::move(m_result));
204  }
205 
213  template<typename U, typename std::enable_if_t<!std::is_same_v<U, void>, int> = 0>
214  Result<U> map(const std::function<Result<U>(const T&)>& f) const
215  {
216  if (this->is_ok())
217  {
218  return f(this->get());
219  }
220  else
221  {
222  return ERR(this->get_error());
223  }
224  }
225 
233  template<typename U, typename std::enable_if_t<!std::is_same_v<U, void>, int> = 0>
234  Result<U> map(const std::function<Result<U>(T&&)>& f)
235  {
236  if (this->is_ok())
237  {
238  return f(this->get());
239  }
240  else
241  {
242  return ERR(this->get_error());
243  }
244  }
245 
246  private:
247  std::variant<T, Error> m_result;
248  };
249 } // namespace hal
Error && get_error()
Definition: result.h:201
Result(result_constructor_type::ER, const Error &error)
Definition: result.h:91
bool operator==(const Result< T > &other)
Definition: result.h:122
Result(result_constructor_type::OK)
Definition: result.h:77
bool is_ok() const
Definition: result.h:143
const T & get() const
Definition: result.h:166
static Result< T > Ok(const T &value)
Definition: result.h:102
Result< U > map(const std::function< Result< U >(T &&)> &f)
Definition: result.h:234
const Error & get_error() const
Definition: result.h:190
Result(result_constructor_type::OK, const T &value)
Definition: result.h:82
T && get()
Definition: result.h:179
bool operator!=(const Result< T > &other)
Definition: result.h:133
Result(result_constructor_type::OK, std::remove_reference_t< T > &&value)
Definition: result.h:87
static Result< T > Ok(std::remove_reference_t< T > &&value)
Definition: result.h:111
bool is_error() const
Definition: result.h:153
Result< U > map(const std::function< Result< U >(const T &)> &f) const
Definition: result.h:214
#define ERR(message)
Definition: result.h:60
#define OK(...)
Definition: result.h:56
Definition: defines.h:45