HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
functional.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../utility/utility.hpp"
8#include "../macros.hpp"
9#include <type_traits>
10#include <future>
11
12hi_export_module(hikogui.container.functional);
13
14
15hi_export namespace hi::inline v1 {
16
17template<typename Proto>
19
20template<typename Result, typename... Arguments>
21class function<Result(Arguments...)> {
22public:
23 using result_type = Result;
24
25 virtual ~function() = default;
26 virtual result_type operator()(Arguments... arguments) = 0;
27};
28
29namespace detail {
30
31template<typename Function, typename Proto>
33
34template<typename Function, typename Result, typename... Arguments>
35class function_impl<Function, Result(Arguments...)> final : public function<Result(Arguments...)> {
36public:
37 using result_type = typename function<Result(Arguments...)>::result_type;
38
39 template<typename Func>
40 function_impl(Func&& func) noexcept : _function(std::forward<Func>(func))
41 {
42 }
43
44 result_type operator()(Arguments... arguments) override
45 {
46 return _function(std::forward<decltype(arguments)>(arguments)...);
47 }
48
49private:
50 Function _function;
51};
52
53template<typename Function, typename Proto>
55
56template<typename Function, typename... Arguments>
57class async_function_impl<Function, void(Arguments...)> final : public function<void(Arguments...)> {
58public:
59 using result_type = void;
60 using async_result_type = std::invoke_result_t<Function, Arguments...>;
61
62 template<typename Func>
63 async_function_impl(Func&& func) noexcept : _function(std::forward<Func>(func)), _promise()
64 {
65 }
66
67 void operator()(Arguments... arguments) override
68 {
69 if constexpr (std::is_same_v<async_result_type, void>) {
70 try {
71 _function(std::forward<decltype(arguments)>(arguments)...);
72 _promise.set_value();
73 } catch (...) {
74 _promise.set_exception(std::current_exception());
75 }
76 } else {
77 try {
78 _promise.set_value(_function(std::forward<decltype(arguments)>(arguments)...));
79 } catch (...) {
80 _promise.set_exception(std::current_exception());
81 }
82 }
83 }
84
85 [[nodiscard]] std::future<async_result_type> get_future() noexcept
86 {
87 return _promise.get_future();
88 }
89
90private:
91 Function _function;
93};
94
95}
96
97template<typename Proto, typename Func>
98auto make_function(Func&& func)
99{
100 return detail::function_impl<std::decay_t<Func>, Proto>{std::forward<Func>(func)};
101}
102
103template<typename Proto, typename Func>
104auto make_async_function(Func&& func)
105{
106 return detail::async_function_impl<std::decay_t<Func>, Proto>{std::forward<Func>(func)};
107}
108
109} // namespace hi::inline v1
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Definition functional.hpp:18
Definition functional.hpp:32
Definition functional.hpp:54
T current_exception(T... args)
T forward(T... args)