libquentier  0.8.0
The library for rich desktop clients of Evernote service
TrackedTask.h
1 /*
2  * Copyright 2022-2024 Dmitry Ivanov
3  *
4  * This file is part of libquentier
5  *
6  * libquentier is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, version 3 of the License.
9  *
10  * libquentier is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libquentier. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include <functional>
22 #include <type_traits>
23 #include <utility>
24 
25 namespace quentier::threading {
26 
27 namespace detail {
28 
29 template <typename LockableObject, typename Function, typename... Arguments>
30 constexpr std::enable_if_t<std::is_invocable_v<Function, Arguments...>> invoke(
31  LockableObject & lockableObject, Function & function,
32  Arguments &&... arguments)
33 {
34  const auto lockedObject = lockableObject.lock();
35  if (lockedObject) {
36  std::invoke(function, std::forward<Arguments>(arguments)...);
37  }
38 }
39 
40 template <typename LockableObject, typename Function, typename... Arguments>
41 constexpr std::enable_if_t<
42  !std::is_invocable_v<Function, Arguments...> &&
43  std::is_member_function_pointer_v<Function>>
44  invoke(
45  LockableObject & lockableObject, Function & function,
46  Arguments &&... arguments)
47 {
48  const auto lockedObject = lockableObject.lock();
49  if (lockedObject) {
50  std::invoke(
51  function, *lockedObject, std::forward<Arguments>(arguments)...);
52  }
53 }
54 
55 } // namespace detail
56 
73 template <typename LockableObject, typename Function>
75 {
76 public:
77  template <typename SomeLockableObject, typename SomeFunction>
78  constexpr TrackedTask(
79  SomeLockableObject && someLockableObject, SomeFunction && function) :
80  m_lockableObject{std::forward<SomeLockableObject>(someLockableObject)},
81  m_function{std::forward<SomeFunction>(function)}
82  {}
83 
84  template <
85  typename... Arguments,
86  typename = std::enable_if_t<
87  std::is_invocable_v<Function, Arguments...> ||
88  std::is_member_function_pointer_v<Function>>>
89  constexpr void operator()(Arguments &&... arguments)
90  {
91  detail::invoke(
92  m_lockableObject, m_function,
93  std::forward<Arguments>(arguments)...);
94  }
95 
96  template <
97  typename... Arguments,
98  typename = std::enable_if_t<
99  std::is_invocable_v<Function, Arguments...> ||
100  std::is_member_function_pointer_v<Function>>>
101  constexpr void operator()(Arguments &&... arguments) const
102  {
103  detail::invoke(
104  m_lockableObject, m_function,
105  std::forward<Arguments>(arguments)...);
106  }
107 
108 private:
109  LockableObject m_lockableObject;
110  Function m_function;
111 };
112 
113 template <typename LockableObject, typename Function>
114 TrackedTask(LockableObject, Function) -> TrackedTask<LockableObject, Function>;
115 
116 } // namespace quentier::threading
Definition: threading/Factory.h:24
Definition: TrackedTask.h:74