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

smart_callable.hpp
Go to the documentation of this file.
1 #ifndef EAGINE_SMART_CALLABLE_HPP
9 #define EAGINE_SMART_CALLABLE_HPP
10 
11 #include "args_within_limits.hpp"
12 #include "assert.hpp"
13 #include "valid_if/decl.hpp"
14 
15 namespace eagine {
16 //------------------------------------------------------------------------------
17 template <bool Asserting, typename Callable>
18 class smart_callable;
19 //------------------------------------------------------------------------------
20 template <bool Asserting, typename RV, typename... Params>
21 class smart_callable_base;
22 //------------------------------------------------------------------------------
23 template <typename RV, typename... Params>
24 class smart_callable_base<false, RV, Params...> {
25 protected:
26  template <typename Callable, typename... Args>
27  static constexpr auto _invoke(Callable& callable, Args&&... args) {
28 #ifdef __clang__
29  EAGINE_DIAG_PUSH()
30  EAGINE_DIAG_OFF(conversion)
31  EAGINE_DIAG_OFF(sign-conversion)
32 #endif
33  using ORV = optionally_valid<RV>;
34  return args_within_limits_of<Params...>(args...)
35  ? ORV{callable(std::forward<Args>(args)...)}
36  : ORV{};
37 #ifdef __clang__
38  EAGINE_DIAG_POP()
39 #endif
40  }
41 };
42 //------------------------------------------------------------------------------
43 template <typename RV, typename... Params>
44 class smart_callable_base<true, RV, Params...> {
45 protected:
46  template <typename Callable, typename... Args>
47  static constexpr auto _invoke(Callable& callable, Args&&... args) {
48 #ifdef __clang__
49  EAGINE_DIAG_PUSH()
50  EAGINE_DIAG_OFF(conversion)
51  EAGINE_DIAG_OFF(sign-conversion)
52 #endif
53  EAGINE_ASSERT(args_within_limits_of<Params...>(args...));
54  return callable(std::forward<Args>(args)...);
55 #ifdef __clang__
56  EAGINE_DIAG_POP()
57 #endif
58  }
59 };
60 //------------------------------------------------------------------------------
61 template <bool Asseting, typename RV, typename... Params>
62 class smart_callable<Asseting, RV (*)(Params...)>
63  : public smart_callable_base<Asseting, RV, Params...> {
64 public:
65  constexpr smart_callable(RV (*function)(Params...)) noexcept
66  : _function{function} {}
67 
68  template <typename... Args>
69  constexpr auto operator()(Args&&... args) const {
70  this->_invoke(_function, std::forward<Args>(args)...);
71  }
72 
73 private:
74  RV (*_function)(Params...) = nullptr;
75 };
76 //------------------------------------------------------------------------------
77 template <typename RV, typename... Params>
78 static constexpr smart_callable<false, RV (*)(Params...)>
79 smart_call(RV (*function)(Params...)) noexcept {
80  return {function};
81 }
82 //------------------------------------------------------------------------------
83 template <typename RV, typename... Params>
84 static constexpr smart_callable<true, RV (*)(Params...)>
85 safe_call(RV (*function)(Params...)) noexcept {
86  return {function};
87 }
88 //------------------------------------------------------------------------------
89 } // namespace eagine
90 
91 #endif // EAGINE_SMART_CALLABLE_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).