Ram Gandikota / Mbed OS ABCD
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FunctionPointerBind.h Source File

FunctionPointerBind.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef MBED_FUNCTIONPOINTERBIND_H__
00018 #define MBED_FUNCTIONPOINTERBIND_H__
00019 
00020 #include <string.h>
00021 #include <stdint.h>
00022 #include <stddef.h>
00023 #include <stdarg.h>
00024 #include <assert.h>
00025 #include "FunctionPointerBase.h"
00026 
00027 #ifndef EVENT_STORAGE_SIZE
00028 #define EVENT_STORAGE_SIZE 32
00029 #endif
00030 
00031 #define MBED_STATIC_ASSERT(MBED_STATIC_ASSERT_FAILED,MSG)\
00032     switch(0){\
00033         case 0:case (MBED_STATIC_ASSERT_FAILED): \
00034         break;}
00035 
00036 namespace mbed{
00037 
00038 template<typename R>
00039 class FunctionPointerBind : public FunctionPointerBase<R> {
00040 public:
00041     // Call the Event
00042     inline R call() {
00043         return FunctionPointerBase<R>::call(static_cast<void *>(_storage));
00044     }
00045     FunctionPointerBind():
00046         FunctionPointerBase<R>(),
00047         _ops(&FunctionPointerBase<R>::_nullops)
00048     {}
00049 
00050     FunctionPointerBind(const FunctionPointerBind<R> & fp):
00051         FunctionPointerBase<R>(),
00052         _ops(&FunctionPointerBase<R>::_nullops) {
00053         *this = fp;
00054     }
00055 
00056     virtual ~FunctionPointerBind() {
00057         _ops->destructor(_storage);
00058     }
00059 
00060     FunctionPointerBind<R> & operator=(const FunctionPointerBind<R>& rhs) {
00061         if (_ops != &FunctionPointerBase<R>::_nullops) {
00062             _ops->destructor(_storage);
00063         }
00064         FunctionPointerBase<R>::copy(&rhs);
00065         _ops = rhs._ops;
00066         _ops->copy_args(_storage, (void *)rhs._storage);
00067         return *this;
00068     }
00069 
00070     /**
00071      * Clears the current binding, making this instance unbound
00072      */
00073     virtual void clear() {
00074         if (_ops != &FunctionPointerBase<R>::_nullops) {
00075             _ops->destructor(_storage);
00076         }
00077         _ops = &FunctionPointerBase<R>::_nullops;
00078         FunctionPointerBase<R>::clear();
00079     }
00080 
00081     template<typename S>
00082     FunctionPointerBind<R> & bind(const struct FunctionPointerBase<R>::ArgOps * ops , S * argStruct, FunctionPointerBase<R> *fp, ...) {
00083         MBED_STATIC_ASSERT(sizeof(S) <= sizeof(_storage), ERROR: Arguments too large for FunctionPointerBind internal storage)
00084         if (_ops != &FunctionPointerBase<R>::_nullops) {
00085             _ops->destructor(_storage);
00086         }
00087         _ops = ops;
00088         FunctionPointerBase<R>::copy(fp);
00089         assert(this->_ops != NULL);
00090         assert(this->_ops->constructor != NULL);
00091         if (argStruct) {
00092             this->_ops->copy_args(this->_storage, (void *)argStruct);
00093         } else {
00094             va_list args;
00095             va_start(args, fp);
00096             this->_ops->constructor(_storage, args);
00097             va_end(args);
00098         }
00099         return *this;
00100     }
00101 
00102     R operator()() {
00103         return call();
00104     }
00105 
00106 protected:
00107     const struct FunctionPointerBase<R>::ArgOps * _ops;
00108     uint32_t _storage[(EVENT_STORAGE_SIZE+sizeof(uint32_t)-1)/sizeof(uint32_t)];
00109 };
00110 }
00111 
00112 #endif // MBED_FUNCTIONPOINTERBIND_H__