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

optional_expr.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_OPTIONAL_EXPR_HPP
10 #define EAGINE_OPTIONAL_EXPR_HPP
11 
12 #include "assert.hpp"
13 #include "valid_if/decl.hpp"
14 
15 namespace eagine {
16 
17 template <typename Derived, typename... P>
18 struct nary_optional_expr;
19 
20 template <typename Derived, typename L, typename R>
21 struct nary_optional_expr<Derived, L, R> {
22 private:
23  L _l;
24  R _r;
25 
26  const Derived& _self() const noexcept {
27  return *static_cast<const Derived*>(this);
28  }
29 
30  template <typename T, typename P>
31  static bool _is_valid(const valid_if<T, P>& v) noexcept {
32  return v.is_valid();
33  }
34 
35  template <typename... P>
36  static bool _is_valid(const nary_optional_expr<P...>& e) noexcept {
37  return e.is_valid();
38  }
39 
40  template <typename T>
41  static bool _is_valid(const T&) noexcept {
42  return true;
43  }
44 
45  template <typename T, typename P>
46  static const T& _get(const valid_if<T, P>& v) {
47  return v.value();
48  }
49 
50  template <typename... P>
51  static auto _get(const nary_optional_expr<P...>& e) {
52  return e.value();
53  }
54 
55  template <typename T>
56  static const T& _get(const T& v) {
57  return v;
58  }
59 
60 protected:
61  auto _get_l() const {
62  return _get(_l);
63  }
64 
65  auto _get_r() const {
66  return _get(_r);
67  }
68 
69 public:
70  nary_optional_expr(L l, R r)
71  : _l(l)
72  , _r(r) {}
73 
74  bool is_valid() const noexcept {
75  return _is_valid(_l) && _is_valid(_r);
76  }
77 
78  explicit operator bool() const noexcept {
79  return is_valid();
80  }
81 
82  auto value() const {
83  EAGINE_ASSERT(is_valid());
84  return _self().evaluate();
85  }
86 
87  template <typename T>
88  auto value_or(const T& v) const {
89  return is_valid() ? _self().evaluate() : v;
90  }
91 
92  template <typename Func>
93  void then(Func func) const {
94  if(is_valid()) {
95  func(value());
96  }
97  }
98 };
99 
100 template <typename L, typename R>
101 class optional_binary_slash_expr
102  : public nary_optional_expr<optional_binary_slash_expr<L, R>, L, R> {
103 public:
104  using nary_optional_expr<optional_binary_slash_expr, L, R>::
105  nary_optional_expr;
106 
107  auto evaluate() const {
108  return this->_get_l() / this->_get_r();
109  }
110 };
111 
112 template <typename T1, typename T2, typename P2>
113 static inline optional_binary_slash_expr<T1, valid_if<T2, P2>>
114 operator/(const T1& v1, const valid_if<T2, P2>& v2) noexcept {
115  return {v1, v2};
116 }
117 
118 } // namespace eagine
119 
120 #endif // EAGINE_OPTIONAL_EXPR_HPP
Common code is placed in this namespace.
Definition: eagine.hpp:21

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