Extended MaximInterface

Dependents:   mbed_DS28EC20_GPIO

Committer:
reARMnimator
Date:
Mon Jan 06 15:54:55 2020 +0000
Revision:
10:de4b8812877d
Parent:
7:471901a04573
Fixed inappropriate include path.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 0:f77ad7f72d04 1 /*******************************************************************************
IanBenzMaxim 0:f77ad7f72d04 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 0:f77ad7f72d04 3 *
IanBenzMaxim 0:f77ad7f72d04 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 0:f77ad7f72d04 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 0:f77ad7f72d04 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 0:f77ad7f72d04 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 0:f77ad7f72d04 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 0:f77ad7f72d04 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 0:f77ad7f72d04 10 *
IanBenzMaxim 0:f77ad7f72d04 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 0:f77ad7f72d04 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 0:f77ad7f72d04 13 *
IanBenzMaxim 0:f77ad7f72d04 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 0:f77ad7f72d04 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 0:f77ad7f72d04 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 0:f77ad7f72d04 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 0:f77ad7f72d04 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 0:f77ad7f72d04 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 0:f77ad7f72d04 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 0:f77ad7f72d04 21 *
IanBenzMaxim 0:f77ad7f72d04 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 0:f77ad7f72d04 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 0:f77ad7f72d04 24 * Products, Inc. Branding Policy.
IanBenzMaxim 0:f77ad7f72d04 25 *
IanBenzMaxim 0:f77ad7f72d04 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 0:f77ad7f72d04 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 0:f77ad7f72d04 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 0:f77ad7f72d04 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 0:f77ad7f72d04 30 * ownership rights.
IanBenzMaxim 0:f77ad7f72d04 31 *******************************************************************************/
IanBenzMaxim 0:f77ad7f72d04 32
IanBenzMaxim 0:f77ad7f72d04 33 #ifndef MaximInterface_Function
IanBenzMaxim 0:f77ad7f72d04 34 #define MaximInterface_Function
IanBenzMaxim 0:f77ad7f72d04 35
IanBenzMaxim 0:f77ad7f72d04 36 #include <stddef.h>
IanBenzMaxim 6:a8c83a2e6fa4 37 #include "SafeBool.hpp"
IanBenzMaxim 0:f77ad7f72d04 38 #include "type_traits.hpp"
IanBenzMaxim 0:f77ad7f72d04 39
IanBenzMaxim 0:f77ad7f72d04 40 // Include for std::swap.
IanBenzMaxim 0:f77ad7f72d04 41 #include <algorithm>
IanBenzMaxim 0:f77ad7f72d04 42 #include <utility>
IanBenzMaxim 0:f77ad7f72d04 43
IanBenzMaxim 0:f77ad7f72d04 44 namespace MaximInterface {
IanBenzMaxim 0:f77ad7f72d04 45 namespace detail {
IanBenzMaxim 0:f77ad7f72d04 46
IanBenzMaxim 0:f77ad7f72d04 47 // Provides char buffer storage for a given type.
IanBenzMaxim 0:f77ad7f72d04 48 // Suitability of alignment for type should be verified with alignment_of.
IanBenzMaxim 0:f77ad7f72d04 49 template <typename Type, size_t TypeSize> union TypeStorage {
IanBenzMaxim 0:f77ad7f72d04 50 public:
IanBenzMaxim 0:f77ad7f72d04 51 operator const Type *() const { return reinterpret_cast<const Type *>(data); }
IanBenzMaxim 0:f77ad7f72d04 52
IanBenzMaxim 0:f77ad7f72d04 53 operator Type *() {
IanBenzMaxim 0:f77ad7f72d04 54 return const_cast<Type *>(
IanBenzMaxim 0:f77ad7f72d04 55 static_cast<const Type *>(static_cast<const TypeStorage &>(*this)));
IanBenzMaxim 0:f77ad7f72d04 56 }
IanBenzMaxim 0:f77ad7f72d04 57
IanBenzMaxim 0:f77ad7f72d04 58 const Type & operator*() const { return **this; }
IanBenzMaxim 0:f77ad7f72d04 59
IanBenzMaxim 0:f77ad7f72d04 60 Type & operator*() {
IanBenzMaxim 0:f77ad7f72d04 61 return const_cast<Type &>(
IanBenzMaxim 0:f77ad7f72d04 62 static_cast<const TypeStorage &>(*this).operator*());
IanBenzMaxim 0:f77ad7f72d04 63 }
IanBenzMaxim 0:f77ad7f72d04 64
IanBenzMaxim 0:f77ad7f72d04 65 const Type * operator->() const { return *this; }
IanBenzMaxim 0:f77ad7f72d04 66
IanBenzMaxim 0:f77ad7f72d04 67 Type * operator->() {
IanBenzMaxim 0:f77ad7f72d04 68 return const_cast<Type *>(
IanBenzMaxim 0:f77ad7f72d04 69 static_cast<const TypeStorage &>(*this).operator->());
IanBenzMaxim 0:f77ad7f72d04 70 }
IanBenzMaxim 0:f77ad7f72d04 71
IanBenzMaxim 0:f77ad7f72d04 72 private:
IanBenzMaxim 0:f77ad7f72d04 73 char data[TypeSize];
IanBenzMaxim 6:a8c83a2e6fa4 74 long double aligner1;
IanBenzMaxim 6:a8c83a2e6fa4 75 long int aligner2;
IanBenzMaxim 6:a8c83a2e6fa4 76 void * aligner3;
IanBenzMaxim 0:f77ad7f72d04 77 };
IanBenzMaxim 0:f77ad7f72d04 78
IanBenzMaxim 0:f77ad7f72d04 79 // Computes the internal target size for TypeStorage based on a desired total
IanBenzMaxim 0:f77ad7f72d04 80 // size. No internal storage will be allocated if the requested size is smaller
IanBenzMaxim 0:f77ad7f72d04 81 // than the required data elements of TypeWrapper or if the requested size is
IanBenzMaxim 0:f77ad7f72d04 82 // smaller than minimum size of TypeStorage.
IanBenzMaxim 0:f77ad7f72d04 83 template <typename Target, size_t totalSize> class TypeWrapperTotalSize {
IanBenzMaxim 0:f77ad7f72d04 84 private:
IanBenzMaxim 0:f77ad7f72d04 85 typedef TypeStorage<Target, 1> MinSizeStorage;
IanBenzMaxim 6:a8c83a2e6fa4 86
IanBenzMaxim 0:f77ad7f72d04 87 static const size_t otherDataSize = sizeof(Target *);
IanBenzMaxim 6:a8c83a2e6fa4 88
IanBenzMaxim 0:f77ad7f72d04 89 // Round down to be a multiple of alignment_of<MinSizeTargetStorage>::value.
IanBenzMaxim 0:f77ad7f72d04 90 static const size_t internalTargetRawSize =
IanBenzMaxim 0:f77ad7f72d04 91 (totalSize - otherDataSize) / alignment_of<MinSizeStorage>::value *
IanBenzMaxim 0:f77ad7f72d04 92 alignment_of<MinSizeStorage>::value;
IanBenzMaxim 0:f77ad7f72d04 93
IanBenzMaxim 0:f77ad7f72d04 94 public:
IanBenzMaxim 0:f77ad7f72d04 95 // Use internal storage if internalTargetRawSize is valid and at least as
IanBenzMaxim 0:f77ad7f72d04 96 // large as the minimum size of TypeStorage.
IanBenzMaxim 0:f77ad7f72d04 97 static const size_t internalTargetSize =
IanBenzMaxim 0:f77ad7f72d04 98 ((totalSize > otherDataSize) &&
IanBenzMaxim 0:f77ad7f72d04 99 (internalTargetRawSize >= sizeof(MinSizeStorage)))
IanBenzMaxim 0:f77ad7f72d04 100 ? internalTargetRawSize
IanBenzMaxim 0:f77ad7f72d04 101 : 0;
IanBenzMaxim 0:f77ad7f72d04 102 };
IanBenzMaxim 0:f77ad7f72d04 103
IanBenzMaxim 0:f77ad7f72d04 104 // Basic type erasure implementation with small object optimization.
IanBenzMaxim 0:f77ad7f72d04 105 template <typename Target, template <typename> class TargetAdapter,
IanBenzMaxim 0:f77ad7f72d04 106 size_t internalTargetSize =
IanBenzMaxim 0:f77ad7f72d04 107 TypeWrapperTotalSize<Target, 32>::internalTargetSize>
IanBenzMaxim 0:f77ad7f72d04 108 class TypeWrapper {
IanBenzMaxim 0:f77ad7f72d04 109 private:
IanBenzMaxim 0:f77ad7f72d04 110 typedef TypeStorage<Target, internalTargetSize> TargetStorage;
IanBenzMaxim 0:f77ad7f72d04 111
IanBenzMaxim 0:f77ad7f72d04 112 public:
IanBenzMaxim 0:f77ad7f72d04 113 TypeWrapper() : currentTarget(NULL) {}
IanBenzMaxim 0:f77ad7f72d04 114
IanBenzMaxim 0:f77ad7f72d04 115 TypeWrapper(const TypeWrapper & other) {
IanBenzMaxim 0:f77ad7f72d04 116 if (other.currentTarget == other.internalTarget) {
IanBenzMaxim 0:f77ad7f72d04 117 other.currentTarget->clone(internalTarget);
IanBenzMaxim 0:f77ad7f72d04 118 currentTarget = internalTarget;
IanBenzMaxim 0:f77ad7f72d04 119 } else if (other.currentTarget) {
IanBenzMaxim 0:f77ad7f72d04 120 currentTarget = other.currentTarget->clone();
IanBenzMaxim 0:f77ad7f72d04 121 } else {
IanBenzMaxim 0:f77ad7f72d04 122 currentTarget = NULL;
IanBenzMaxim 0:f77ad7f72d04 123 }
IanBenzMaxim 0:f77ad7f72d04 124 }
IanBenzMaxim 0:f77ad7f72d04 125
IanBenzMaxim 0:f77ad7f72d04 126 template <typename Source> TypeWrapper(Source source) {
IanBenzMaxim 0:f77ad7f72d04 127 if (sizeof(TargetAdapter<Source>) <= internalTargetSize &&
IanBenzMaxim 0:f77ad7f72d04 128 alignment_of<TargetAdapter<Source> >::value <=
IanBenzMaxim 0:f77ad7f72d04 129 alignment_of<TargetStorage>::value) {
IanBenzMaxim 0:f77ad7f72d04 130 new (internalTarget) TargetAdapter<Source>(source);
IanBenzMaxim 0:f77ad7f72d04 131 currentTarget = internalTarget;
IanBenzMaxim 0:f77ad7f72d04 132 } else {
IanBenzMaxim 0:f77ad7f72d04 133 currentTarget = new TargetAdapter<Source>(source);
IanBenzMaxim 0:f77ad7f72d04 134 }
IanBenzMaxim 0:f77ad7f72d04 135 }
IanBenzMaxim 0:f77ad7f72d04 136
IanBenzMaxim 0:f77ad7f72d04 137 ~TypeWrapper() {
IanBenzMaxim 0:f77ad7f72d04 138 if (currentTarget == internalTarget) {
IanBenzMaxim 0:f77ad7f72d04 139 currentTarget->~Target();
IanBenzMaxim 0:f77ad7f72d04 140 } else {
IanBenzMaxim 0:f77ad7f72d04 141 delete currentTarget;
IanBenzMaxim 0:f77ad7f72d04 142 }
IanBenzMaxim 0:f77ad7f72d04 143 }
IanBenzMaxim 0:f77ad7f72d04 144
IanBenzMaxim 0:f77ad7f72d04 145 const TypeWrapper & operator=(const TypeWrapper & rhs) {
IanBenzMaxim 0:f77ad7f72d04 146 TypeWrapper(rhs).swap(*this);
IanBenzMaxim 0:f77ad7f72d04 147 return *this;
IanBenzMaxim 0:f77ad7f72d04 148 }
IanBenzMaxim 0:f77ad7f72d04 149
IanBenzMaxim 0:f77ad7f72d04 150 template <typename Source> const TypeWrapper & operator=(Source source) {
IanBenzMaxim 0:f77ad7f72d04 151 TypeWrapper(source).swap(*this);
IanBenzMaxim 0:f77ad7f72d04 152 return *this;
IanBenzMaxim 0:f77ad7f72d04 153 }
IanBenzMaxim 0:f77ad7f72d04 154
IanBenzMaxim 0:f77ad7f72d04 155 void clear() { TypeWrapper().swap(*this); }
IanBenzMaxim 0:f77ad7f72d04 156
IanBenzMaxim 0:f77ad7f72d04 157 void swap(TypeWrapper & other) {
IanBenzMaxim 0:f77ad7f72d04 158 if (this == &other) {
IanBenzMaxim 0:f77ad7f72d04 159 return;
IanBenzMaxim 0:f77ad7f72d04 160 }
IanBenzMaxim 0:f77ad7f72d04 161
IanBenzMaxim 0:f77ad7f72d04 162 if (currentTarget == internalTarget &&
IanBenzMaxim 0:f77ad7f72d04 163 other.currentTarget == other.internalTarget) {
IanBenzMaxim 0:f77ad7f72d04 164 TargetStorage temp;
IanBenzMaxim 0:f77ad7f72d04 165 currentTarget->clone(temp);
IanBenzMaxim 0:f77ad7f72d04 166 currentTarget->~Target();
IanBenzMaxim 0:f77ad7f72d04 167 currentTarget = NULL;
IanBenzMaxim 0:f77ad7f72d04 168 other.currentTarget->clone(internalTarget);
IanBenzMaxim 0:f77ad7f72d04 169 other.currentTarget->~Target();
IanBenzMaxim 0:f77ad7f72d04 170 other.currentTarget = NULL;
IanBenzMaxim 0:f77ad7f72d04 171 currentTarget = internalTarget;
IanBenzMaxim 0:f77ad7f72d04 172 temp->clone(other.internalTarget);
IanBenzMaxim 0:f77ad7f72d04 173 temp->~Target();
IanBenzMaxim 0:f77ad7f72d04 174 other.currentTarget = other.internalTarget;
IanBenzMaxim 0:f77ad7f72d04 175 } else if (currentTarget == internalTarget) {
IanBenzMaxim 0:f77ad7f72d04 176 currentTarget->clone(other.internalTarget);
IanBenzMaxim 0:f77ad7f72d04 177 currentTarget->~Target();
IanBenzMaxim 0:f77ad7f72d04 178 currentTarget = other.currentTarget;
IanBenzMaxim 0:f77ad7f72d04 179 other.currentTarget = other.internalTarget;
IanBenzMaxim 0:f77ad7f72d04 180 } else if (other.currentTarget == other.internalTarget) {
IanBenzMaxim 0:f77ad7f72d04 181 other.currentTarget->clone(internalTarget);
IanBenzMaxim 0:f77ad7f72d04 182 other.currentTarget->~Target();
IanBenzMaxim 0:f77ad7f72d04 183 other.currentTarget = currentTarget;
IanBenzMaxim 0:f77ad7f72d04 184 currentTarget = internalTarget;
IanBenzMaxim 0:f77ad7f72d04 185 } else {
IanBenzMaxim 0:f77ad7f72d04 186 using std::swap;
IanBenzMaxim 0:f77ad7f72d04 187 swap(currentTarget, other.currentTarget);
IanBenzMaxim 0:f77ad7f72d04 188 }
IanBenzMaxim 0:f77ad7f72d04 189 }
IanBenzMaxim 0:f77ad7f72d04 190
IanBenzMaxim 0:f77ad7f72d04 191 const Target * target() const { return currentTarget; }
IanBenzMaxim 0:f77ad7f72d04 192
IanBenzMaxim 0:f77ad7f72d04 193 private:
IanBenzMaxim 0:f77ad7f72d04 194 TargetStorage internalTarget;
IanBenzMaxim 0:f77ad7f72d04 195 Target * currentTarget;
IanBenzMaxim 0:f77ad7f72d04 196 };
IanBenzMaxim 0:f77ad7f72d04 197
IanBenzMaxim 0:f77ad7f72d04 198 // TypeWrapper specialization with no internal storage space.
IanBenzMaxim 0:f77ad7f72d04 199 template <typename Target, template <typename> class TargetAdapter>
IanBenzMaxim 0:f77ad7f72d04 200 class TypeWrapper<Target, TargetAdapter, 0> {
IanBenzMaxim 0:f77ad7f72d04 201 public:
IanBenzMaxim 0:f77ad7f72d04 202 TypeWrapper() : currentTarget(NULL) {}
IanBenzMaxim 0:f77ad7f72d04 203
IanBenzMaxim 0:f77ad7f72d04 204 TypeWrapper(const TypeWrapper & other) {
IanBenzMaxim 0:f77ad7f72d04 205 if (other.currentTarget) {
IanBenzMaxim 0:f77ad7f72d04 206 currentTarget = other.currentTarget->clone();
IanBenzMaxim 0:f77ad7f72d04 207 } else {
IanBenzMaxim 0:f77ad7f72d04 208 currentTarget = NULL;
IanBenzMaxim 0:f77ad7f72d04 209 }
IanBenzMaxim 0:f77ad7f72d04 210 }
IanBenzMaxim 0:f77ad7f72d04 211
IanBenzMaxim 0:f77ad7f72d04 212 template <typename Source>
IanBenzMaxim 0:f77ad7f72d04 213 TypeWrapper(Source source)
IanBenzMaxim 0:f77ad7f72d04 214 : currentTarget(new TargetAdapter<Source>(source)) {}
IanBenzMaxim 0:f77ad7f72d04 215
IanBenzMaxim 0:f77ad7f72d04 216 ~TypeWrapper() { delete currentTarget; }
IanBenzMaxim 0:f77ad7f72d04 217
IanBenzMaxim 0:f77ad7f72d04 218 const TypeWrapper & operator=(const TypeWrapper & rhs) {
IanBenzMaxim 0:f77ad7f72d04 219 TypeWrapper(rhs).swap(*this);
IanBenzMaxim 0:f77ad7f72d04 220 return *this;
IanBenzMaxim 0:f77ad7f72d04 221 }
IanBenzMaxim 0:f77ad7f72d04 222
IanBenzMaxim 0:f77ad7f72d04 223 template <typename Source> const TypeWrapper & operator=(Source source) {
IanBenzMaxim 0:f77ad7f72d04 224 TypeWrapper(source).swap(*this);
IanBenzMaxim 0:f77ad7f72d04 225 return *this;
IanBenzMaxim 0:f77ad7f72d04 226 }
IanBenzMaxim 0:f77ad7f72d04 227
IanBenzMaxim 0:f77ad7f72d04 228 void clear() { TypeWrapper().swap(*this); }
IanBenzMaxim 0:f77ad7f72d04 229
IanBenzMaxim 0:f77ad7f72d04 230 void swap(TypeWrapper & other) {
IanBenzMaxim 0:f77ad7f72d04 231 using std::swap;
IanBenzMaxim 0:f77ad7f72d04 232 swap(currentTarget, other.currentTarget);
IanBenzMaxim 0:f77ad7f72d04 233 }
IanBenzMaxim 0:f77ad7f72d04 234
IanBenzMaxim 0:f77ad7f72d04 235 const Target * target() const { return currentTarget; }
IanBenzMaxim 0:f77ad7f72d04 236
IanBenzMaxim 0:f77ad7f72d04 237 private:
IanBenzMaxim 0:f77ad7f72d04 238 Target * currentTarget;
IanBenzMaxim 0:f77ad7f72d04 239 };
IanBenzMaxim 0:f77ad7f72d04 240
IanBenzMaxim 0:f77ad7f72d04 241 } // namespace detail
IanBenzMaxim 0:f77ad7f72d04 242
IanBenzMaxim 7:471901a04573 243 // Function wrapper similar to std::function for 0-3 argument functions.
IanBenzMaxim 0:f77ad7f72d04 244 template <typename> class Function;
IanBenzMaxim 0:f77ad7f72d04 245
IanBenzMaxim 0:f77ad7f72d04 246 // Function implementation for zero argument functions.
IanBenzMaxim 0:f77ad7f72d04 247 template <typename ResultType> class Function<ResultType()> {
IanBenzMaxim 0:f77ad7f72d04 248 public:
IanBenzMaxim 0:f77ad7f72d04 249 typedef ResultType result_type;
IanBenzMaxim 0:f77ad7f72d04 250
IanBenzMaxim 0:f77ad7f72d04 251 Function(ResultType (*func)() = NULL) : callableWrapper() {
IanBenzMaxim 0:f77ad7f72d04 252 if (func) {
IanBenzMaxim 0:f77ad7f72d04 253 callableWrapper = func;
IanBenzMaxim 0:f77ad7f72d04 254 }
IanBenzMaxim 0:f77ad7f72d04 255 }
IanBenzMaxim 0:f77ad7f72d04 256
IanBenzMaxim 0:f77ad7f72d04 257 template <typename F> Function(F func) : callableWrapper(func) {}
IanBenzMaxim 0:f77ad7f72d04 258
IanBenzMaxim 0:f77ad7f72d04 259 const Function & operator=(ResultType (*func)()) {
IanBenzMaxim 0:f77ad7f72d04 260 if (func) {
IanBenzMaxim 0:f77ad7f72d04 261 callableWrapper = func;
IanBenzMaxim 0:f77ad7f72d04 262 } else {
IanBenzMaxim 0:f77ad7f72d04 263 callableWrapper.clear();
IanBenzMaxim 0:f77ad7f72d04 264 }
IanBenzMaxim 0:f77ad7f72d04 265 return *this;
IanBenzMaxim 0:f77ad7f72d04 266 }
IanBenzMaxim 0:f77ad7f72d04 267
IanBenzMaxim 0:f77ad7f72d04 268 template <typename F> const Function & operator=(F func) {
IanBenzMaxim 0:f77ad7f72d04 269 callableWrapper = func;
IanBenzMaxim 0:f77ad7f72d04 270 return *this;
IanBenzMaxim 0:f77ad7f72d04 271 }
IanBenzMaxim 0:f77ad7f72d04 272
IanBenzMaxim 0:f77ad7f72d04 273 void swap(Function & other) { callableWrapper.swap(other.callableWrapper); }
IanBenzMaxim 0:f77ad7f72d04 274
IanBenzMaxim 6:a8c83a2e6fa4 275 operator SafeBool() const {
IanBenzMaxim 6:a8c83a2e6fa4 276 return makeSafeBool(callableWrapper.target() != NULL);
IanBenzMaxim 6:a8c83a2e6fa4 277 }
IanBenzMaxim 0:f77ad7f72d04 278
IanBenzMaxim 0:f77ad7f72d04 279 ResultType operator()() const {
IanBenzMaxim 6:a8c83a2e6fa4 280 return callableWrapper.target() ? callableWrapper.target()->invoke()
IanBenzMaxim 0:f77ad7f72d04 281 : ResultType();
IanBenzMaxim 0:f77ad7f72d04 282 }
IanBenzMaxim 0:f77ad7f72d04 283
IanBenzMaxim 0:f77ad7f72d04 284 private:
IanBenzMaxim 0:f77ad7f72d04 285 class Callable {
IanBenzMaxim 0:f77ad7f72d04 286 public:
IanBenzMaxim 0:f77ad7f72d04 287 virtual ~Callable() {}
IanBenzMaxim 6:a8c83a2e6fa4 288 virtual ResultType invoke() const = 0;
IanBenzMaxim 0:f77ad7f72d04 289 virtual Callable * clone() const = 0;
IanBenzMaxim 0:f77ad7f72d04 290 virtual void clone(void * buffer) const = 0;
IanBenzMaxim 0:f77ad7f72d04 291 };
IanBenzMaxim 0:f77ad7f72d04 292
IanBenzMaxim 0:f77ad7f72d04 293 template <typename F> class CallableAdapter : public Callable {
IanBenzMaxim 0:f77ad7f72d04 294 public:
IanBenzMaxim 0:f77ad7f72d04 295 CallableAdapter(F func) : func(func) {}
IanBenzMaxim 0:f77ad7f72d04 296
IanBenzMaxim 6:a8c83a2e6fa4 297 virtual ResultType invoke() const { return func(); }
IanBenzMaxim 0:f77ad7f72d04 298
IanBenzMaxim 0:f77ad7f72d04 299 virtual Callable * clone() const { return new CallableAdapter(*this); }
IanBenzMaxim 0:f77ad7f72d04 300
IanBenzMaxim 0:f77ad7f72d04 301 virtual void clone(void * buffer) const {
IanBenzMaxim 0:f77ad7f72d04 302 new (buffer) CallableAdapter(*this);
IanBenzMaxim 0:f77ad7f72d04 303 }
IanBenzMaxim 0:f77ad7f72d04 304
IanBenzMaxim 0:f77ad7f72d04 305 private:
IanBenzMaxim 0:f77ad7f72d04 306 F func;
IanBenzMaxim 0:f77ad7f72d04 307 };
IanBenzMaxim 0:f77ad7f72d04 308
IanBenzMaxim 0:f77ad7f72d04 309 detail::TypeWrapper<Callable, CallableAdapter> callableWrapper;
IanBenzMaxim 0:f77ad7f72d04 310 };
IanBenzMaxim 0:f77ad7f72d04 311
IanBenzMaxim 0:f77ad7f72d04 312 template <typename ResultType>
IanBenzMaxim 0:f77ad7f72d04 313 inline void swap(Function<ResultType()> & lhs, Function<ResultType()> & rhs) {
IanBenzMaxim 0:f77ad7f72d04 314 lhs.swap(rhs);
IanBenzMaxim 0:f77ad7f72d04 315 }
IanBenzMaxim 0:f77ad7f72d04 316
IanBenzMaxim 0:f77ad7f72d04 317 // Function implementation for one argument functions.
IanBenzMaxim 0:f77ad7f72d04 318 template <typename ArgumentType, typename ResultType>
IanBenzMaxim 0:f77ad7f72d04 319 class Function<ResultType(ArgumentType)> {
IanBenzMaxim 0:f77ad7f72d04 320 public:
IanBenzMaxim 0:f77ad7f72d04 321 typedef ArgumentType argument_type;
IanBenzMaxim 0:f77ad7f72d04 322 typedef ResultType result_type;
IanBenzMaxim 0:f77ad7f72d04 323
IanBenzMaxim 0:f77ad7f72d04 324 Function(ResultType (*func)(ArgumentType) = NULL) : callableWrapper() {
IanBenzMaxim 0:f77ad7f72d04 325 if (func) {
IanBenzMaxim 0:f77ad7f72d04 326 callableWrapper = func;
IanBenzMaxim 0:f77ad7f72d04 327 }
IanBenzMaxim 0:f77ad7f72d04 328 }
IanBenzMaxim 0:f77ad7f72d04 329
IanBenzMaxim 0:f77ad7f72d04 330 template <typename F> Function(F func) : callableWrapper(func) {}
IanBenzMaxim 0:f77ad7f72d04 331
IanBenzMaxim 0:f77ad7f72d04 332 const Function & operator=(ResultType (*func)(ArgumentType)) {
IanBenzMaxim 0:f77ad7f72d04 333 if (func) {
IanBenzMaxim 0:f77ad7f72d04 334 callableWrapper = func;
IanBenzMaxim 0:f77ad7f72d04 335 } else {
IanBenzMaxim 0:f77ad7f72d04 336 callableWrapper.clear();
IanBenzMaxim 0:f77ad7f72d04 337 }
IanBenzMaxim 0:f77ad7f72d04 338 return *this;
IanBenzMaxim 0:f77ad7f72d04 339 }
IanBenzMaxim 0:f77ad7f72d04 340
IanBenzMaxim 0:f77ad7f72d04 341 template <typename F> const Function & operator=(F func) {
IanBenzMaxim 0:f77ad7f72d04 342 callableWrapper = func;
IanBenzMaxim 0:f77ad7f72d04 343 return *this;
IanBenzMaxim 0:f77ad7f72d04 344 }
IanBenzMaxim 0:f77ad7f72d04 345
IanBenzMaxim 0:f77ad7f72d04 346 void swap(Function & other) { callableWrapper.swap(other.callableWrapper); }
IanBenzMaxim 0:f77ad7f72d04 347
IanBenzMaxim 6:a8c83a2e6fa4 348 operator SafeBool() const {
IanBenzMaxim 6:a8c83a2e6fa4 349 return makeSafeBool(callableWrapper.target() != NULL);
IanBenzMaxim 6:a8c83a2e6fa4 350 }
IanBenzMaxim 0:f77ad7f72d04 351
IanBenzMaxim 0:f77ad7f72d04 352 ResultType operator()(ArgumentType arg) const {
IanBenzMaxim 6:a8c83a2e6fa4 353 return callableWrapper.target() ? callableWrapper.target()->invoke(arg)
IanBenzMaxim 0:f77ad7f72d04 354 : ResultType();
IanBenzMaxim 0:f77ad7f72d04 355 }
IanBenzMaxim 0:f77ad7f72d04 356
IanBenzMaxim 0:f77ad7f72d04 357 private:
IanBenzMaxim 0:f77ad7f72d04 358 class Callable {
IanBenzMaxim 0:f77ad7f72d04 359 public:
IanBenzMaxim 0:f77ad7f72d04 360 virtual ~Callable() {}
IanBenzMaxim 6:a8c83a2e6fa4 361 virtual ResultType invoke(ArgumentType) const = 0;
IanBenzMaxim 0:f77ad7f72d04 362 virtual Callable * clone() const = 0;
IanBenzMaxim 0:f77ad7f72d04 363 virtual void clone(void * buffer) const = 0;
IanBenzMaxim 0:f77ad7f72d04 364 };
IanBenzMaxim 0:f77ad7f72d04 365
IanBenzMaxim 0:f77ad7f72d04 366 template <typename F> class CallableAdapter : public Callable {
IanBenzMaxim 0:f77ad7f72d04 367 public:
IanBenzMaxim 0:f77ad7f72d04 368 CallableAdapter(F func) : func(func) {}
IanBenzMaxim 0:f77ad7f72d04 369
IanBenzMaxim 6:a8c83a2e6fa4 370 virtual ResultType invoke(ArgumentType arg) const { return func(arg); }
IanBenzMaxim 0:f77ad7f72d04 371
IanBenzMaxim 0:f77ad7f72d04 372 virtual Callable * clone() const { return new CallableAdapter(*this); }
IanBenzMaxim 0:f77ad7f72d04 373
IanBenzMaxim 0:f77ad7f72d04 374 virtual void clone(void * buffer) const {
IanBenzMaxim 0:f77ad7f72d04 375 new (buffer) CallableAdapter(*this);
IanBenzMaxim 0:f77ad7f72d04 376 }
IanBenzMaxim 0:f77ad7f72d04 377
IanBenzMaxim 0:f77ad7f72d04 378 private:
IanBenzMaxim 0:f77ad7f72d04 379 F func;
IanBenzMaxim 0:f77ad7f72d04 380 };
IanBenzMaxim 0:f77ad7f72d04 381
IanBenzMaxim 0:f77ad7f72d04 382 detail::TypeWrapper<Callable, CallableAdapter> callableWrapper;
IanBenzMaxim 0:f77ad7f72d04 383 };
IanBenzMaxim 0:f77ad7f72d04 384
IanBenzMaxim 0:f77ad7f72d04 385 template <typename ArgumentType, typename ResultType>
IanBenzMaxim 0:f77ad7f72d04 386 inline void swap(Function<ResultType(ArgumentType)> & lhs,
IanBenzMaxim 0:f77ad7f72d04 387 Function<ResultType(ArgumentType)> & rhs) {
IanBenzMaxim 0:f77ad7f72d04 388 lhs.swap(rhs);
IanBenzMaxim 0:f77ad7f72d04 389 }
IanBenzMaxim 0:f77ad7f72d04 390
IanBenzMaxim 0:f77ad7f72d04 391 // Function implementation for two argument functions.
IanBenzMaxim 0:f77ad7f72d04 392 template <typename FirstArgumentType, typename SecondArgumentType,
IanBenzMaxim 0:f77ad7f72d04 393 typename ResultType>
IanBenzMaxim 0:f77ad7f72d04 394 class Function<ResultType(FirstArgumentType, SecondArgumentType)> {
IanBenzMaxim 0:f77ad7f72d04 395 public:
IanBenzMaxim 0:f77ad7f72d04 396 typedef FirstArgumentType first_argument_type;
IanBenzMaxim 0:f77ad7f72d04 397 typedef SecondArgumentType second_argument_type;
IanBenzMaxim 0:f77ad7f72d04 398 typedef ResultType result_type;
IanBenzMaxim 0:f77ad7f72d04 399
IanBenzMaxim 0:f77ad7f72d04 400 Function(ResultType (*func)(FirstArgumentType, SecondArgumentType) = NULL)
IanBenzMaxim 0:f77ad7f72d04 401 : callableWrapper() {
IanBenzMaxim 0:f77ad7f72d04 402 if (func) {
IanBenzMaxim 0:f77ad7f72d04 403 callableWrapper = func;
IanBenzMaxim 0:f77ad7f72d04 404 }
IanBenzMaxim 0:f77ad7f72d04 405 }
IanBenzMaxim 0:f77ad7f72d04 406
IanBenzMaxim 0:f77ad7f72d04 407 template <typename F> Function(F func) : callableWrapper(func) {}
IanBenzMaxim 0:f77ad7f72d04 408
IanBenzMaxim 0:f77ad7f72d04 409 const Function & operator=(ResultType (*func)(FirstArgumentType,
IanBenzMaxim 0:f77ad7f72d04 410 SecondArgumentType)) {
IanBenzMaxim 0:f77ad7f72d04 411 if (func) {
IanBenzMaxim 0:f77ad7f72d04 412 callableWrapper = func;
IanBenzMaxim 0:f77ad7f72d04 413 } else {
IanBenzMaxim 0:f77ad7f72d04 414 callableWrapper.clear();
IanBenzMaxim 0:f77ad7f72d04 415 }
IanBenzMaxim 0:f77ad7f72d04 416 return *this;
IanBenzMaxim 0:f77ad7f72d04 417 }
IanBenzMaxim 0:f77ad7f72d04 418
IanBenzMaxim 0:f77ad7f72d04 419 template <typename F> const Function & operator=(F func) {
IanBenzMaxim 0:f77ad7f72d04 420 callableWrapper = func;
IanBenzMaxim 0:f77ad7f72d04 421 return *this;
IanBenzMaxim 0:f77ad7f72d04 422 }
IanBenzMaxim 0:f77ad7f72d04 423
IanBenzMaxim 0:f77ad7f72d04 424 void swap(Function & other) { callableWrapper.swap(other.callableWrapper); }
IanBenzMaxim 0:f77ad7f72d04 425
IanBenzMaxim 6:a8c83a2e6fa4 426 operator SafeBool() const {
IanBenzMaxim 6:a8c83a2e6fa4 427 return makeSafeBool(callableWrapper.target() != NULL);
IanBenzMaxim 6:a8c83a2e6fa4 428 }
IanBenzMaxim 0:f77ad7f72d04 429
IanBenzMaxim 0:f77ad7f72d04 430 ResultType operator()(FirstArgumentType arg1, SecondArgumentType arg2) const {
IanBenzMaxim 6:a8c83a2e6fa4 431 return callableWrapper.target()
IanBenzMaxim 6:a8c83a2e6fa4 432 ? callableWrapper.target()->invoke(arg1, arg2)
IanBenzMaxim 6:a8c83a2e6fa4 433 : ResultType();
IanBenzMaxim 0:f77ad7f72d04 434 }
IanBenzMaxim 0:f77ad7f72d04 435
IanBenzMaxim 0:f77ad7f72d04 436 private:
IanBenzMaxim 0:f77ad7f72d04 437 class Callable {
IanBenzMaxim 0:f77ad7f72d04 438 public:
IanBenzMaxim 0:f77ad7f72d04 439 virtual ~Callable() {}
IanBenzMaxim 6:a8c83a2e6fa4 440 virtual ResultType invoke(FirstArgumentType, SecondArgumentType) const = 0;
IanBenzMaxim 0:f77ad7f72d04 441 virtual Callable * clone() const = 0;
IanBenzMaxim 0:f77ad7f72d04 442 virtual void clone(void * buffer) const = 0;
IanBenzMaxim 0:f77ad7f72d04 443 };
IanBenzMaxim 0:f77ad7f72d04 444
IanBenzMaxim 0:f77ad7f72d04 445 template <typename F> class CallableAdapter : public Callable {
IanBenzMaxim 0:f77ad7f72d04 446 public:
IanBenzMaxim 0:f77ad7f72d04 447 CallableAdapter(F func) : func(func) {}
IanBenzMaxim 0:f77ad7f72d04 448
IanBenzMaxim 6:a8c83a2e6fa4 449 virtual ResultType invoke(FirstArgumentType arg1,
IanBenzMaxim 6:a8c83a2e6fa4 450 SecondArgumentType arg2) const {
IanBenzMaxim 0:f77ad7f72d04 451 return func(arg1, arg2);
IanBenzMaxim 0:f77ad7f72d04 452 }
IanBenzMaxim 0:f77ad7f72d04 453
IanBenzMaxim 0:f77ad7f72d04 454 virtual Callable * clone() const { return new CallableAdapter(*this); }
IanBenzMaxim 0:f77ad7f72d04 455
IanBenzMaxim 0:f77ad7f72d04 456 virtual void clone(void * buffer) const {
IanBenzMaxim 0:f77ad7f72d04 457 new (buffer) CallableAdapter(*this);
IanBenzMaxim 0:f77ad7f72d04 458 }
IanBenzMaxim 0:f77ad7f72d04 459
IanBenzMaxim 0:f77ad7f72d04 460 private:
IanBenzMaxim 0:f77ad7f72d04 461 F func;
IanBenzMaxim 0:f77ad7f72d04 462 };
IanBenzMaxim 0:f77ad7f72d04 463
IanBenzMaxim 0:f77ad7f72d04 464 detail::TypeWrapper<Callable, CallableAdapter> callableWrapper;
IanBenzMaxim 0:f77ad7f72d04 465 };
IanBenzMaxim 0:f77ad7f72d04 466
IanBenzMaxim 0:f77ad7f72d04 467 template <typename FirstArgumentType, typename SecondArgumentType,
IanBenzMaxim 0:f77ad7f72d04 468 typename ResultType>
IanBenzMaxim 0:f77ad7f72d04 469 inline void
IanBenzMaxim 0:f77ad7f72d04 470 swap(Function<ResultType(FirstArgumentType, SecondArgumentType)> & lhs,
IanBenzMaxim 0:f77ad7f72d04 471 Function<ResultType(FirstArgumentType, SecondArgumentType)> & rhs) {
IanBenzMaxim 0:f77ad7f72d04 472 lhs.swap(rhs);
IanBenzMaxim 0:f77ad7f72d04 473 }
IanBenzMaxim 0:f77ad7f72d04 474
IanBenzMaxim 6:a8c83a2e6fa4 475 // Function implementation for three argument functions.
IanBenzMaxim 6:a8c83a2e6fa4 476 template <typename FirstArgumentType, typename SecondArgumentType,
IanBenzMaxim 6:a8c83a2e6fa4 477 typename ThirdArgumentType, typename ResultType>
IanBenzMaxim 6:a8c83a2e6fa4 478 class Function<ResultType(FirstArgumentType, SecondArgumentType,
IanBenzMaxim 6:a8c83a2e6fa4 479 ThirdArgumentType)> {
IanBenzMaxim 6:a8c83a2e6fa4 480 public:
IanBenzMaxim 6:a8c83a2e6fa4 481 typedef ResultType result_type;
IanBenzMaxim 6:a8c83a2e6fa4 482
IanBenzMaxim 6:a8c83a2e6fa4 483 Function(ResultType (*func)(FirstArgumentType, SecondArgumentType,
IanBenzMaxim 6:a8c83a2e6fa4 484 ThirdArgumentType) = NULL)
IanBenzMaxim 6:a8c83a2e6fa4 485 : callableWrapper() {
IanBenzMaxim 6:a8c83a2e6fa4 486 if (func) {
IanBenzMaxim 6:a8c83a2e6fa4 487 callableWrapper = func;
IanBenzMaxim 6:a8c83a2e6fa4 488 }
IanBenzMaxim 6:a8c83a2e6fa4 489 }
IanBenzMaxim 6:a8c83a2e6fa4 490
IanBenzMaxim 6:a8c83a2e6fa4 491 template <typename F> Function(F func) : callableWrapper(func) {}
IanBenzMaxim 6:a8c83a2e6fa4 492
IanBenzMaxim 6:a8c83a2e6fa4 493 const Function & operator=(ResultType (*func)(FirstArgumentType,
IanBenzMaxim 6:a8c83a2e6fa4 494 SecondArgumentType,
IanBenzMaxim 6:a8c83a2e6fa4 495 ThirdArgumentType)) {
IanBenzMaxim 6:a8c83a2e6fa4 496 if (func) {
IanBenzMaxim 6:a8c83a2e6fa4 497 callableWrapper = func;
IanBenzMaxim 6:a8c83a2e6fa4 498 } else {
IanBenzMaxim 6:a8c83a2e6fa4 499 callableWrapper.clear();
IanBenzMaxim 6:a8c83a2e6fa4 500 }
IanBenzMaxim 6:a8c83a2e6fa4 501 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 502 }
IanBenzMaxim 6:a8c83a2e6fa4 503
IanBenzMaxim 6:a8c83a2e6fa4 504 template <typename F> const Function & operator=(F func) {
IanBenzMaxim 6:a8c83a2e6fa4 505 callableWrapper = func;
IanBenzMaxim 6:a8c83a2e6fa4 506 return *this;
IanBenzMaxim 6:a8c83a2e6fa4 507 }
IanBenzMaxim 6:a8c83a2e6fa4 508
IanBenzMaxim 6:a8c83a2e6fa4 509 void swap(Function & other) { callableWrapper.swap(other.callableWrapper); }
IanBenzMaxim 6:a8c83a2e6fa4 510
IanBenzMaxim 6:a8c83a2e6fa4 511 operator SafeBool() const {
IanBenzMaxim 6:a8c83a2e6fa4 512 return makeSafeBool(callableWrapper.target() != NULL);
IanBenzMaxim 6:a8c83a2e6fa4 513 }
IanBenzMaxim 6:a8c83a2e6fa4 514
IanBenzMaxim 6:a8c83a2e6fa4 515 ResultType operator()(FirstArgumentType arg1, SecondArgumentType arg2,
IanBenzMaxim 6:a8c83a2e6fa4 516 ThirdArgumentType arg3) const {
IanBenzMaxim 6:a8c83a2e6fa4 517 return callableWrapper.target()
IanBenzMaxim 6:a8c83a2e6fa4 518 ? callableWrapper.target()->invoke(arg1, arg2, arg3)
IanBenzMaxim 6:a8c83a2e6fa4 519 : ResultType();
IanBenzMaxim 6:a8c83a2e6fa4 520 }
IanBenzMaxim 6:a8c83a2e6fa4 521
IanBenzMaxim 6:a8c83a2e6fa4 522 private:
IanBenzMaxim 6:a8c83a2e6fa4 523 class Callable {
IanBenzMaxim 6:a8c83a2e6fa4 524 public:
IanBenzMaxim 6:a8c83a2e6fa4 525 virtual ~Callable() {}
IanBenzMaxim 6:a8c83a2e6fa4 526 virtual ResultType invoke(FirstArgumentType, SecondArgumentType,
IanBenzMaxim 6:a8c83a2e6fa4 527 ThirdArgumentType) const = 0;
IanBenzMaxim 6:a8c83a2e6fa4 528 virtual Callable * clone() const = 0;
IanBenzMaxim 6:a8c83a2e6fa4 529 virtual void clone(void * buffer) const = 0;
IanBenzMaxim 6:a8c83a2e6fa4 530 };
IanBenzMaxim 6:a8c83a2e6fa4 531
IanBenzMaxim 6:a8c83a2e6fa4 532 template <typename F> class CallableAdapter : public Callable {
IanBenzMaxim 6:a8c83a2e6fa4 533 public:
IanBenzMaxim 6:a8c83a2e6fa4 534 CallableAdapter(F func) : func(func) {}
IanBenzMaxim 6:a8c83a2e6fa4 535
IanBenzMaxim 6:a8c83a2e6fa4 536 virtual ResultType invoke(FirstArgumentType arg1, SecondArgumentType arg2,
IanBenzMaxim 6:a8c83a2e6fa4 537 ThirdArgumentType arg3) const {
IanBenzMaxim 6:a8c83a2e6fa4 538 return func(arg1, arg2, arg3);
IanBenzMaxim 6:a8c83a2e6fa4 539 }
IanBenzMaxim 6:a8c83a2e6fa4 540
IanBenzMaxim 6:a8c83a2e6fa4 541 virtual Callable * clone() const { return new CallableAdapter(*this); }
IanBenzMaxim 6:a8c83a2e6fa4 542
IanBenzMaxim 6:a8c83a2e6fa4 543 virtual void clone(void * buffer) const {
IanBenzMaxim 6:a8c83a2e6fa4 544 new (buffer) CallableAdapter(*this);
IanBenzMaxim 6:a8c83a2e6fa4 545 }
IanBenzMaxim 6:a8c83a2e6fa4 546
IanBenzMaxim 6:a8c83a2e6fa4 547 private:
IanBenzMaxim 6:a8c83a2e6fa4 548 F func;
IanBenzMaxim 6:a8c83a2e6fa4 549 };
IanBenzMaxim 6:a8c83a2e6fa4 550
IanBenzMaxim 6:a8c83a2e6fa4 551 detail::TypeWrapper<Callable, CallableAdapter> callableWrapper;
IanBenzMaxim 6:a8c83a2e6fa4 552 };
IanBenzMaxim 6:a8c83a2e6fa4 553
IanBenzMaxim 6:a8c83a2e6fa4 554 template <typename FirstArgumentType, typename SecondArgumentType,
IanBenzMaxim 6:a8c83a2e6fa4 555 typename ThirdArgumentType, typename ResultType>
IanBenzMaxim 6:a8c83a2e6fa4 556 inline void swap(Function<ResultType(FirstArgumentType, SecondArgumentType,
IanBenzMaxim 6:a8c83a2e6fa4 557 ThirdArgumentType)> & lhs,
IanBenzMaxim 6:a8c83a2e6fa4 558 Function<ResultType(FirstArgumentType, SecondArgumentType,
IanBenzMaxim 6:a8c83a2e6fa4 559 ThirdArgumentType)> & rhs) {
IanBenzMaxim 6:a8c83a2e6fa4 560 lhs.swap(rhs);
IanBenzMaxim 6:a8c83a2e6fa4 561 }
IanBenzMaxim 6:a8c83a2e6fa4 562
IanBenzMaxim 0:f77ad7f72d04 563 } // namespace MaximInterface
IanBenzMaxim 0:f77ad7f72d04 564
IanBenzMaxim 0:f77ad7f72d04 565 #endif