Ram Gandikota
/
ABCD
A metronome using the FRDM K64F board
mbed-client/test/mbedclient/utest/common/FunctionPointerBase.h@0:a7a43371b306, 2017-05-14 (annotated)
- Committer:
- ram54288
- Date:
- Sun May 14 18:40:18 2017 +0000
- Revision:
- 0:a7a43371b306
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ram54288 | 0:a7a43371b306 | 1 | /* mbed Microcontroller Library |
ram54288 | 0:a7a43371b306 | 2 | * Copyright (c) 2015 ARM Limited |
ram54288 | 0:a7a43371b306 | 3 | * |
ram54288 | 0:a7a43371b306 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
ram54288 | 0:a7a43371b306 | 5 | * you may not use this file except in compliance with the License. |
ram54288 | 0:a7a43371b306 | 6 | * You may obtain a copy of the License at |
ram54288 | 0:a7a43371b306 | 7 | * |
ram54288 | 0:a7a43371b306 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
ram54288 | 0:a7a43371b306 | 9 | * |
ram54288 | 0:a7a43371b306 | 10 | * Unless required by applicable law or agreed to in writing, software |
ram54288 | 0:a7a43371b306 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
ram54288 | 0:a7a43371b306 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
ram54288 | 0:a7a43371b306 | 13 | * See the License for the specific language governing permissions and |
ram54288 | 0:a7a43371b306 | 14 | * limitations under the License. |
ram54288 | 0:a7a43371b306 | 15 | */ |
ram54288 | 0:a7a43371b306 | 16 | #ifndef MBED_FUNCTIONPOINTERBASE_H |
ram54288 | 0:a7a43371b306 | 17 | #define MBED_FUNCTIONPOINTERBASE_H |
ram54288 | 0:a7a43371b306 | 18 | |
ram54288 | 0:a7a43371b306 | 19 | #include <string.h> |
ram54288 | 0:a7a43371b306 | 20 | #include <stdint.h> |
ram54288 | 0:a7a43371b306 | 21 | #include <stddef.h> |
ram54288 | 0:a7a43371b306 | 22 | #include <stdarg.h> |
ram54288 | 0:a7a43371b306 | 23 | namespace mbed { |
ram54288 | 0:a7a43371b306 | 24 | |
ram54288 | 0:a7a43371b306 | 25 | template<typename R> |
ram54288 | 0:a7a43371b306 | 26 | class FunctionPointerBase { |
ram54288 | 0:a7a43371b306 | 27 | public: |
ram54288 | 0:a7a43371b306 | 28 | operator bool(void) const { |
ram54288 | 0:a7a43371b306 | 29 | return (_membercaller != NULL) && (_object != NULL); |
ram54288 | 0:a7a43371b306 | 30 | } |
ram54288 | 0:a7a43371b306 | 31 | |
ram54288 | 0:a7a43371b306 | 32 | /** |
ram54288 | 0:a7a43371b306 | 33 | * Clears the current function pointer assignment |
ram54288 | 0:a7a43371b306 | 34 | * After clear(), this instance will point to nothing (NULL) |
ram54288 | 0:a7a43371b306 | 35 | */ |
ram54288 | 0:a7a43371b306 | 36 | virtual void clear() { |
ram54288 | 0:a7a43371b306 | 37 | _membercaller = NULL; |
ram54288 | 0:a7a43371b306 | 38 | _object = NULL; |
ram54288 | 0:a7a43371b306 | 39 | } |
ram54288 | 0:a7a43371b306 | 40 | |
ram54288 | 0:a7a43371b306 | 41 | protected: |
ram54288 | 0:a7a43371b306 | 42 | struct ArgOps { |
ram54288 | 0:a7a43371b306 | 43 | void (*constructor)(void *, va_list); |
ram54288 | 0:a7a43371b306 | 44 | void (*copy_args)(void *, void *); |
ram54288 | 0:a7a43371b306 | 45 | void (*destructor)(void *); |
ram54288 | 0:a7a43371b306 | 46 | }; |
ram54288 | 0:a7a43371b306 | 47 | void * _object; // object Pointer/function pointer |
ram54288 | 0:a7a43371b306 | 48 | R (*_membercaller)(void *, uintptr_t *, void *); |
ram54288 | 0:a7a43371b306 | 49 | // aligned raw member function pointer storage - converted back by registered _membercaller |
ram54288 | 0:a7a43371b306 | 50 | uintptr_t _member[4]; |
ram54288 | 0:a7a43371b306 | 51 | static const struct ArgOps _nullops; |
ram54288 | 0:a7a43371b306 | 52 | |
ram54288 | 0:a7a43371b306 | 53 | protected: |
ram54288 | 0:a7a43371b306 | 54 | FunctionPointerBase():_object(NULL), _membercaller(NULL) {} |
ram54288 | 0:a7a43371b306 | 55 | FunctionPointerBase(const FunctionPointerBase<R> & fp) { |
ram54288 | 0:a7a43371b306 | 56 | copy(&fp); |
ram54288 | 0:a7a43371b306 | 57 | } |
ram54288 | 0:a7a43371b306 | 58 | virtual ~FunctionPointerBase() { |
ram54288 | 0:a7a43371b306 | 59 | } |
ram54288 | 0:a7a43371b306 | 60 | |
ram54288 | 0:a7a43371b306 | 61 | /** |
ram54288 | 0:a7a43371b306 | 62 | * Calls the member pointed to by object::member or (function)object |
ram54288 | 0:a7a43371b306 | 63 | * @param arg |
ram54288 | 0:a7a43371b306 | 64 | * @return |
ram54288 | 0:a7a43371b306 | 65 | */ |
ram54288 | 0:a7a43371b306 | 66 | inline R call(void* arg) { |
ram54288 | 0:a7a43371b306 | 67 | return _membercaller(_object, _member, arg); |
ram54288 | 0:a7a43371b306 | 68 | } |
ram54288 | 0:a7a43371b306 | 69 | |
ram54288 | 0:a7a43371b306 | 70 | void copy(const FunctionPointerBase<R> * fp) { |
ram54288 | 0:a7a43371b306 | 71 | _object = fp->_object; |
ram54288 | 0:a7a43371b306 | 72 | memcpy (_member, fp->_member, sizeof(_member)); |
ram54288 | 0:a7a43371b306 | 73 | _membercaller = fp->_membercaller; |
ram54288 | 0:a7a43371b306 | 74 | } |
ram54288 | 0:a7a43371b306 | 75 | private: |
ram54288 | 0:a7a43371b306 | 76 | static void _null_constructor(void * dest, va_list args) {(void) dest;(void) args;} |
ram54288 | 0:a7a43371b306 | 77 | static void _null_copy_args(void *dest , void* src) {(void) dest; (void) src;} |
ram54288 | 0:a7a43371b306 | 78 | static void _null_destructor(void *args) {(void) args;} |
ram54288 | 0:a7a43371b306 | 79 | |
ram54288 | 0:a7a43371b306 | 80 | }; |
ram54288 | 0:a7a43371b306 | 81 | template<typename R> |
ram54288 | 0:a7a43371b306 | 82 | const struct FunctionPointerBase<R>::ArgOps FunctionPointerBase<R>::_nullops = { |
ram54288 | 0:a7a43371b306 | 83 | FunctionPointerBase<R>::_null_constructor, |
ram54288 | 0:a7a43371b306 | 84 | FunctionPointerBase<R>::_null_copy_args, |
ram54288 | 0:a7a43371b306 | 85 | FunctionPointerBase<R>::_null_destructor |
ram54288 | 0:a7a43371b306 | 86 | }; |
ram54288 | 0:a7a43371b306 | 87 | |
ram54288 | 0:a7a43371b306 | 88 | } |
ram54288 | 0:a7a43371b306 | 89 | #endif |