QuantumLibrary
quantum_capture_impl.h
1 /*
2 ** Copyright 2018 Bloomberg Finance L.P.
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16 //NOTE: DO NOT INCLUDE DIRECTLY
17 
18 //##############################################################################################
19 //#################################### IMPLEMENTATIONS #########################################
20 //##############################################################################################
21 
22 namespace Bloomberg {
23 namespace quantum {
24 
25 //==============================================================================================
26 // class Capture
27 //==============================================================================================
28 template <typename FUNC, typename ... ARGS>
29 Capture<FUNC,ARGS...>::Capture(FUNC&& func, ARGS&&...args) :
30  _func(std::forward<FUNC>(func)),
31  _args(std::forward<ARGS>(args)...) //pack
32 {}
33 
34 template <typename FUNC, typename ... ARGS>
35 template <typename ... T>
37  return apply<int>(_func, std::move(_args), std::forward<T>(t)...); //fwd
38 }
39 
40 template <typename FUNC, typename ... ARGS>
41 Capture<FUNC, ARGS...>
42 makeCapture(FUNC&& func, ARGS&& ... args)
43 {
44  return Capture<FUNC, ARGS...>(std::forward<FUNC>(func), std::forward<ARGS>(args)...);
45 }
46 
47 //==============================================================================================
48 // class Function
49 //==============================================================================================
50 
51 template <typename RET, typename ... ARGS>
52 Function<RET(ARGS...)>::Function(RET(*ptr)(ARGS...)) :
53  _callable(reinterpret_cast<void*>(ptr)),
54  _deleter(dummyDeleter)
55 {
56  _callback = [](void* ptr, ARGS...args)->RET {
57  return (*reinterpret_cast<Func>(ptr))(std::forward<ARGS>(args)...);
58  };
59 }
60 
61 template <typename RET, typename ... ARGS>
62 Function<RET(ARGS...)>::Function(const Function<RET(ARGS...)>& other)
63 {
64  *this = other;
65 }
66 
67 template <typename RET, typename ... ARGS>
68 Function<RET(ARGS...)>::Function(Function<RET(ARGS...)>&& other)
69 {
70  *this = std::move(other);
71 }
72 
73 template <typename RET, typename ... ARGS>
74 Function<RET(ARGS...)>&
75 Function<RET(ARGS...)>::operator=(const Function<RET(ARGS...)>& other)
76 {
77  if (this != &other) {
78  _callback = other._callback;
79  _deleter = other._deleter;
80  if (other._callable == other._storage.data()) {
81  _storage = other._storage;
82  _callable = _storage.data();
83  }
84  else {
85  _callable = other._callable;
86  }
87  }
88  return *this;
89 }
90 
91 template <typename RET, typename ... ARGS>
92 Function<RET(ARGS...)>&
93 Function<RET(ARGS...)>::operator=(Function<RET(ARGS...)>&& other)
94 {
95  *this = other;
96  if (this != &other) {
97  other._callable = nullptr; //disable
98  }
99  return *this;
100 }
101 
102 template <typename RET, typename ... ARGS>
103 Function<RET(ARGS...)>::~Function()
104 {
105  _deleter(_callable);
106 }
107 
108 template <typename RET, typename ... ARGS>
109 template <typename FUNCTOR>
110 Function<RET(ARGS...)>::Function(FUNCTOR&& functor)
111 {
112  initFunctor(std::forward<FUNCTOR>(functor), std::is_lvalue_reference<FUNCTOR>());
113 }
114 
115 template <typename RET, typename ... ARGS>
116 RET Function<RET(ARGS...)>::operator()(ARGS...args) {
117  return _callback(_callable, std::forward<ARGS>(args)...);
118 }
119 
120 template <typename RET, typename ... ARGS>
121 Function<RET(ARGS...)>::operator bool() const {
122  return !!_callable;
123 }
124 
125 template <typename RET, typename ... ARGS>
126 template <typename FUNCTOR>
127 void Function<RET(ARGS...)>::initFunctor(FUNCTOR&& functor, std::true_type)
128 {
129  _callable = std::addressof(functor);
130  _deleter = dummyDeleter;
131  _callback = [](void* ptr, ARGS...args)->RET {
132  return (*reinterpret_cast<std::remove_reference_t<FUNCTOR>*>(ptr))(std::forward<ARGS>(args)...);
133  };
134 }
135 
136 template <typename RET, typename ... ARGS>
137 template <typename FUNCTOR>
138 void Function<RET(ARGS...)>::initFunctor(FUNCTOR&& functor, std::false_type)
139 {
140  if (sizeof(FUNCTOR) <= size) {
141  new (_storage.data()) FUNCTOR(std::forward<FUNCTOR>(functor));
142  _callable = _storage.data();
143  _deleter = dummyDeleter;
144  }
145  else {
146  _callable = new char[sizeof(FUNCTOR)];
147  new (_callable) FUNCTOR(std::forward<FUNCTOR>(functor));
148  _deleter = deleter;
149  }
150  _callback = [](void* ptr, ARGS...args)->RET {
151  return (*reinterpret_cast<std::remove_reference_t<FUNCTOR>*>(ptr))(std::forward<ARGS>(args)...);
152  };
153 }
154 
155 }
156 }
Definition: quantum_buffer_impl.h:22
Definition: quantum_stl_impl.h:23
Capture(FUNC &&func, ARGS &&...args)
Definition: quantum_capture_impl.h:29
int operator()(T &&...t)
Definition: quantum_capture_impl.h:36
Similar implementation to std::function except that it allows capture of non-copyable types.
Definition: quantum_capture.h:62
Capture< FUNC, ARGS... > makeCapture(FUNC &&func, ARGS &&... args)
Definition: quantum_capture_impl.h:42
Class allowing lambda parameter captures.
Definition: quantum_capture.h:38