Roy Want / Mbed OS beaconCompileReadyFork
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Thunk.h Source File

Thunk.h

00001 /*
00002  * Copyright (c) 2016, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * 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, WITHOUT
00013  * 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 #ifndef EVENTQUEUE_THUNK_H_
00018 #define EVENTQUEUE_THUNK_H_
00019 
00020 #include "AlignedStorage.h"
00021 #include "detail/ThunkVTable.h"
00022 
00023 namespace eq {
00024 
00025 // forward declaration of ThunkVTableGenerator
00026 namespace detail {
00027 template<typename T>
00028 class ThunkVTableGenerator;
00029 }
00030 
00031 /**
00032  * A Thunk is a container holding any kind of nullary callable.
00033  * It wrap value semantic and function call operations of the inner callable
00034  * held.
00035  * \note Thunk of callable bound to arguments should be generated by the
00036  * function make_thunk.
00037  */
00038 class Thunk {
00039     // Size for the internal buffer of the Thunk
00040     static const std::size_t BufferSize = 24;
00041 
00042     template<typename T>
00043     friend class detail::ThunkVTableGenerator;
00044 
00045 public:
00046 
00047     /**
00048      * Thunk Empty constructor.
00049      * When this thunk is called, if does nothing.
00050      */
00051     Thunk();
00052 
00053     /**
00054      * Construct a Thunk from a nullary callable of type F.
00055      * When the call operator is invoked, it call a copy of f ( f() ).
00056      */
00057     template<typename F>
00058     Thunk(const F& f);
00059 
00060     /**
00061      * Special constructor for pointer to function.
00062      * Allow references to functions to gracefully decay into pointer to function.
00063      * Otherwise, reference to function are not copy constructible (their is no
00064      * constructible function type in C++).
00065      * When the call operator is invoked, it call a copy of f ( f() ).
00066      */
00067     Thunk(void (*f)());
00068 
00069     /**
00070      * Copy construction of a thunk.
00071      * Take care that the inner F is correctly copied.
00072      */
00073     Thunk(const Thunk& other) : _storage(), _vtable() {
00074         other._vtable->copy(*this, other);
00075     }
00076 
00077     /**
00078      * Destruction of the Thunk correctly call the destructor of the
00079      * inner callable.
00080      */
00081     ~Thunk() {
00082         _vtable->destroy(*this);
00083     }
00084 
00085     /**
00086      * Copy assignement from another thunk.
00087      * Ensure that the callable held is correctly destroyed then copy
00088      * the correctly copy the new one.
00089      */
00090     Thunk& operator=(const Thunk& other) {
00091         if (this == &other) {
00092             return *this;
00093         }
00094         _vtable->destroy(*this);
00095         other._vtable->copy(*this, other);
00096         return *this;
00097     }
00098 
00099     /**
00100      * Call operator. Invoke the inner callable.
00101      */
00102     void operator()() const {
00103         _vtable->call(*this);
00104     }
00105 
00106 private:
00107     static void empty_thunk() { }
00108 
00109     AlignedStorage<char[BufferSize]> _storage;
00110     const detail::ThunkVTable* _vtable;
00111 };
00112 
00113 } // namespace eq
00114 
00115 #include "detail/Thunk.impl.h"
00116 
00117 #endif  /* EVENTQUEUE_THUNK_H_ */