Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Maxim Interface is a library framework focused on providing flexible and expressive hardware interfaces. Both communication interfaces such as I2C and 1-Wire and device interfaces such as DS18B20 are supported. Modern C++ concepts are used extensively while keeping compatibility with C++98/C++03 and requiring no external dependencies. The embedded-friendly design does not depend on exceptions or RTTI.

The full version of the project is hosted on GitLab: https://gitlab.com/iabenz/MaximInterface

Committer:
IanBenzMaxim
Date:
Tue Dec 03 10:52:28 2019 -0600
Revision:
11:3f3bf6bf5e6c
Parent:
8:5ea891c7d1a1
Updated to version 2.1.

Who changed what in which revision?

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