OGLplus  (0.59.0) a C++ wrapper for rendering APIs

extract.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_EXTRACT_HPP
10 #define EAGINE_EXTRACT_HPP
11 
12 #include "assert.hpp"
13 #include "nothing.hpp"
14 #include <memory>
15 #include <type_traits>
16 
17 namespace eagine {
18 //------------------------------------------------------------------------------
21 template <typename T>
22 static constexpr auto extract(T* ptr) noexcept -> T& {
23  return EAGINE_CONSTEXPR_ASSERT(bool(ptr), *ptr);
24 }
25 //------------------------------------------------------------------------------
27 template <typename T>
28 static constexpr auto
29 extract_or(T* ptr, std::remove_const_t<T>& fallback) noexcept -> T& {
30  return bool(ptr) ? *ptr : fallback;
31 }
32 //------------------------------------------------------------------------------
34 template <typename T, typename F>
35 static constexpr auto extract_or(T* ptr, F&& fallback)
36  -> std::enable_if_t<std::is_convertible_v<F, T>, T> {
37  return bool(ptr) ? *ptr : T{std::forward<F>(fallback)};
38 }
39 //------------------------------------------------------------------------------
42 template <typename T>
43 static constexpr auto extract(std::shared_ptr<T>& ptr) noexcept -> T& {
44  return EAGINE_CONSTEXPR_ASSERT(bool(ptr), *ptr);
45 }
46 //------------------------------------------------------------------------------
49 template <typename T>
50 static constexpr auto extract(const std::shared_ptr<T>& ptr) noexcept
51  -> const T& {
52  return EAGINE_CONSTEXPR_ASSERT(bool(ptr), *ptr);
53 }
54 //------------------------------------------------------------------------------
56 template <typename T>
57 static constexpr auto
58 extract_or(std::shared_ptr<T>& ptr, std::remove_const_t<T>& fallback) noexcept
59  -> T& {
60  return bool(ptr) ? *ptr : fallback;
61 }
62 //------------------------------------------------------------------------------
64 template <typename T, typename F>
65 static constexpr auto extract_or(std::shared_ptr<T>& ptr, F&& fallback)
66  -> std::enable_if_t<std::is_convertible_v<F, T>, T> {
67  return bool(ptr) ? *ptr : T{std::forward<F>(fallback)};
68 }
69 //------------------------------------------------------------------------------
72 template <typename T, typename D>
73 static constexpr auto extract(std::unique_ptr<T, D>& ptr) noexcept -> T& {
74  return EAGINE_CONSTEXPR_ASSERT(bool(ptr), *ptr);
75 }
76 //------------------------------------------------------------------------------
79 template <typename T, typename D>
80 static constexpr auto extract(const std::unique_ptr<T, D>& ptr) noexcept
81  -> const T& {
82  return EAGINE_CONSTEXPR_ASSERT(bool(ptr), *ptr);
83 }
84 //------------------------------------------------------------------------------
86 template <typename T, typename D>
87 static constexpr auto extract_or(
88  std::unique_ptr<T, D>& ptr,
89  std::remove_const_t<T>& fallback) noexcept -> T& {
90  return bool(ptr) ? *ptr : fallback;
91 }
92 //------------------------------------------------------------------------------
94 template <typename T, typename D, typename F>
95 static constexpr auto extract_or(std::unique_ptr<T, D>& ptr, F&& fallback)
96  -> std::enable_if_t<std::is_convertible_v<F, T>, T> {
97  return bool(ptr) ? *ptr : T{std::forward<F>(fallback)};
98 }
99 //------------------------------------------------------------------------------
102 template <typename Outcome>
103 struct ok_traits {
105  static constexpr auto nok_info(const Outcome&) noexcept -> nothing_t {
106  return {};
107  }
108 };
109 //------------------------------------------------------------------------------
127 template <typename Outcome>
128 class ok {
129 private:
130  Outcome _outcome{};
131 
132  using _traits = ok_traits<Outcome>;
133 
134 public:
136  constexpr ok(Outcome&& outcome) noexcept(noexcept(std::declval<Outcome&&>()))
137  : _outcome{std::move(outcome)} {}
138 
140  explicit constexpr
141  operator bool() noexcept(noexcept(bool(std::declval<Outcome&>()))) {
142  return bool(_outcome);
143  }
144 
146  explicit constexpr operator bool() const
147  noexcept(noexcept(bool(std::declval<const Outcome&>()))) {
148  return bool(_outcome);
149  }
150 
153  constexpr auto get() noexcept(noexcept(extract(_outcome)))
154  -> decltype(extract(_outcome)) {
155  return extract(_outcome);
156  }
157 
160  constexpr auto get() const noexcept(noexcept(extract(_outcome)))
161  -> decltype(extract(_outcome)) {
162  return extract(_outcome);
163  }
164 
167  constexpr operator decltype(extract(std::declval<Outcome&>()))() noexcept(
168  noexcept(extract(_outcome))) {
169  return extract(_outcome);
170  }
171 
174  constexpr operator decltype(extract(std::declval<const Outcome&>()))() const
175  noexcept(noexcept(extract(_outcome))) {
176  return extract(_outcome);
177  }
178 
179  constexpr auto nok() const noexcept
180  -> decltype(_traits::nok_info(_outcome)) {
181  return _traits::nok_info(_outcome);
182  }
183 
184  constexpr auto operator!() const noexcept
185  -> decltype(_traits::nok_info(_outcome)) {
186  return _traits::nok_info(_outcome);
187  }
188 };
189 //------------------------------------------------------------------------------
192 template <typename Outcome>
193 auto extract(const ok<Outcome>& x) noexcept -> const auto& {
194  return x.get();
195 }
196 //------------------------------------------------------------------------------
199 template <typename Outcome>
200 auto begin(
201  const ok<Outcome>& x,
202  decltype(std::declval<const ok<Outcome>&>().get().begin())* = nullptr) {
203  return x.get().begin();
204 }
205 //------------------------------------------------------------------------------
208 template <typename Outcome>
209 auto end(
210  const ok<Outcome>& x,
211  decltype(std::declval<const ok<Outcome>&>().get().end())* = nullptr) {
212  return x.get().end();
213 }
214 //------------------------------------------------------------------------------
215 } // namespace eagine
216 
217 #endif // EAGINE_EXTRACT_HPP
constexpr ok(Outcome &&outcome) noexcept(noexcept(std::declval< Outcome && >()))
Construction from a function call outcome object.
Definition: extract.hpp:136
static constexpr auto extract_or(T *ptr, std::remove_const_t< T > &fallback) noexcept -> T &
Checks ptr and dereferences it if not null, otherwise returns fallback.
Definition: extract.hpp:29
Common code is placed in this namespace.
Definition: eagine.hpp:21
constexpr auto get() noexcept(noexcept(extract(_outcome))) -> decltype(extract(_outcome))
Extracts the stored outcome value.
Definition: extract.hpp:153
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
Class representing "none" / "nothing" values.
Definition: nothing.hpp:17
auto end(const ok< Outcome > &x, decltype(std::declval< const ok< Outcome > & >().get().end()) *=nullptr)
Overload of begin for instantiations of the ok template.
Definition: extract.hpp:209
auto begin(const ok< Outcome > &x, decltype(std::declval< const ok< Outcome > & >().get().begin()) *=nullptr)
Overload of begin for instantiations of the ok template.
Definition: extract.hpp:200
static constexpr auto nok_info(const Outcome &) noexcept -> nothing_t
Returns additional info type for values that are not-OK.
Definition: extract.hpp:105
Traits used for customization of class ok for the specified Outcome.
Definition: extract.hpp:103
Value typically wrapping function call result and success indicator.
Definition: extract.hpp:128
constexpr auto get() const noexcept(noexcept(extract(_outcome))) -> decltype(extract(_outcome))
Extracts the stored outcome value.
Definition: extract.hpp:160
auto extract(const ok< Outcome > &x) noexcept -> const auto &
Overload of extract for instantiations of the ok template.
Definition: extract.hpp:193

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).