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 "type_traits.hpp"
8#include <type_traits>
9#include <future>
10
11namespace hi::inline v1 {
12
13template<typename Proto>
15
16template<typename Result, typename... Arguments>
17class function<Result(Arguments...)> {
18public:
19 using result_type = Result;
20
21 virtual ~function() = default;
22 virtual result_type operator()(Arguments... arguments) = 0;
23};
24
25namespace detail {
26
27template<typename Function, typename Proto>
29
30template<typename Function, typename Result, typename... Arguments>
31class function_impl<Function, Result(Arguments...)> final : public function<Result(Arguments...)> {
32public:
33 using result_type = typename function<Result(Arguments...)>::result_type;
34
35 template<typename Func>
36 function_impl(Func&& func) noexcept : _function(std::forward<Func>(func))
37 {
38 }
39
40 result_type operator()(Arguments... arguments) override
41 {
42 return _function(std::forward<decltype(arguments)>(arguments)...);
43 }
44
45private:
46 Function _function;
47};
48
49template<typename Function, typename Proto>
51
52template<typename Function, typename... Arguments>
53class async_function_impl<Function, void(Arguments...)> final : public function<void(Arguments...)> {
54public:
55 using result_type = void;
56 using async_result_type = std::invoke_result_t<Function, Arguments...>;
57
58 template<typename Func>
59 async_function_impl(Func&& func) noexcept : _function(std::forward<Func>(func)), _promise()
60 {
61 }
62
63 void operator()(Arguments... arguments) override
64 {
65 if constexpr (std::is_same_v<async_result_type, void>) {
66 try {
67 _function(std::forward<decltype(arguments)>(arguments)...);
68 _promise.set_value();
69 } catch (...) {
70 _promise.set_exception(std::current_exception());
71 }
72 } else {
73 try {
74 _promise.set_value(_function(std::forward<decltype(arguments)>(arguments)...));
75 } catch (...) {
76 _promise.set_exception(std::current_exception());
77 }
78 }
79 }
80
81 [[nodiscard]] std::future<async_result_type> get_future() noexcept
82 {
83 return _promise.get_future();
84 }
85
86private:
87 Function _function;
89};
90
91}
92
93template<typename Proto, typename Func>
94auto make_function(Func&& func)
95{
96 return detail::function_impl<std::decay_t<Func>, Proto>{std::forward<Func>(func)};
97}
98
99template<typename Proto, typename Func>
100auto make_async_function(Func&& func)
101{
102 return detail::async_function_impl<std::decay_t<Func>, Proto>{std::forward<Func>(func)};
103}
104
105} // namespace hi::inline v1
DOXYGEN BUG.
Definition algorithm.hpp:15
Definition functional.hpp:14
Definition functional.hpp:28
Definition functional.hpp:50
T current_exception(T... args)
T forward(T... args)