Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
EventQueue.h
00001 /* 00002 * Copyright (c) 2016-2019 ARM Limited 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #ifndef EVENT_QUEUE_H 00019 #define EVENT_QUEUE_H 00020 00021 #include "events/equeue.h" 00022 #include "platform/Callback.h" 00023 #include "platform/NonCopyable.h" 00024 #include <cstddef> 00025 #include <new> 00026 00027 namespace events { 00028 /** 00029 * \addtogroup events-public-api 00030 * @{ 00031 */ 00032 00033 /** EVENTS_EVENT_SIZE 00034 * Minimum size of an event 00035 * This size fits a Callback<void()> at minimum 00036 */ 00037 #define EVENTS_EVENT_SIZE \ 00038 (EQUEUE_EVENT_SIZE - 2*sizeof(void*) + sizeof(mbed::Callback<void()>)) 00039 00040 /** EVENTS_QUEUE_SIZE 00041 * Default size of buffer for events 00042 */ 00043 #define EVENTS_QUEUE_SIZE (32*EVENTS_EVENT_SIZE) 00044 00045 // Predeclared classes 00046 template <typename F> 00047 class Event; 00048 template <typename F, typename A> 00049 class UserAllocatedEvent; 00050 00051 /** 00052 * \defgroup events_EventQueue EventQueue class 00053 * @{ 00054 */ 00055 00056 /** EventQueue 00057 * 00058 * Flexible event queue for dispatching events 00059 */ 00060 class EventQueue : private mbed::NonCopyable<EventQueue> { 00061 public: 00062 /** Create an EventQueue 00063 * 00064 * Create an event queue. The event queue either allocates a buffer of 00065 * the specified size with malloc or uses the user provided buffer or 00066 * uses 1B dummy buffer if 0 size passed. 00067 * 00068 * 0 size queue is a special purpose queue to dispatch static events 00069 * only (see UserAllocatedEvent). Such a queue gives the guarantee 00070 * that no dynamic memory allocation will take place while queue 00071 * creation and events posting & dispatching. 00072 * 00073 * @param size Size of buffer to use for events in bytes 00074 * (default to EVENTS_QUEUE_SIZE) 00075 * If 0 provided then 1B dummy buffer is used 00076 * @param buffer Pointer to buffer to use for events 00077 * (default to NULL) 00078 */ 00079 EventQueue(unsigned size = EVENTS_QUEUE_SIZE, unsigned char *buffer = NULL); 00080 00081 /** Destroy an EventQueue 00082 */ 00083 ~EventQueue(); 00084 00085 /** Dispatch events 00086 * 00087 * Executes events until the specified milliseconds have passed. 00088 * If ms is negative, the dispatch function will dispatch events 00089 * indefinitely or until break_dispatch is called on this queue. 00090 * 00091 * When called with a finite timeout, the dispatch function is guaranteed 00092 * to terminate. When called with a timeout of 0, the dispatch function 00093 * does not wait and is IRQ safe. 00094 * 00095 * @param ms Time to wait for events in milliseconds, a negative 00096 * value will dispatch events indefinitely 00097 * (default to -1) 00098 */ 00099 void dispatch(int ms = -1); 00100 00101 /** Dispatch events without a timeout 00102 * 00103 * This is equivalent to EventQueue::dispatch with no arguments, but 00104 * avoids overload ambiguities when passed as a callback. 00105 * 00106 * @see EventQueue::dispatch 00107 */ 00108 void dispatch_forever() 00109 { 00110 dispatch(); 00111 } 00112 00113 /** Break out of a running event loop 00114 * 00115 * Forces the specified event queue's dispatch loop to terminate. Pending 00116 * events may finish executing, but no new events will be executed. 00117 */ 00118 void break_dispatch(); 00119 00120 /** Millisecond counter 00121 * 00122 * Returns the underlying tick of the event queue represented as the 00123 * number of milliseconds that have passed since an arbitrary point in 00124 * time. Intentionally overflows to 0 after 2^32-1. 00125 * 00126 * @return The underlying tick of the event queue in milliseconds 00127 */ 00128 unsigned tick(); 00129 00130 /** Cancel an in-flight event 00131 * 00132 * Attempts to cancel an event referenced by the unique id returned from 00133 * one of the call functions. It is safe to call cancel after an event 00134 * has already been dispatched. 00135 * 00136 * id must be valid i.e. event must have not finished executing. 00137 * 00138 * The cancel function is IRQ safe. 00139 * 00140 * If called while the event queue's dispatch loop is active in another thread, 00141 * the cancel function does not guarantee that the event will not execute after it 00142 * returns, as the event may have already begun executing. A call made from 00143 * the same thread as the dispatch loop will always succeed with a valid id. 00144 * 00145 * @param id Unique id of the event 00146 * @return true if event was successfully cancelled 00147 * false if event was not cancelled (invalid id or executing already begun) 00148 */ 00149 bool cancel(int id); 00150 00151 /** Cancel an in-flight user allocated event 00152 * 00153 * Attempts to cancel an UserAllocatedEvent referenced by its address 00154 * It is safe to call cancel after an event has already been dispatched. 00155 * 00156 * Event must be valid i.e. event must have not finished executing 00157 * and must have been bound to this queue. 00158 * 00159 * The cancel function is IRQ safe. 00160 * 00161 * If called while the event queue's dispatch loop is active in another thread, 00162 * the cancel function does not guarantee that the event will not execute after it 00163 * returns, as the event may have already begun executing. A call made from 00164 * the same thread as the dispatch loop will always succeed with a valid id. 00165 * 00166 * @param event Address of the event 00167 * @return true if event was successfully cancelled 00168 * false if event was not cancelled (invalid queue or executing already begun) 00169 */ 00170 template<typename F, typename A> 00171 bool cancel(UserAllocatedEvent<F, A> *event) 00172 { 00173 if (event->_equeue != &_equeue) { 00174 return false; 00175 } 00176 return equeue_cancel_user_allocated(&_equeue, event); 00177 } 00178 00179 /** Query how much time is left for delayed event 00180 * 00181 * If the event is delayed, this function can be used to query how much time 00182 * is left until the event is due to be dispatched. 00183 * 00184 * id must be valid i.e. event must have not finished executing. 00185 * 00186 * This function is IRQ safe. 00187 * 00188 * @param id Unique id of the event 00189 * 00190 * @return Remaining time in milliseconds or 00191 * 0 if event is already due to be dispatched or 00192 * is currently executing. 00193 * Undefined if id is invalid. 00194 * 00195 */ 00196 int time_left(int id); 00197 00198 /** Query how much time is left for delayed UserAllocatedEvent 00199 * 00200 * If the event is delayed, this function can be used to query how much time 00201 * is left until the event is due to be dispatched. 00202 * 00203 * Event must be valid i.e. event must have not finished executing 00204 * and must have been bound to this queue. 00205 * 00206 * This function is IRQ safe. 00207 * 00208 * @param event Address of the event 00209 * 00210 * @return Remaining time in milliseconds or 00211 * 0 if event is already due to be dispatched or 00212 * is currently executing. 00213 * Undefined if id is invalid. 00214 * 00215 */ 00216 template<typename F, typename A> 00217 int time_left(UserAllocatedEvent<F, A> *event) 00218 { 00219 if (event && event->_equeue != &_equeue) { 00220 return -1; 00221 } 00222 return equeue_timeleft_user_allocated(&_equeue, &event->_e); 00223 } 00224 00225 /** Background an event queue onto a single-shot timer-interrupt 00226 * 00227 * When updated, the event queue will call the provided update function 00228 * with a timeout indicating when the queue should be dispatched. A 00229 * negative timeout will be passed to the update function when the 00230 * timer-interrupt is no longer needed. 00231 * 00232 * Passing a null function disables the existing update function. 00233 * 00234 * The background function allows an event queue to take advantage of 00235 * hardware timers or other event loops, allowing an event queue to be 00236 * ran in the background without consuming the foreground thread. 00237 * 00238 * @param update Function called to indicate when the queue should be 00239 * dispatched 00240 */ 00241 void background(mbed::Callback<void(int)> update); 00242 00243 /** Chain an event queue onto another event queue 00244 * 00245 * After chaining a queue to a target, calling dispatch on the target 00246 * queue will also dispatch events from this queue. The queues use 00247 * their own buffers and events must be handled independently. 00248 * 00249 * A null queue as the target will unchain the existing queue. 00250 * 00251 * The chain function allows multiple event queues to be composed, 00252 * sharing the context of a dispatch loop while still being managed 00253 * independently 00254 * 00255 * @param target Queue that will dispatch this queue's events as a 00256 * part of its dispatch loop 00257 * 00258 * @return Zero on success and negative error code value if chaining fails 00259 * 00260 */ 00261 int chain(EventQueue *target); 00262 00263 00264 00265 #if defined(DOXYGEN_ONLY) 00266 /** Calls an event on the queue 00267 * 00268 * The specified callback will be executed in the context of the event 00269 * queue's dispatch loop. 00270 * 00271 * The call function is IRQ safe and can act as a mechanism for moving 00272 * events out of IRQ contexts. 00273 * 00274 * @param f Function to execute in the context of the dispatch loop 00275 * @param args Arguments to pass to the callback 00276 * @return A unique id that represents the posted event and can 00277 * be passed to cancel, or an id of 0 if there is not 00278 * enough memory to allocate the event. 00279 * Returned id will remain valid until event has finished 00280 * executing. 00281 * 00282 * @code 00283 * #include "mbed.h" 00284 * 00285 * int main() { 00286 * // creates a queue with the default size 00287 * EventQueue queue; 00288 * 00289 * // events are simple callbacks 00290 * queue.call(printf, "called immediately\n"); 00291 * 00292 * // the dispatch method executes events 00293 * queue.dispatch(); 00294 * } 00295 * @endcode 00296 */ 00297 template <typename F, typename ...Args> 00298 int call(F f, Args ...args); 00299 00300 /** Calls an event on the queue 00301 * 00302 * The specified callback is executed in the context of the event 00303 * queue's dispatch loop. 00304 * 00305 * The call function is IRQ safe and can act as a mechanism for moving 00306 * events out of IRQ contexts. 00307 * 00308 * @param obj Object to call with the member function 00309 * @param method Member function to execute in the context of the dispatch loop 00310 * @param args Arguments to pass to the callback 00311 * @return A unique ID that represents the posted event and can 00312 * be passed to cancel, or an ID of 0 if there is not 00313 * enough memory to allocate the event. 00314 * Returned ID remains valid until event has finished 00315 * executing. 00316 * 00317 * @code 00318 * #include "mbed.h" 00319 * 00320 * class EventHandler { 00321 * int _id; 00322 * public: 00323 * EventHandler(int id) : _id(id) { } 00324 * 00325 * void handler(int c) { 00326 * printf("ID: %d Param: %d\r\n", _id, c); 00327 * } 00328 * }; 00329 * 00330 * int main() { 00331 * // creates a queue with the default size 00332 * EventQueue queue; 00333 * 00334 * // Create EventHandler object with state 00335 * EventHandler handler_cb(1); 00336 * 00337 * // events are simple callbacks, call object method 00338 * // with provided parameter 00339 * queue.call(&handler_cb, &EventHandler::handler, 2); 00340 * 00341 * // the dispath method executes events 00342 * queue.dispatch(); 00343 * } 00344 * @endcode 00345 */ 00346 // AStyle ignore, not handling correctly below 00347 // *INDENT-OFF* 00348 template <typename T, typename R, typename ...Args> 00349 int call(T *obj, R (T::*method)(Args ...args), Args ...args); 00350 // *INDENT-ON* 00351 00352 /** Calls an event on the queue after a specified delay 00353 * 00354 * The specified callback is executed in the context of the event 00355 * queue's dispatch loop. 00356 * 00357 * The call_in function is IRQ safe and can act as a mechanism for moving 00358 * events out of IRQ contexts. 00359 * 00360 * @param ms Time to delay in milliseconds 00361 * @param args Arguments to pass to the callback 00362 * @return A unique ID that represents the posted event and can 00363 * be passed to cancel, or an ID of 0 if there is not 00364 * enough memory to allocate the event. 00365 * 00366 * @code 00367 * #include "mbed.h" 00368 * 00369 * int main() { 00370 * // creates a queue with the default size 00371 * EventQueue queue; 00372 * 00373 * // events are simple callbacks 00374 * queue.call_in(2000, printf, "called in 2 seconds\n"); 00375 * 00376 * // the dispatch methods executes events 00377 * queue.dispatch(); 00378 * } 00379 * @endcode 00380 */ 00381 template <typename F, typename ...Args> 00382 int call_in(int ms, Args ...args); 00383 00384 /** Calls an event on the queue after a specified delay 00385 * 00386 * The specified callback is executed in the context of the event 00387 * queue's dispatch loop. 00388 * 00389 * The call_in function is IRQ safe and can act as a mechanism for moving 00390 * events out of IRQ contexts. 00391 * 00392 * @param ms Time to delay in milliseconds 00393 * @param obj Object to call with the member function 00394 * @param method Member function to execute in the context of the dispatch loop 00395 * @param args Arguments to pass to the callback 00396 * @return A unique ID that represents the posted event and can 00397 * be passed to cancel, or an ID of 0 if there is not 00398 * enough memory to allocate the event. 00399 * 00400 * @code 00401 * #include "mbed.h" 00402 * 00403 * class EventHandler { 00404 * int _id; 00405 * public: 00406 * EventHandler(int id) : _id(id) { } 00407 * 00408 * void handler(int c) { 00409 * printf("ID: %d Param: %d\r\n", _id, c); 00410 * } 00411 * }; 00412 * 00413 * int main() { 00414 * // creates a queue with the default size 00415 * EventQueue queue; 00416 * 00417 * // Create EventHandler object with state 00418 * EventHandler handler_cb(3); 00419 * 00420 * // events are simple callbacks, call object method in 2 seconds 00421 * // with provided parameter 00422 * queue.call_in(2000, &handler_cb, &EventHandler::handler, 4); 00423 * 00424 * // the dispatch method executes events 00425 * queue.dispatch(); 00426 * } 00427 * @endcode 00428 */ 00429 // AStyle ignore, not handling correctly below 00430 // *INDENT-OFF* 00431 template <typename T, typename R, typename ...Args> 00432 int call_in(int ms, T *obj, R (T::*method)(Args ...args), Args ...args); 00433 // *INDENT-ON* 00434 00435 /** Calls an event on the queue periodically 00436 * 00437 * @note The first call_every event occurs after the specified delay. 00438 * To create a periodic event that fires immediately, @see Event. 00439 * 00440 * The specified callback is executed in the context of the event 00441 * queue's dispatch loop. 00442 * 00443 * The call_every function is IRQ safe and can act as a mechanism for 00444 * moving events out of IRQ contexts. 00445 * 00446 * @param ms Period of the event in milliseconds 00447 * @param f Function to execute in the context of the dispatch loop 00448 * @param args Arguments to pass to the callback 00449 * @return A unique ID that represents the posted event and can 00450 * be passed to cancel, or an ID of 0 if there is not 00451 * enough memory to allocate the event. 00452 * 00453 * @code 00454 * #include "mbed.h" 00455 * 00456 * class EventHandler { 00457 * int _id; 00458 * public: 00459 * EventHandler(int id) : _id(id) { } 00460 * 00461 * void handler(int c) { 00462 * printf("ID: %d Param: %d\r\n", _id, c); 00463 * } 00464 * }; 00465 * 00466 * int main() { 00467 * // creates a queue with the default size 00468 * EventQueue queue; 00469 * 00470 * // events are simple callbacks, call every 2 seconds 00471 * queue.call_every(2000, printf, "Calling every 2 seconds\n"); 00472 * 00473 * // the dispatch method executes events 00474 * queue.dispatch(); 00475 * } 00476 * @endcode 00477 */ 00478 template <typename F, typename ...Args> 00479 int call_every(int ms, F f, Args ...args); 00480 00481 /** Calls an event on the queue periodically 00482 * 00483 * @note The first call_every event occurs after the specified delay. 00484 * To create a periodic event that fires immediately, @see Event. 00485 * 00486 * The specified callback is executed in the context of the event 00487 * queue's dispatch loop. 00488 * 00489 * The call_every function is IRQ safe and can act as a mechanism for 00490 * moving events out of IRQ contexts. 00491 * 00492 * @param ms Period of the event in milliseconds 00493 * @param obj Object to call with the member function 00494 * @param method Member function to execute in the context of the dispatch loop 00495 * @param args Arguments to pass to the callback 00496 * 00497 * @code 00498 * #include "mbed.h" 00499 * 00500 * class EventHandler { 00501 * int _id; 00502 * public: 00503 * EventHandler(int id) : _id(id) { } 00504 * 00505 * void handler(int c) { 00506 * printf("ID: %d Param: %d\r\n", _id, c); 00507 * } 00508 * }; 00509 * 00510 * int main() { 00511 * // creates a queue with the default size 00512 * EventQueue queue; 00513 * 00514 * // Create EventHandler object with state 00515 * EventHandler handler_cb(5); 00516 * 00517 * // events are simple callbacks, call object method every 2 seconds 00518 * // with provided parameter 00519 * queue.call_every(2000, &handler_cb, &EventHandler::handler, 6); 00520 * 00521 * // the dispatch method executes events 00522 * queue.dispatch(); 00523 * } 00524 * @endcode 00525 */ 00526 // AStyle ignore, not handling correctly below 00527 // *INDENT-OFF* 00528 template <typename T, typename R, typename ...Args> 00529 int call_every(int ms, T *obj, R (T::*method)(Args ...args), Args ...args); 00530 // *INDENT-ON* 00531 00532 /** Creates an event bound to the event queue 00533 * 00534 * Constructs an event bound to the specified event queue. The specified 00535 * callback acts as the target for the event and is executed in the 00536 * context of the event queue's dispatch loop once posted. 00537 * 00538 * @param func Function to execute when the event is dispatched 00539 * @param context_args Arguments to pass to the callback 00540 * @return Event that dispatches on the specific queue 00541 * 00542 * @code 00543 * #include "mbed.h" 00544 * 00545 * void handler(int c) { 00546 * printf("Param: %d\r\n", c); 00547 * } 00548 * 00549 * int main() 00550 * { 00551 * EventQueue queue; 00552 * 00553 * // Create event with parameter 00554 * Event<void()> e = queue.event(handler, 1); 00555 * e(); 00556 * 00557 * // Create event and post parameter later 00558 * Event<void(int)> e2 = queue.event(handler); 00559 * 00560 * // Post the event with paramter 8 00561 * e.post(8); 00562 * 00563 * // The dispatch method executes events 00564 * queue.dispatch(); 00565 * 00566 * e2.post(2); 00567 * 00568 * queue.dispatch(); 00569 * } 00570 * @endcode 00571 */ 00572 // AStyle ignore, not handling correctly below 00573 // *INDENT-OFF* 00574 template <typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args> 00575 Event<void(Args...)> event(R (*func)(BoundArgs..., Args...), ContextArgs ...context_args); 00576 // *INDENT-ON* 00577 00578 /** Creates an event bound to the event queue 00579 * 00580 * Constructs an event bound to the specified event queue. The specified 00581 * callback acts as the target for the event and is executed in the 00582 * context of the event queue's dispatch loop once posted. 00583 * 00584 * @param obj Object to call with the member function 00585 * @param method Member function to execute in the context of the dispatch loop 00586 * @param context_args Arguments to pass to the callback 00587 * @return Event that dispatches on the specific queue 00588 * 00589 * @code 00590 * #include "mbed.h" 00591 * 00592 * class EventHandler { 00593 * int _id; 00594 * 00595 * public: 00596 * EventHandler(int id) : _id(id) { } 00597 * 00598 * void handler(int c) { 00599 * printf("ID: %d Param: %d\r\n", _id, c); 00600 * } 00601 * }; 00602 * 00603 * int main() 00604 * { 00605 * EventQueue queue; 00606 * 00607 * EventHandler handler_cb(10); 00608 * 00609 * // Create event on the eventqueue with a method callback 00610 * Event<void(int)> e = queue.event(&handler_cb, &EventHandler::handler); 00611 * 00612 * // Post the event with paramter 8 00613 * e.post(11); 00614 * 00615 * // The dispatch method executes events 00616 * queue.dispatch(); 00617 * } 00618 * @endcode 00619 */ 00620 // AStyle ignore, not handling correctly below 00621 // *INDENT-OFF* 00622 template <typename T, typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args> 00623 Event<void(Args...)> event(T *obj, R (T::*method)(BoundArgs..., Args...), ContextArgs ...context_args); 00624 // *INDENT-ON* 00625 00626 /** Creates an event bound to the event queue 00627 * 00628 * Constructs an event bound to the specified event queue. The specified 00629 * callback acts as the target for the event and is executed in the 00630 * context of the event queue's dispatch loop once posted. 00631 * 00632 * @param cb Callback object 00633 * @param context_args Arguments to pass to the callback 00634 * @return Event that dispatches on the specific queue 00635 * 00636 * @code 00637 * #include "mbed.h" 00638 * 00639 * void handler(int c) { 00640 * printf("Param: %d\r\n", c); 00641 * } 00642 * 00643 * int main() 00644 * { 00645 * EventQueue queue; 00646 * // Create callback object acting as a function 00647 * // pointer to handler 00648 * Callback<void(int)> cb(handler); 00649 * 00650 * // Pass the callback object to the eventqueue 00651 * Event<void(int)> e = queue.event(cb); 00652 * 00653 * // Post the event with parameter 8 00654 * e.post(9); 00655 * 00656 * // The dispatch method executes events 00657 * q.dispatch(); 00658 * } 00659 * @endcode 00660 */ 00661 template <typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args> 00662 Event<void(Args...)> event(mbed::Callback<R(BoundArgs..., Args...)> cb, ContextArgs ...context_args); 00663 00664 /** Creates an user allocated event bound to the event queue 00665 * 00666 * Constructs an user allocated event bound to the specified event queue. 00667 * The specified callback acts as the target for the event and is executed 00668 * in the context of the event queue's dispatch loop once posted. 00669 * 00670 * @code 00671 * #include "mbed.h" 00672 * 00673 * void handler(int data) { ... } 00674 * 00675 * class Device { 00676 * public: 00677 * void handler(int data) { ... } 00678 * }; 00679 * 00680 * Device dev; 00681 * 00682 * // queue with not internal storage for dynamic events 00683 * // accepts only user allocated events 00684 * static EventQueue queue(0); 00685 * // Create events 00686 * static auto e1 = make_user_allocated_event(&dev, Device::handler, 2); 00687 * static auto e2 = queue.make_user_allocated_event(handler, 3); 00688 * 00689 * int main() 00690 * { 00691 * e1.call_on(&queue); 00692 * e2.call(); 00693 * 00694 * queue.dispatch(1); 00695 * } 00696 * @endcode 00697 * 00698 * @param f Function to execute when the event is dispatched 00699 * @return Event that will dispatch on the specific queue 00700 */ 00701 template <typename F, typename... ArgTs> 00702 UserAllocatedEvent<F, void(ArgTs...)> make_user_allocated_event(F f, ArgTs... args); 00703 00704 /** Creates an user allocated event bound to the event queue 00705 * @see EventQueue::make_user_allocated_event 00706 */ 00707 template <typename T, typename R, typename... ArgTs> 00708 UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(T *obj, R(T::*method)(ArgTs... args), ArgTs... args); 00709 00710 00711 #else 00712 00713 /** Calls an event on the queue 00714 * 00715 * The specified callback is executed in the context of the event 00716 * queue's dispatch loop. 00717 * 00718 * The call function is IRQ safe and can act as a mechanism for moving 00719 * events out of IRQ contexts. 00720 * 00721 * @param f Function to execute in the context of the dispatch loop 00722 * @return A unique ID that represents the posted event and can 00723 * be passed to cancel, or an ID of 0 if there is not 00724 * enough memory to allocate the event. 00725 * Returned ID remains valid until event has finished 00726 * executing. 00727 * 00728 * @code 00729 * #include "mbed.h" 00730 * 00731 * int main() 00732 * { 00733 * EventQueue queue; 00734 * 00735 * Callback<void(int)> cb(handler); 00736 * 00737 * // Create event on the eventqueue with a separate callback object 00738 * Event<void(int)> e = queue.event(cb); 00739 * e.post(1); 00740 * queue.dispatch(); 00741 * } 00742 * @endcode 00743 */ 00744 template <typename F> 00745 int call(F f) 00746 { 00747 void *p = equeue_alloc(&_equeue, sizeof(F)); 00748 if (!p) { 00749 return 0; 00750 } 00751 00752 F *e = new (p) F(f); 00753 equeue_event_dtor(e, &EventQueue::function_dtor<F>); 00754 return equeue_post(&_equeue, &EventQueue::function_call<F>, e); 00755 } 00756 00757 00758 /** Calls an event on the queue 00759 * @see EventQueue::call 00760 * @param f Function to execute in the context of the dispatch loop 00761 * @param args Arguments to pass to the callback 00762 */ 00763 template <typename F, typename... ArgTs> 00764 int call(F f, ArgTs... args) 00765 { 00766 return call(context<F, ArgTs...>(f, args...)); 00767 } 00768 00769 /** Calls an event on the queue 00770 * @see EventQueue::call 00771 */ 00772 template <typename T, typename R, typename... ArgTs> 00773 int call(T *obj, R(T::*method)(ArgTs...), ArgTs... args) 00774 { 00775 return call(mbed::callback(obj, method), args...); 00776 } 00777 00778 /** Calls an event on the queue 00779 * @see EventQueue::call 00780 */ 00781 template <typename T, typename R, typename... ArgTs> 00782 int call(const T *obj, R(T::*method)(ArgTs...) const, ArgTs... args) 00783 { 00784 return call(mbed::callback(obj, method), args...); 00785 } 00786 00787 /** Calls an event on the queue 00788 * @see EventQueue::call 00789 */ 00790 template <typename T, typename R, typename... ArgTs> 00791 int call(volatile T *obj, R(T::*method)(ArgTs...) volatile, ArgTs... args) 00792 { 00793 return call(mbed::callback(obj, method), args...); 00794 } 00795 00796 /** Calls an event on the queue 00797 * @see EventQueue::call 00798 */ 00799 template <typename T, typename R, typename... ArgTs> 00800 int call(const volatile T *obj, R(T::*method)(ArgTs...) const volatile, ArgTs... args) 00801 { 00802 return call(mbed::callback(obj, method), args...); 00803 } 00804 00805 /** Calls an event on the queue after a specified delay 00806 * 00807 * The specified callback will be executed in the context of the event 00808 * queue's dispatch loop. 00809 * 00810 * The call_in function is IRQ safe and can act as a mechanism for moving 00811 * events out of IRQ contexts. 00812 * 00813 * @param ms Time to delay in milliseconds 00814 * @param f Function to execute in the context of the dispatch loop 00815 * @return A unique id that represents the posted event and can 00816 * be passed to cancel, or an id of 0 if there is not 00817 * enough memory to allocate the event. 00818 */ 00819 template <typename F> 00820 int call_in(int ms, F f) 00821 { 00822 void *p = equeue_alloc(&_equeue, sizeof(F)); 00823 if (!p) { 00824 return 0; 00825 } 00826 00827 F *e = new (p) F(f); 00828 equeue_event_delay(e, ms); 00829 equeue_event_dtor(e, &EventQueue::function_dtor<F>); 00830 return equeue_post(&_equeue, &EventQueue::function_call<F>, e); 00831 } 00832 00833 /** Calls an event on the queue after a specified delay 00834 * @see EventQueue::call_in 00835 * @param ms Time to delay in milliseconds 00836 * @param f Function to execute in the context of the dispatch loop 00837 * @param args Arguments to pass to the callback 00838 */ 00839 template <typename F, typename... ArgTs> 00840 int call_in(int ms, F f, ArgTs... args) 00841 { 00842 return call_in(ms, context<F, ArgTs...>(f, args...)); 00843 } 00844 00845 /** Calls an event on the queue after a specified delay 00846 * @see EventQueue::call_in 00847 */ 00848 template <typename T, typename R, typename... ArgTs> 00849 int call_in(int ms, T *obj, R(T::*method)(ArgTs...), ArgTs... args) 00850 { 00851 return call_in(ms, mbed::callback(obj, method), args...); 00852 } 00853 00854 /** Calls an event on the queue after a specified delay 00855 * @see EventQueue::call_in 00856 */ 00857 template <typename T, typename R, typename... ArgTs> 00858 int call_in(int ms, const T *obj, R(T::*method)(ArgTs...) const, ArgTs... args) 00859 { 00860 return call_in(ms, mbed::callback(obj, method), args...); 00861 } 00862 00863 /** Calls an event on the queue after a specified delay 00864 * @see EventQueue::call_in 00865 */ 00866 template <typename T, typename R, typename... ArgTs> 00867 int call_in(int ms, volatile T *obj, R(T::*method)(ArgTs...) volatile, ArgTs... args) 00868 { 00869 return call_in(ms, mbed::callback(obj, method), args...); 00870 } 00871 00872 /** Calls an event on the queue after a specified delay 00873 * @see EventQueue::call_in 00874 */ 00875 template <typename T, typename R, typename... ArgTs> 00876 int call_in(int ms, const volatile T *obj, R(T::*method)(ArgTs...) const volatile, ArgTs... args) 00877 { 00878 return call_in(ms, mbed::callback(obj, method), args...); 00879 } 00880 00881 /** Calls an event on the queue periodically 00882 * 00883 * @note The first call_every event occurs after the specified delay. 00884 * To create a periodic event that fires immediately, @see Event. 00885 * 00886 * The specified callback will be executed in the context of the event 00887 * queue's dispatch loop. 00888 * 00889 * The call_every function is IRQ safe and can act as a mechanism for 00890 * moving events out of IRQ contexts. 00891 * 00892 * @param f Function to execute in the context of the dispatch loop 00893 * @param ms Period of the event in milliseconds 00894 * @return A unique id that represents the posted event and can 00895 * be passed to cancel, or an id of 0 if there is not 00896 * enough memory to allocate the event. 00897 */ 00898 template <typename F> 00899 int call_every(int ms, F f) 00900 { 00901 void *p = equeue_alloc(&_equeue, sizeof(F)); 00902 if (!p) { 00903 return 0; 00904 } 00905 00906 F *e = new (p) F(f); 00907 equeue_event_delay(e, ms); 00908 equeue_event_period(e, ms); 00909 equeue_event_dtor(e, &EventQueue::function_dtor<F>); 00910 return equeue_post(&_equeue, &EventQueue::function_call<F>, e); 00911 } 00912 00913 /** Calls an event on the queue periodically 00914 * @see EventQueue::call_every 00915 * @param f Function to execute in the context of the dispatch loop 00916 * @param args Arguments to pass to the callback 00917 * @param ms Period of the event in milliseconds 00918 */ 00919 template <typename F, typename... ArgTs> 00920 int call_every(int ms, F f, ArgTs... args) 00921 { 00922 return call_every(ms, context<F, ArgTs...>(f, args...)); 00923 } 00924 00925 /** Calls an event on the queue periodically 00926 * @see EventQueue::call_every 00927 */ 00928 template <typename T, typename R, typename... ArgTs> 00929 int call_every(int ms, T *obj, R(T::*method)(ArgTs...), ArgTs... args) 00930 { 00931 return call_every(ms, mbed::callback(obj, method), args...); 00932 } 00933 00934 /** Calls an event on the queue periodically 00935 * @see EventQueue::call_every 00936 */ 00937 template <typename T, typename R, typename... ArgTs> 00938 int call_every(int ms, const T *obj, R(T::*method)(ArgTs...) const, ArgTs... args) 00939 { 00940 return call_every(ms, mbed::callback(obj, method), args...); 00941 } 00942 00943 /** Calls an event on the queue periodically 00944 * @see EventQueue::call_every 00945 */ 00946 template <typename T, typename R, typename... ArgTs> 00947 int call_every(int ms, volatile T *obj, R(T::*method)(ArgTs...) volatile, ArgTs... args) 00948 { 00949 return call_every(ms, mbed::callback(obj, method), args...); 00950 } 00951 00952 /** Calls an event on the queue periodically 00953 * @see EventQueue::call_every 00954 */ 00955 template <typename T, typename R, typename... ArgTs> 00956 int call_every(int ms, const volatile T *obj, R(T::*method)(ArgTs...) const volatile, ArgTs... args) 00957 { 00958 return call_every(ms, mbed::callback(obj, method), args...); 00959 } 00960 00961 /** Creates an event bound to the event queue 00962 * 00963 * Constructs an event bound to the specified event queue. The specified 00964 * callback acts as the target for the event and is executed in the 00965 * context of the event queue's dispatch loop once posted. 00966 * 00967 * @param func Function to execute when the event is dispatched 00968 * @return Event that will dispatch on the specific queue 00969 */ 00970 template <typename R, typename... ArgTs> 00971 Event<void(ArgTs...)> event(R(*func)(ArgTs...)); 00972 00973 /** Creates an event bound to the event queue 00974 * @see EventQueue::event 00975 */ 00976 template <typename T, typename R, typename... ArgTs> 00977 Event<void(ArgTs...)> event(T *obj, R(T::*method)(ArgTs...)); 00978 00979 /** Creates an event bound to the event queue 00980 * @see EventQueue::event 00981 */ 00982 template <typename T, typename R, typename... ArgTs> 00983 Event<void(ArgTs...)> event(const T *obj, R(T::*method)(ArgTs...) const); 00984 00985 /** Creates an event bound to the event queue 00986 * @see EventQueue::event 00987 */ 00988 template <typename T, typename R, typename... ArgTs> 00989 Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(ArgTs...) volatile); 00990 00991 /** Creates an event bound to the event queue 00992 * @see EventQueue::event 00993 */ 00994 template <typename T, typename R, typename... ArgTs> 00995 Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(ArgTs...) const volatile); 00996 00997 /** Creates an event bound to the event queue 00998 * @see EventQueue::event 00999 */ 01000 template <typename R, typename... ArgTs> 01001 Event<void(ArgTs...)> event(mbed::Callback<R(ArgTs...)> cb); 01002 01003 /** Creates an event bound to the event queue 01004 * @see EventQueue::event 01005 */ 01006 template <typename R, typename B0, typename C0, typename... ArgTs> 01007 Event<void(ArgTs...)> event(R(*func)(B0, ArgTs...), C0 c0); 01008 01009 /** Creates an event bound to the event queue 01010 * @see EventQueue::event 01011 */ 01012 template <typename T, typename R, typename B0, typename C0, typename... ArgTs> 01013 Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, ArgTs...), C0 c0); 01014 01015 /** Creates an event bound to the event queue 01016 * @see EventQueue::event 01017 */ 01018 template <typename T, typename R, typename B0, typename C0, typename... ArgTs> 01019 Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, ArgTs...) const, C0 c0); 01020 01021 /** Creates an event bound to the event queue 01022 * @see EventQueue::event 01023 */ 01024 template <typename T, typename R, typename B0, typename C0, typename... ArgTs> 01025 Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, ArgTs...) volatile, C0 c0); 01026 01027 /** Creates an event bound to the event queue 01028 * @see EventQueue::event 01029 */ 01030 template <typename T, typename R, typename B0, typename C0, typename... ArgTs> 01031 Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, ArgTs...) const volatile, C0 c0); 01032 01033 /** Creates an event bound to the event queue 01034 * @see EventQueue::event 01035 */ 01036 template <typename R, typename B0, typename C0, typename... ArgTs> 01037 Event<void(ArgTs...)> event(mbed::Callback<R(B0, ArgTs...)> cb, C0 c0); 01038 01039 /** Creates an event bound to the event queue 01040 * @see EventQueue::event 01041 */ 01042 template <typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs> 01043 Event<void(ArgTs...)> event(R(*func)(B0, B1, ArgTs...), C0 c0, C1 c1); 01044 01045 /** Creates an event bound to the event queue 01046 * @see EventQueue::event 01047 */ 01048 template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs> 01049 Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, ArgTs...), C0 c0, C1 c1); 01050 01051 /** Creates an event bound to the event queue 01052 * @see EventQueue::event 01053 */ 01054 template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs> 01055 Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, ArgTs...) const, C0 c0, C1 c1); 01056 01057 /** Creates an event bound to the event queue 01058 * @see EventQueue::event 01059 */ 01060 template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs> 01061 Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, ArgTs...) volatile, C0 c0, C1 c1); 01062 01063 /** Creates an event bound to the event queue 01064 * @see EventQueue::event 01065 */ 01066 template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs> 01067 Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, ArgTs...) const volatile, C0 c0, C1 c1); 01068 01069 /** Creates an event bound to the event queue 01070 * @see EventQueue::event 01071 */ 01072 template <typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs> 01073 Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, ArgTs...)> cb, C0 c0, C1 c1); 01074 01075 /** Creates an event bound to the event queue 01076 * @see EventQueue::event 01077 */ 01078 template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs> 01079 Event<void(ArgTs...)> event(R(*func)(B0, B1, B2, ArgTs...), C0 c0, C1 c1, C2 c2); 01080 01081 /** Creates an event bound to the event queue 01082 * @see EventQueue::event 01083 */ 01084 template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs> 01085 Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, B2, ArgTs...), C0 c0, C1 c1, C2 c2); 01086 01087 /** Creates an event bound to the event queue 01088 * @see EventQueue::event 01089 */ 01090 template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs> 01091 Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const, C0 c0, C1 c1, C2 c2); 01092 01093 /** Creates an event bound to the event queue 01094 * @see EventQueue::event 01095 */ 01096 template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs> 01097 Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) volatile, C0 c0, C1 c1, C2 c2); 01098 01099 /** Creates an event bound to the event queue 01100 * @see EventQueue::event 01101 */ 01102 template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs> 01103 Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2); 01104 01105 /** Creates an event bound to the event queue 01106 * @see EventQueue::event 01107 */ 01108 template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs> 01109 Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, B2, ArgTs...)> cb, C0 c0, C1 c1, C2 c2); 01110 01111 /** Creates an event bound to the event queue 01112 * @see EventQueue::event 01113 */ 01114 template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs> 01115 Event<void(ArgTs...)> event(R(*func)(B0, B1, B2, B3, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3); 01116 01117 /** Creates an event bound to the event queue 01118 * @see EventQueue::event 01119 */ 01120 template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs> 01121 Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3); 01122 01123 /** Creates an event bound to the event queue 01124 * @see EventQueue::event 01125 */ 01126 template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs> 01127 Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) const, C0 c0, C1 c1, C2 c2, C3 c3); 01128 01129 /** Creates an event bound to the event queue 01130 * @see EventQueue::event 01131 */ 01132 template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs> 01133 Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) volatile, C0 c0, C1 c1, C2 c2, C3 c3); 01134 01135 /** Creates an event bound to the event queue 01136 * @see EventQueue::event 01137 */ 01138 template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs> 01139 Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2, C3 c3); 01140 01141 /** Creates an event bound to the event queue 01142 * @see EventQueue::event 01143 */ 01144 template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs> 01145 Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, B2, B3, ArgTs...)> cb, C0 c0, C1 c1, C2 c2, C3 c3); 01146 01147 /** Creates an event bound to the event queue 01148 * @see EventQueue::event 01149 */ 01150 template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs> 01151 Event<void(ArgTs...)> event(R(*func)(B0, B1, B2, B3, B4, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); 01152 01153 /** Creates an event bound to the event queue 01154 * @see EventQueue::event 01155 */ 01156 template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs> 01157 Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); 01158 01159 /** Creates an event bound to the event queue 01160 * @see EventQueue::event 01161 */ 01162 template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs> 01163 Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); 01164 01165 /** Creates an event bound to the event queue 01166 * @see EventQueue::event 01167 */ 01168 template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs> 01169 Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); 01170 01171 /** Creates an event bound to the event queue 01172 * @see EventQueue::event 01173 */ 01174 template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs> 01175 Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); 01176 01177 /** Creates an event bound to the event queue 01178 * @see EventQueue::event 01179 */ 01180 template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs> 01181 Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, B2, B3, B4, ArgTs...)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); 01182 01183 /** Creates an user allocated event bound to the event queue 01184 * 01185 * Constructs an user allocated event bound to the specified event queue. 01186 * The specified callback acts as the target for the event and is executed 01187 * in the context of the event queue's dispatch loop once posted. 01188 * 01189 * @param f Function to execute when the event is dispatched 01190 * @return Event that will dispatch on the specific queue 01191 */ 01192 template <typename F, typename... ArgTs> 01193 UserAllocatedEvent<F, void(ArgTs...)> make_user_allocated_event(F f, ArgTs... args); 01194 01195 /** Creates an user allocated event bound to the event queue 01196 * @see EventQueue::make_user_allocated_event 01197 */ 01198 template <typename T, typename R, typename... ArgTs> 01199 UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(T *obj, R(T::*method)(ArgTs... args), ArgTs... args); 01200 01201 /** Creates an user allocated event bound to the event queue 01202 * @see EventQueue::make_user_allocated_event 01203 */ 01204 template <typename T, typename R, typename... ArgTs> 01205 UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(const T *obj, R(T::*method)(ArgTs... args) const, ArgTs... args); 01206 01207 /** Creates an user allocated event bound to the event queue 01208 * @see EventQueue::make_user_allocated_event 01209 */ 01210 template <typename T, typename R, typename... ArgTs> 01211 UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(volatile T *obj, R(T::*method)(ArgTs... args) volatile, ArgTs... args); 01212 01213 /** Creates an user allocated event bound to the event queue 01214 * @see EventQueue::make_user_allocated_event 01215 */ 01216 template <typename T, typename R, typename... ArgTs> 01217 UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(const volatile T *obj, R(T::*method)(ArgTs... args) const volatile, ArgTs... args); 01218 #endif 01219 01220 protected: 01221 #if !defined(DOXYGEN_ONLY) 01222 template <typename F> 01223 friend class Event; 01224 template <typename F, typename A> 01225 friend class UserAllocatedEvent; 01226 struct equeue _equeue; 01227 mbed::Callback<void(int)> _update; 01228 01229 // Function attributes 01230 template <typename F> 01231 static void function_call(void *p) 01232 { 01233 (*(F *)p)(); 01234 } 01235 01236 template <typename F> 01237 static void function_dtor(void *p) 01238 { 01239 ((F *)p)->~F(); 01240 } 01241 01242 // Context structures 01243 template <typename F, typename... ContextArgTs> 01244 struct context; 01245 01246 template <typename F> 01247 struct context<F> { 01248 F f; 01249 01250 constexpr context(F f) 01251 : f(f) {} 01252 01253 template <typename... ArgTs> 01254 void operator()(ArgTs... args) 01255 { 01256 f(args...); 01257 } 01258 }; 01259 01260 template <typename F, typename C0> 01261 struct context<F, C0> { 01262 F f; 01263 C0 c0; 01264 01265 constexpr context(F f, C0 c0) 01266 : f(f), c0(c0) {} 01267 01268 template <typename... ArgTs> 01269 void operator()(ArgTs... args) 01270 { 01271 f(c0, args...); 01272 } 01273 }; 01274 01275 template <typename F, typename C0, typename C1> 01276 struct context<F, C0, C1> { 01277 F f; 01278 C0 c0; 01279 C1 c1; 01280 01281 constexpr context(F f, C0 c0, C1 c1) 01282 : f(f), c0(c0), c1(c1) {} 01283 01284 template <typename... ArgTs> 01285 void operator()(ArgTs... args) 01286 { 01287 f(c0, c1, args...); 01288 } 01289 }; 01290 01291 template <typename F, typename C0, typename C1, typename C2> 01292 struct context<F, C0, C1, C2> { 01293 F f; 01294 C0 c0; 01295 C1 c1; 01296 C2 c2; 01297 01298 constexpr context(F f, C0 c0, C1 c1, C2 c2) 01299 : f(f), c0(c0), c1(c1), c2(c2) {} 01300 01301 template <typename... ArgTs> 01302 void operator()(ArgTs... args) 01303 { 01304 f(c0, c1, c2, args...); 01305 } 01306 }; 01307 01308 template <typename F, typename C0, typename C1, typename C2, typename C3> 01309 struct context<F, C0, C1, C2, C3> { 01310 F f; 01311 C0 c0; 01312 C1 c1; 01313 C2 c2; 01314 C3 c3; 01315 01316 constexpr context(F f, C0 c0, C1 c1, C2 c2, C3 c3) 01317 : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} 01318 01319 template <typename... ArgTs> 01320 void operator()(ArgTs... args) 01321 { 01322 f(c0, c1, c2, c3, args...); 01323 } 01324 }; 01325 01326 template <typename F, typename C0, typename C1, typename C2, typename C3, typename C4> 01327 struct context<F, C0, C1, C2, C3, C4> { 01328 F f; 01329 C0 c0; 01330 C1 c1; 01331 C2 c2; 01332 C3 c3; 01333 C4 c4; 01334 01335 constexpr context(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) 01336 : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} 01337 01338 template <typename... ArgTs> 01339 void operator()(ArgTs... args) 01340 { 01341 f(c0, c1, c2, c3, c4, args...); 01342 } 01343 }; 01344 #endif //!defined(DOXYGEN_ONLY) 01345 }; 01346 01347 /** @}*/ 01348 /** @}*/ 01349 01350 } 01351 01352 #endif
Generated on Tue Jul 12 2022 13:54:19 by
