pro vyuku PSS v Jecne

Committer:
vladvana
Date:
Sun Sep 24 12:31:52 2017 +0000
Revision:
0:23d1f73bf130
podklady pro cviceni z PSS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vladvana 0:23d1f73bf130 1 /* mbed Microcontroller Library
vladvana 0:23d1f73bf130 2 * Copyright (c) 2006-2015 ARM Limited
vladvana 0:23d1f73bf130 3 *
vladvana 0:23d1f73bf130 4 * Licensed under the Apache License, Version 2.0 (the "License");
vladvana 0:23d1f73bf130 5 * you may not use this file except in compliance with the License.
vladvana 0:23d1f73bf130 6 * You may obtain a copy of the License at
vladvana 0:23d1f73bf130 7 *
vladvana 0:23d1f73bf130 8 * http://www.apache.org/licenses/LICENSE-2.0
vladvana 0:23d1f73bf130 9 *
vladvana 0:23d1f73bf130 10 * Unless required by applicable law or agreed to in writing, software
vladvana 0:23d1f73bf130 11 * distributed under the License is distributed on an "AS IS" BASIS,
vladvana 0:23d1f73bf130 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vladvana 0:23d1f73bf130 13 * See the License for the specific language governing permissions and
vladvana 0:23d1f73bf130 14 * limitations under the License.
vladvana 0:23d1f73bf130 15 */
vladvana 0:23d1f73bf130 16 #ifndef MBED_FUNCTIONPOINTER_H
vladvana 0:23d1f73bf130 17 #define MBED_FUNCTIONPOINTER_H
vladvana 0:23d1f73bf130 18
vladvana 0:23d1f73bf130 19 #include <string.h>
vladvana 0:23d1f73bf130 20 #include <stdint.h>
vladvana 0:23d1f73bf130 21
vladvana 0:23d1f73bf130 22 namespace mbed {
vladvana 0:23d1f73bf130 23
vladvana 0:23d1f73bf130 24 /* If we had variaditic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */
vladvana 0:23d1f73bf130 25
vladvana 0:23d1f73bf130 26 /** A class for storing and calling a pointer to a static or member function
vladvana 0:23d1f73bf130 27 */
vladvana 0:23d1f73bf130 28 template <typename R, typename A1>
vladvana 0:23d1f73bf130 29 class FunctionPointerArg1{
vladvana 0:23d1f73bf130 30 public:
vladvana 0:23d1f73bf130 31 /** Create a FunctionPointer, attaching a static function
vladvana 0:23d1f73bf130 32 *
vladvana 0:23d1f73bf130 33 * @param function The static function to attach (default is none)
vladvana 0:23d1f73bf130 34 */
vladvana 0:23d1f73bf130 35 FunctionPointerArg1(R (*function)(A1) = 0) {
vladvana 0:23d1f73bf130 36 attach(function);
vladvana 0:23d1f73bf130 37 }
vladvana 0:23d1f73bf130 38
vladvana 0:23d1f73bf130 39 /** Create a FunctionPointer, attaching a member function
vladvana 0:23d1f73bf130 40 *
vladvana 0:23d1f73bf130 41 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
vladvana 0:23d1f73bf130 42 * @param function The address of the member function to attach
vladvana 0:23d1f73bf130 43 */
vladvana 0:23d1f73bf130 44 template<typename T>
vladvana 0:23d1f73bf130 45 FunctionPointerArg1(T *object, R (T::*member)(A1)) {
vladvana 0:23d1f73bf130 46 attach(object, member);
vladvana 0:23d1f73bf130 47 }
vladvana 0:23d1f73bf130 48
vladvana 0:23d1f73bf130 49 /** Attach a static function
vladvana 0:23d1f73bf130 50 *
vladvana 0:23d1f73bf130 51 * @param function The static function to attach (default is none)
vladvana 0:23d1f73bf130 52 */
vladvana 0:23d1f73bf130 53 void attach(R (*function)(A1)) {
vladvana 0:23d1f73bf130 54 _p.function = function;
vladvana 0:23d1f73bf130 55 _membercaller = 0;
vladvana 0:23d1f73bf130 56 }
vladvana 0:23d1f73bf130 57
vladvana 0:23d1f73bf130 58 /** Attach a member function
vladvana 0:23d1f73bf130 59 *
vladvana 0:23d1f73bf130 60 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
vladvana 0:23d1f73bf130 61 * @param function The address of the member function to attach
vladvana 0:23d1f73bf130 62 */
vladvana 0:23d1f73bf130 63 template<typename T>
vladvana 0:23d1f73bf130 64 void attach(T *object, R (T::*member)(A1)) {
vladvana 0:23d1f73bf130 65 _p.object = static_cast<void*>(object);
vladvana 0:23d1f73bf130 66 *reinterpret_cast<R (T::**)(A1)>(_member) = member;
vladvana 0:23d1f73bf130 67 _membercaller = &FunctionPointerArg1::membercaller<T>;
vladvana 0:23d1f73bf130 68 }
vladvana 0:23d1f73bf130 69
vladvana 0:23d1f73bf130 70 /** Call the attached static or member function
vladvana 0:23d1f73bf130 71 */
vladvana 0:23d1f73bf130 72 R call(A1 a) {
vladvana 0:23d1f73bf130 73 if (_membercaller == 0 && _p.function) {
vladvana 0:23d1f73bf130 74 return _p.function(a);
vladvana 0:23d1f73bf130 75 } else if (_membercaller && _p.object) {
vladvana 0:23d1f73bf130 76 return _membercaller(_p.object, _member, a);
vladvana 0:23d1f73bf130 77 }
vladvana 0:23d1f73bf130 78 return (R)0;
vladvana 0:23d1f73bf130 79 }
vladvana 0:23d1f73bf130 80
vladvana 0:23d1f73bf130 81 /** Get registered static function
vladvana 0:23d1f73bf130 82 */
vladvana 0:23d1f73bf130 83 R(*get_function(A1))() {
vladvana 0:23d1f73bf130 84 return _membercaller ? (R(*)(A1))0 : (R(*)(A1))_p.function;
vladvana 0:23d1f73bf130 85 }
vladvana 0:23d1f73bf130 86
vladvana 0:23d1f73bf130 87 #ifdef MBED_OPERATORS
vladvana 0:23d1f73bf130 88 R operator ()(A1 a) {
vladvana 0:23d1f73bf130 89 return call(a);
vladvana 0:23d1f73bf130 90 }
vladvana 0:23d1f73bf130 91 operator bool(void) const {
vladvana 0:23d1f73bf130 92 return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
vladvana 0:23d1f73bf130 93 }
vladvana 0:23d1f73bf130 94 #endif
vladvana 0:23d1f73bf130 95 private:
vladvana 0:23d1f73bf130 96 template<typename T>
vladvana 0:23d1f73bf130 97 static R membercaller(void *object, uintptr_t *member, A1 a) {
vladvana 0:23d1f73bf130 98 T* o = static_cast<T*>(object);
vladvana 0:23d1f73bf130 99 R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member);
vladvana 0:23d1f73bf130 100 return (o->**m)(a);
vladvana 0:23d1f73bf130 101 }
vladvana 0:23d1f73bf130 102
vladvana 0:23d1f73bf130 103 union {
vladvana 0:23d1f73bf130 104 R (*function)(A1); // static function pointer
vladvana 0:23d1f73bf130 105 void *object; // object this pointer
vladvana 0:23d1f73bf130 106 } _p;
vladvana 0:23d1f73bf130 107 uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
vladvana 0:23d1f73bf130 108 R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object
vladvana 0:23d1f73bf130 109 };
vladvana 0:23d1f73bf130 110
vladvana 0:23d1f73bf130 111 /** A class for storing and calling a pointer to a static or member function (R ()(void))
vladvana 0:23d1f73bf130 112 */
vladvana 0:23d1f73bf130 113 template <typename R>
vladvana 0:23d1f73bf130 114 class FunctionPointerArg1<R, void>{
vladvana 0:23d1f73bf130 115 public:
vladvana 0:23d1f73bf130 116 /** Create a FunctionPointer, attaching a static function
vladvana 0:23d1f73bf130 117 *
vladvana 0:23d1f73bf130 118 * @param function The static function to attach (default is none)
vladvana 0:23d1f73bf130 119 */
vladvana 0:23d1f73bf130 120 FunctionPointerArg1(R (*function)(void) = 0) {
vladvana 0:23d1f73bf130 121 attach(function);
vladvana 0:23d1f73bf130 122 }
vladvana 0:23d1f73bf130 123
vladvana 0:23d1f73bf130 124 /** Create a FunctionPointer, attaching a member function
vladvana 0:23d1f73bf130 125 *
vladvana 0:23d1f73bf130 126 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
vladvana 0:23d1f73bf130 127 * @param function The address of the void member function to attach
vladvana 0:23d1f73bf130 128 */
vladvana 0:23d1f73bf130 129 template<typename T>
vladvana 0:23d1f73bf130 130 FunctionPointerArg1(T *object, R (T::*member)(void)) {
vladvana 0:23d1f73bf130 131 attach(object, member);
vladvana 0:23d1f73bf130 132 }
vladvana 0:23d1f73bf130 133
vladvana 0:23d1f73bf130 134 /** Attach a static function
vladvana 0:23d1f73bf130 135 *
vladvana 0:23d1f73bf130 136 * @param function The void static function to attach (default is none)
vladvana 0:23d1f73bf130 137 */
vladvana 0:23d1f73bf130 138 void attach(R (*function)(void)) {
vladvana 0:23d1f73bf130 139 _p.function = function;
vladvana 0:23d1f73bf130 140 _membercaller = 0;
vladvana 0:23d1f73bf130 141 }
vladvana 0:23d1f73bf130 142
vladvana 0:23d1f73bf130 143 /** Attach a member function
vladvana 0:23d1f73bf130 144 *
vladvana 0:23d1f73bf130 145 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
vladvana 0:23d1f73bf130 146 * @param function The address of the void member function to attach
vladvana 0:23d1f73bf130 147 */
vladvana 0:23d1f73bf130 148 template<typename T>
vladvana 0:23d1f73bf130 149 void attach(T *object, R (T::*member)(void)) {
vladvana 0:23d1f73bf130 150 _p.object = static_cast<void*>(object);
vladvana 0:23d1f73bf130 151 *reinterpret_cast<R (T::**)(void)>(_member) = member;
vladvana 0:23d1f73bf130 152 _membercaller = &FunctionPointerArg1::membercaller<T>;
vladvana 0:23d1f73bf130 153 }
vladvana 0:23d1f73bf130 154
vladvana 0:23d1f73bf130 155 /** Call the attached static or member function
vladvana 0:23d1f73bf130 156 */
vladvana 0:23d1f73bf130 157 R call(){
vladvana 0:23d1f73bf130 158 if (_membercaller == 0 && _p.function) {
vladvana 0:23d1f73bf130 159 return _p.function();
vladvana 0:23d1f73bf130 160 } else if (_membercaller && _p.object) {
vladvana 0:23d1f73bf130 161 return _membercaller(_p.object, _member);
vladvana 0:23d1f73bf130 162 }
vladvana 0:23d1f73bf130 163 return (R)0;
vladvana 0:23d1f73bf130 164 }
vladvana 0:23d1f73bf130 165
vladvana 0:23d1f73bf130 166 /** Get registered static function
vladvana 0:23d1f73bf130 167 */
vladvana 0:23d1f73bf130 168 R(*get_function())() {
vladvana 0:23d1f73bf130 169 return _membercaller ? (R(*)())0 : (R(*)())_p.function;
vladvana 0:23d1f73bf130 170 }
vladvana 0:23d1f73bf130 171
vladvana 0:23d1f73bf130 172 #ifdef MBED_OPERATORS
vladvana 0:23d1f73bf130 173 R operator ()(void) {
vladvana 0:23d1f73bf130 174 return call();
vladvana 0:23d1f73bf130 175 }
vladvana 0:23d1f73bf130 176 operator bool(void) const {
vladvana 0:23d1f73bf130 177 return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
vladvana 0:23d1f73bf130 178 }
vladvana 0:23d1f73bf130 179 #endif
vladvana 0:23d1f73bf130 180
vladvana 0:23d1f73bf130 181 private:
vladvana 0:23d1f73bf130 182 template<typename T>
vladvana 0:23d1f73bf130 183 static R membercaller(void *object, uintptr_t *member) {
vladvana 0:23d1f73bf130 184 T* o = static_cast<T*>(object);
vladvana 0:23d1f73bf130 185 R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member);
vladvana 0:23d1f73bf130 186 return (o->**m)();
vladvana 0:23d1f73bf130 187 }
vladvana 0:23d1f73bf130 188
vladvana 0:23d1f73bf130 189 union {
vladvana 0:23d1f73bf130 190 R (*function)(void); // static function pointer
vladvana 0:23d1f73bf130 191 void *object; // object this pointer
vladvana 0:23d1f73bf130 192 } _p;
vladvana 0:23d1f73bf130 193 uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
vladvana 0:23d1f73bf130 194 R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object
vladvana 0:23d1f73bf130 195 };
vladvana 0:23d1f73bf130 196
vladvana 0:23d1f73bf130 197 typedef FunctionPointerArg1<void, void> FunctionPointer;
vladvana 0:23d1f73bf130 198 typedef FunctionPointerArg1<void, int> event_callback_t;
vladvana 0:23d1f73bf130 199
vladvana 0:23d1f73bf130 200 } // namespace mbed
vladvana 0:23d1f73bf130 201
vladvana 0:23d1f73bf130 202 #endif