iceoryx_doc  1.0.1
expected.hpp
1 // Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved.
2 // Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // SPDX-License-Identifier: Apache-2.0
17 #ifndef IOX_UTILS_CXX_EXPECTED_HPP
18 #define IOX_UTILS_CXX_EXPECTED_HPP
19 
20 #include "iceoryx_utils/cxx/attributes.hpp"
21 #include "iceoryx_utils/cxx/function_ref.hpp"
22 #include "iceoryx_utils/cxx/optional.hpp"
23 #include "iceoryx_utils/cxx/variant.hpp"
24 
25 #include <utility>
26 
27 namespace iox
28 {
29 namespace cxx
30 {
31 namespace internal
32 {
35 template <typename, typename = void>
36 struct HasInvalidStateMember;
37 
39 template <typename...>
40 struct IsOptional;
41 } // namespace internal
42 
45 template <typename T>
47 {
49  "T must have an INVALID_STATE value/member. Alternatively write an ErrorTypeAdapter specialisation "
50  "for your type");
51 
52  static T getInvalidState() noexcept;
53 };
54 
63 template <typename T = void>
64 struct success
65 {
69  success(const T& t) noexcept;
70 
74  success(T&& t) noexcept;
75  template <typename... Targs>
76 
81  success(Targs&&... args) noexcept;
82 
83  T value;
84 };
85 
93 template <>
94 struct success<void>
95 {
96 };
97 
106 template <typename T>
107 struct error
108 {
112  error(const T& t) noexcept;
113 
117  error(T&& t) noexcept;
118 
123  template <typename... Targs>
124  error(Targs&&... args) noexcept;
125 
126  T value;
127 };
128 
129 template <typename... T>
130 class IOX_NO_DISCARD expected;
131 
161 template <typename ErrorType>
162 class IOX_NO_DISCARD expected<ErrorType>
163 {
164  public:
167  expected() = delete;
168 
171  expected(const expected&) noexcept = default;
172 
175  expected(expected&& rhs) noexcept;
176 
177 #if defined(_WIN32)
180  template <typename ValueType>
181  expected(const expected<ValueType, ErrorType>& rhs) noexcept;
182 
185  template <typename ValueType>
186  expected(expected<ValueType, ErrorType>&& rhs) noexcept;
187 #endif
190  ~expected() = default;
191 
194  expected& operator=(const expected&);
195 
198  expected& operator=(expected&& rhs) noexcept;
199 
200 #if defined(_WIN32)
203  template <typename ValueType>
204  expected& operator=(const expected<ValueType, ErrorType>& rhs) noexcept;
205 
208  template <typename ValueType>
209  expected& operator=(expected<ValueType, ErrorType>&& rhs) noexcept;
210 #endif
211 
214  expected(const success<void>& successValue) noexcept;
215 
219  expected(const error<ErrorType>& errorValue) noexcept;
220 
224  expected(error<ErrorType>&& errorValue) noexcept;
225 
228  static expected create_value() noexcept;
229 
234  template <typename... Targs>
235  static expected create_error(Targs&&... args) noexcept;
236 
239  explicit operator bool() const noexcept;
240 
243  bool has_error() const noexcept;
244 
248  ErrorType& get_error() & noexcept;
249 
253  const ErrorType& get_error() const& noexcept;
254 
258  ErrorType&& get_error() && noexcept;
259 
269  const expected& or_else(const cxx::function_ref<void(ErrorType&)>& callable) const noexcept;
270 
280  expected& or_else(const cxx::function_ref<void(ErrorType&)>& callable) noexcept;
281 
291  const expected& and_then(const cxx::function_ref<void()>& callable) const noexcept;
292 
302  expected& and_then(const cxx::function_ref<void()>& callable) noexcept;
303 
304  private:
305  expected(variant<ErrorType>&& store, const bool hasError) noexcept;
306  variant<ErrorType> m_store;
307  bool m_hasError;
308  static constexpr uint64_t ERROR_INDEX = 0U;
309 };
310 
314 template <typename ValueType, typename ErrorType>
315 class IOX_NO_DISCARD expected<ValueType, ErrorType>
316 {
317  public:
320  expected() = delete;
321 
324  expected(const expected&) = default;
325 
328  expected(expected&& rhs) noexcept;
329 
332  ~expected() noexcept = default;
333 
336  expected& operator=(const expected&) noexcept;
337 
340  expected& operator=(expected&& rhs) noexcept;
341 
345  expected(const success<ValueType>& successValue) noexcept;
346 
350  expected(success<ValueType>&& successValue) noexcept;
351 
355  expected(const error<ErrorType>& errorValue) noexcept;
356 
360  expected(error<ErrorType>&& errorValue) noexcept;
361 
366  template <typename... Targs>
367  static expected create_value(Targs&&... args) noexcept;
368 
373  template <typename... Targs>
374  static expected create_error(Targs&&... args) noexcept;
375 
378  explicit operator bool() const noexcept;
379 
382  bool has_error() const noexcept;
383 
387  ErrorType& get_error() & noexcept;
388 
392  const ErrorType& get_error() const& noexcept;
393 
397  ErrorType&& get_error() && noexcept;
398 
402  ValueType& value() & noexcept;
403 
407  const ValueType& value() const& noexcept;
408 
412  ValueType&& value() && noexcept;
413 
417  ValueType value_or(const ValueType& value) const noexcept;
418 
422  ValueType value_or(const ValueType& value) noexcept;
423 
424 
434  ValueType& operator*() noexcept;
435 
445  const ValueType& operator*() const noexcept;
446 
454  ValueType* operator->() noexcept;
455 
463  const ValueType* operator->() const noexcept;
464 
476  template <typename T>
477  operator expected<T>() noexcept;
478 
490  template <typename T>
491  operator expected<T>() const noexcept;
492 
502  const expected& or_else(const cxx::function_ref<void(ErrorType&)>& callable) const noexcept;
503 
513  expected& or_else(const cxx::function_ref<void(ErrorType&)>& callable) noexcept;
514 
524  const expected& and_then(const cxx::function_ref<void(ValueType&)>& callable) const noexcept;
525 
535  expected& and_then(const cxx::function_ref<void(ValueType&)>& callable) noexcept;
536 
548  template <typename Optional = ValueType,
549  typename std::enable_if<internal::IsOptional<Optional>::value, int>::type = 0>
550  const expected& and_then(const cxx::function_ref<void(typename Optional::type&)>& callable) const noexcept;
551 
563  template <typename Optional = ValueType,
564  typename std::enable_if<internal::IsOptional<Optional>::value, int>::type = 0>
565  expected& and_then(const cxx::function_ref<void(typename Optional::type&)>& callable) noexcept;
566 
580  template <typename Optional = ValueType,
581  typename std::enable_if<internal::IsOptional<Optional>::value, int>::type = 0>
582  [[deprecated]] const expected& if_empty(const cxx::function_ref<void()>& callable) const noexcept;
583 
597  template <typename Optional = ValueType,
598  typename std::enable_if<internal::IsOptional<Optional>::value, int>::type = 0>
599  [[deprecated]] expected& if_empty(const cxx::function_ref<void()>& callable) noexcept;
600 
601  optional<ValueType> to_optional() const noexcept;
602 
603  private:
604  expected(variant<ValueType, ErrorType>&& f_store, const bool hasError) noexcept;
605  variant<ValueType, ErrorType> m_store;
606  bool m_hasError;
607  static constexpr uint64_t VALUE_INDEX = 0U;
608  static constexpr uint64_t ERROR_INDEX = 1U;
609 };
610 
611 template <typename ErrorType>
612 class IOX_NO_DISCARD expected<void, ErrorType> : public expected<ErrorType>
613 {
614  public:
616 };
617 
618 
619 } // namespace cxx
620 } // namespace iox
621 
622 #include "iceoryx_utils/internal/cxx/expected.inl"
623 
624 #endif // IOX_UTILS_CXX_EXPECTED_HPP
expected(const expected &) noexcept=default
the copy constructor calls the copy constructor of the contained success value or the error value - d...
~expected()=default
calls the destructor of the success value or error value - depending on what is stored in the expecte...
expected & operator=(expected &&rhs) noexcept
calls the move assignment operator of the contained success value or the error value - depending on w...
expected(expected &&rhs) noexcept
the move constructor calls the move constructor of the contained success value or the error value - d...
expected & operator=(const expected &)
calls the copy assignment operator of the contained success value or the error value - depending on w...
expected()=delete
default ctor is deleted since you have to clearly state if the expected contains a success value or a...
specialization of the expected class which can contain an error as well as a success value
Definition: expected.hpp:316
expected(expected &&rhs) noexcept
the move constructor calls the move constructor of the contained success value or the error value - d...
expected(const expected &)=default
the copy constructor calls the copy constructor of the contained success value or the error value - d...
~expected() noexcept=default
calls the destructor of the success value or error value - depending on what is stored in the expecte...
expected()=delete
default ctor is deleted since you have to clearly state if the expected contains a success value or a...
Definition: function_ref.hpp:32
Optional implementation from the C++17 standard with C++11. The interface is analog to the C++17 stan...
Definition: optional.hpp:63
Variant implementation from the C++17 standard with C++11. The interface is inspired by the C++17 sta...
Definition: variant.hpp:105
building block to easily create free function for logging in a library context
Definition: lockfree_queue.hpp:28
Generic adapter to access INVALID_STATE member or value.
Definition: expected.hpp:47
helper struct to create an expected which is signalling an error more easily
Definition: expected.hpp:108
error(const T &t) noexcept
constructor which creates a error helper class by copying the value of t
Definition: expected.inl:71
Type trait which verifies whether the passed type T has INVALID_STATE std::true_type overload chosen ...
Definition: expected.inl:30
helper struct to create an error only expected which is signalling success more easily
Definition: expected.hpp:95
helper struct to create an expected which is signalling success more easily
Definition: expected.hpp:65