1 #ifndef PROTON_WORK_QUEUE_HPP 2 #define PROTON_WORK_QUEUE_HPP 28 #include "./internal/config.hpp" 29 #include "./internal/export.hpp" 30 #include "./internal/pn_unique_ptr.hpp" 34 #if PN_CPP_HAS_LAMBDAS && PN_CPP_HAS_VARIADIC_TEMPLATES 35 #include <type_traits> 38 struct pn_connection_t;
49 namespace internal {
namespace v03 {
53 virtual ~invocable() {}
55 virtual invocable& clone()
const = 0;
56 virtual void operator() () = 0;
60 struct invocable_cloner : invocable {
61 virtual ~invocable_cloner() {}
62 virtual invocable& clone()
const {
63 return *
new T(static_cast<T const&>(*
this));
67 struct invocable_wrapper {
68 invocable_wrapper(): wrapped_(0) {}
69 invocable_wrapper(
const invocable_wrapper& w): wrapped_(&w.wrapped_->clone()) {}
70 invocable_wrapper& operator=(
const invocable_wrapper& that) {
71 invocable_wrapper newthis(that);
75 #if PN_CPP_HAS_RVALUE_REFERENCES 76 invocable_wrapper(invocable_wrapper&& w): wrapped_(w.wrapped_) {}
77 invocable_wrapper& operator=(invocable_wrapper&& that) {
delete wrapped_; wrapped_ = that.wrapped_;
return *
this; }
79 ~invocable_wrapper() {
delete wrapped_; }
81 invocable_wrapper(
const invocable& i): wrapped_(&i.clone()) {}
82 void operator()() { (*wrapped_)(); }
96 work(
const invocable& i): item_(i) {}
99 void operator()() { item_(); }
104 invocable_wrapper item_;
111 struct work0 :
public invocable_cloner<work0<R> > {
122 template <
class R,
class A>
123 struct work1 :
public invocable_cloner<work1<R,A> > {
127 work1(R (* t)(A), A a) :
135 template <
class R,
class A,
class B>
136 struct work2 :
public invocable_cloner<work2<R,A,B> > {
141 work2(R (* t)(A, B), A a, B b) :
142 fn_(t), a_(a), b_(b) {}
149 template <
class R,
class A,
class B,
class C>
150 struct work3 :
public invocable_cloner<work3<R,A,B,C> > {
156 work3(R (* t)(A, B, C), A a, B b, C c) :
157 fn_(t), a_(a), b_(b), c_(c) {}
164 template <
class R,
class T>
165 struct work_pmf0 :
public invocable_cloner<work_pmf0<R,T> > {
169 work_pmf0(R (T::* a)(), T& h) :
170 holder_(h), fn_(a) {}
177 template <
class R,
class T,
class A>
178 struct work_pmf1 :
public invocable_cloner<work_pmf1<R,T,A> > {
183 work_pmf1(R (T::* t)(A), T& h, A a) :
184 holder_(h), fn_(t), a_(a) {}
191 template <
class R,
class T,
class A,
class B>
192 struct work_pmf2 :
public invocable_cloner<work_pmf2<R,T,A,B> > {
198 work_pmf2(R (T::* t)(A, B), T& h, A a, B b) :
199 holder_(h), fn_(t), a_(a), b_(b) {}
202 (holder_.*fn_)(a_, b_);
206 template <
class R,
class T,
class A,
class B,
class C>
207 struct work_pmf3 :
public invocable_cloner<work_pmf3<R,T,A,B,C> > {
209 R (T::* fn_)(A, B, C);
214 work_pmf3(R (T::* t)(A, B, C), T& h, A a, B b, C c) :
215 holder_(h), fn_(t), a_(a), b_(b), c_(c) {}
218 (holder_.*fn_)(a_, b_, c_);
224 template <
class R,
class T>
225 work make_work(R (T::*f)(), T* t) {
226 return work_pmf0<R, T>(f, *t);
229 template <
class R,
class T,
class A>
230 work make_work(R (T::*f)(A), T* t, A a) {
231 return work_pmf1<R, T, A>(f, *t, a);
234 template <
class R,
class T,
class A,
class B>
235 work make_work(R (T::*f)(A, B), T* t, A a, B b) {
236 return work_pmf2<R, T, A, B>(f, *t, a, b);
239 template <
class R,
class T,
class A,
class B,
class C>
240 work make_work(R (T::*f)(A, B, C), T* t, A a, B b, C c) {
241 return work_pmf3<R, T, A, B, C>(f, *t, a, b, c);
245 work make_work(R (*f)()) {
249 template <
class R,
class A>
250 work make_work(R (*f)(A), A a) {
251 return work1<R, A>(f, a);
254 template <
class R,
class A,
class B>
255 work make_work(R (*f)(A, B), A a, B b) {
256 return work2<R, A, B>(f, a, b);
259 template <
class R,
class A,
class B,
class C>
260 work make_work(R (*f)(A, B, C), A a, B b, C c) {
261 return work3<R, A, B, C>(f, a, b, c);
266 #if PN_CPP_HAS_LAMBDAS && PN_CPP_HAS_VARIADIC_TEMPLATES 268 namespace internal {
namespace v11 {
282 class =
typename std::enable_if<!std::is_same<typename std::decay<T>::type,work>::value>::type
284 work(T&& f): item_(
std::forward<T>(f)) {}
289 void operator()() { item_(); }
294 std::function<void()> item_;
304 template <
class... Rest>
305 work make_work(Rest&&... r) {
306 return std::bind(std::forward<Rest>(r)...);
311 using internal::v11::work;
312 using internal::v11::make_work;
316 using internal::v03::work;
317 using internal::v03::make_work;
352 PN_CPP_EXTERN ~work_queue();
362 PN_CPP_EXTERN
bool add(work fn);
365 PN_CPP_EXTERN PN_CPP_DEPRECATED(
"Use 'work_queue::add(work)'")
bool add(void_function0& fn);
370 #if PN_CPP_HAS_LAMBDAS && PN_CPP_HAS_VARIADIC_TEMPLATES && defined(qpid_proton_cpp_EXPORTS) 371 PN_CPP_EXTERN
bool add(internal::v03::work fn);
383 PN_CPP_EXTERN
void schedule(
duration, work fn);
386 PN_CPP_EXTERN PN_CPP_DEPRECATED(
"Use 'work_queue::schedule(duration, work)'")
void schedule(
duration, void_function0& fn);
391 #if PN_CPP_HAS_LAMBDAS && PN_CPP_HAS_VARIADIC_TEMPLATES && defined(qpid_proton_cpp_EXPORTS) 392 PN_CPP_EXTERN
void schedule(
duration, internal::v03::work fn);
397 PN_CPP_EXTERN
static work_queue&
get(pn_connection_t*);
398 PN_CPP_EXTERN
static work_queue&
get(pn_session_t*);
399 PN_CPP_EXTERN
static work_queue&
get(pn_link_t*);
401 internal::pn_unique_ptr<impl> impl_;
411 #endif // PROTON_WORK_QUEUE_HPP A top-level container of connections, sessions, and links.
Definition: container.hpp:50
void swap(map< K, T > &, map< K, T > &)
Swap proton::map instances.
A span of time in milliseconds.
Definition: duration.hpp:39
A span of time in milliseconds.
Deprecated - Use the API in work_queue.hpp.
Unsettled API - A context for thread-safe execution of work.
Definition: work_queue.hpp:339
Unsettled API - An AMQP driver for a single connection.
Definition: connection_driver.hpp:93
The main Proton namespace.
Definition: annotation_key.hpp:33