Device interface library for multiple platforms including Mbed.
Dependents: DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#
Function.hpp
00001 /******************************************************************************* 00002 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 *******************************************************************************/ 00032 00033 #ifndef MaximInterfaceCore_Function_hpp 00034 #define MaximInterfaceCore_Function_hpp 00035 00036 #include <stddef.h> 00037 #include "None.hpp" 00038 #include "SafeBool.hpp" 00039 #include "type_traits.hpp" 00040 00041 // Include for std::swap. 00042 #include <algorithm> 00043 #include <utility> 00044 00045 namespace MaximInterfaceCore { 00046 namespace detail { 00047 00048 // Provides char buffer storage for a given type. 00049 // Suitability of alignment for type should be verified with alignment_of. 00050 template <typename Type, size_t TypeSize> union TypeStorage { 00051 public: 00052 operator const Type *() const { return reinterpret_cast<const Type *>(data); } 00053 00054 operator Type *() { 00055 return const_cast<Type *>( 00056 static_cast<const Type *>(static_cast<const TypeStorage &>(*this))); 00057 } 00058 00059 const Type & operator*() const { return **this; } 00060 00061 Type & operator*() { 00062 return const_cast<Type &>( 00063 static_cast<const TypeStorage &>(*this).operator*()); 00064 } 00065 00066 const Type * operator->() const { return *this; } 00067 00068 Type * operator->() { 00069 return const_cast<Type *>( 00070 static_cast<const TypeStorage &>(*this).operator->()); 00071 } 00072 00073 private: 00074 char data[TypeSize]; 00075 long double aligner1; 00076 long int aligner2; 00077 void * aligner3; 00078 }; 00079 00080 // Computes the internal target size for TypeStorage based on a desired total 00081 // size. No internal storage will be allocated if the requested size is smaller 00082 // than the required data elements of TypeWrapper or if the requested size is 00083 // smaller than minimum size of TypeStorage. 00084 template <typename Target, size_t totalSize> class TypeWrapperTotalSize { 00085 private: 00086 typedef TypeStorage<Target, 1> MinSizeStorage; 00087 00088 static const size_t otherDataSize = sizeof(Target *); 00089 00090 // Round down to be a multiple of alignment_of<MinSizeTargetStorage>::value. 00091 static const size_t internalTargetRawSize = 00092 (totalSize - otherDataSize) / alignment_of<MinSizeStorage>::value * 00093 alignment_of<MinSizeStorage>::value; 00094 00095 public: 00096 // Use internal storage if internalTargetRawSize is valid and at least as 00097 // large as the minimum size of TypeStorage. 00098 static const size_t internalTargetSize = 00099 ((totalSize > otherDataSize) && 00100 (internalTargetRawSize >= sizeof(MinSizeStorage))) 00101 ? internalTargetRawSize 00102 : 0; 00103 }; 00104 00105 // Basic type erasure implementation with small object optimization. 00106 template <typename Target, template <typename> class TargetAdapter, 00107 size_t internalTargetSize = 00108 TypeWrapperTotalSize<Target, 32>::internalTargetSize> 00109 class TypeWrapper { 00110 private: 00111 typedef TypeStorage<Target, internalTargetSize> TargetStorage; 00112 00113 public: 00114 TypeWrapper() : currentTarget(NULL) {} 00115 00116 TypeWrapper(None) : currentTarget(NULL) {} 00117 00118 TypeWrapper(const TypeWrapper & other) { 00119 if (other.currentTarget == other.internalTarget) { 00120 other.currentTarget->clone(internalTarget); 00121 currentTarget = internalTarget; 00122 } else if (other.currentTarget) { 00123 currentTarget = other.currentTarget->clone(); 00124 } else { 00125 currentTarget = NULL; 00126 } 00127 } 00128 00129 template <typename Source> TypeWrapper(Source source) { 00130 if (sizeof(TargetAdapter<Source>) <= internalTargetSize && 00131 alignment_of<TargetAdapter<Source> >::value <= 00132 alignment_of<TargetStorage>::value) { 00133 new (internalTarget) TargetAdapter<Source>(source); 00134 currentTarget = internalTarget; 00135 } else { 00136 currentTarget = new TargetAdapter<Source>(source); 00137 } 00138 } 00139 00140 ~TypeWrapper() { 00141 if (currentTarget == internalTarget) { 00142 currentTarget->~Target(); 00143 } else { 00144 delete currentTarget; 00145 } 00146 } 00147 00148 const TypeWrapper & operator=(None) { 00149 TypeWrapper().swap(*this); 00150 return *this; 00151 } 00152 00153 const TypeWrapper & operator=(const TypeWrapper & rhs) { 00154 TypeWrapper(rhs).swap(*this); 00155 return *this; 00156 } 00157 00158 template <typename Source> const TypeWrapper & operator=(Source source) { 00159 TypeWrapper(source).swap(*this); 00160 return *this; 00161 } 00162 00163 void swap(TypeWrapper & other) { 00164 if (this == &other) { 00165 return; 00166 } 00167 00168 if (currentTarget == internalTarget && 00169 other.currentTarget == other.internalTarget) { 00170 TargetStorage temp; 00171 currentTarget->clone(temp); 00172 currentTarget->~Target(); 00173 currentTarget = NULL; 00174 other.currentTarget->clone(internalTarget); 00175 other.currentTarget->~Target(); 00176 other.currentTarget = NULL; 00177 currentTarget = internalTarget; 00178 temp->clone(other.internalTarget); 00179 temp->~Target(); 00180 other.currentTarget = other.internalTarget; 00181 } else if (currentTarget == internalTarget) { 00182 currentTarget->clone(other.internalTarget); 00183 currentTarget->~Target(); 00184 currentTarget = other.currentTarget; 00185 other.currentTarget = other.internalTarget; 00186 } else if (other.currentTarget == other.internalTarget) { 00187 other.currentTarget->clone(internalTarget); 00188 other.currentTarget->~Target(); 00189 other.currentTarget = currentTarget; 00190 currentTarget = internalTarget; 00191 } else { 00192 using std::swap; 00193 swap(currentTarget, other.currentTarget); 00194 } 00195 } 00196 00197 const Target * target() const { return currentTarget; } 00198 00199 private: 00200 TargetStorage internalTarget; 00201 Target * currentTarget; 00202 }; 00203 00204 // TypeWrapper specialization with no internal storage space. 00205 template <typename Target, template <typename> class TargetAdapter> 00206 class TypeWrapper<Target, TargetAdapter, 0> { 00207 public: 00208 TypeWrapper() : currentTarget(NULL) {} 00209 00210 TypeWrapper(None) : currentTarget(NULL) {} 00211 00212 TypeWrapper(const TypeWrapper & other) { 00213 if (other.currentTarget) { 00214 currentTarget = other.currentTarget->clone(); 00215 } else { 00216 currentTarget = NULL; 00217 } 00218 } 00219 00220 template <typename Source> 00221 TypeWrapper(Source source) 00222 : currentTarget(new TargetAdapter<Source>(source)) {} 00223 00224 ~TypeWrapper() { delete currentTarget; } 00225 00226 const TypeWrapper & operator=(None) { 00227 TypeWrapper().swap(*this); 00228 return *this; 00229 } 00230 00231 const TypeWrapper & operator=(const TypeWrapper & rhs) { 00232 TypeWrapper(rhs).swap(*this); 00233 return *this; 00234 } 00235 00236 template <typename Source> const TypeWrapper & operator=(Source source) { 00237 TypeWrapper(source).swap(*this); 00238 return *this; 00239 } 00240 00241 void swap(TypeWrapper & other) { 00242 using std::swap; 00243 swap(currentTarget, other.currentTarget); 00244 } 00245 00246 const Target * target() const { return currentTarget; } 00247 00248 private: 00249 Target * currentTarget; 00250 }; 00251 00252 } // namespace detail 00253 00254 /// %Function wrapper similar to std::function for 0-3 argument functions. 00255 template <typename> class Function; 00256 00257 /// Function implementation for zero argument functions. 00258 template <typename ResultType> class Function<ResultType()> { 00259 public: 00260 typedef ResultType result_type; 00261 00262 Function() : callableWrapper() {} 00263 00264 Function(None) : callableWrapper() {} 00265 00266 Function(ResultType (*func)()) : callableWrapper() { 00267 if (func) { 00268 callableWrapper = func; 00269 } 00270 } 00271 00272 template <typename F> Function(F func) : callableWrapper(func) {} 00273 00274 const Function & operator=(None) { 00275 callableWrapper = none; 00276 return *this; 00277 } 00278 00279 const Function & operator=(ResultType (*func)()) { 00280 if (func) { 00281 callableWrapper = func; 00282 } else { 00283 callableWrapper = none; 00284 } 00285 return *this; 00286 } 00287 00288 template <typename F> const Function & operator=(F func) { 00289 callableWrapper = func; 00290 return *this; 00291 } 00292 00293 void swap(Function & other) { callableWrapper.swap(other.callableWrapper); } 00294 00295 operator SafeBool() const { 00296 return makeSafeBool(callableWrapper.target() != NULL); 00297 } 00298 00299 ResultType operator()() const { 00300 return callableWrapper.target() ? callableWrapper.target()->invoke() 00301 : ResultType(); 00302 } 00303 00304 private: 00305 class Callable { 00306 public: 00307 virtual ~Callable() {} 00308 virtual ResultType invoke() const = 0; 00309 virtual Callable * clone() const = 0; 00310 virtual void clone(void * buffer) const = 0; 00311 }; 00312 00313 template <typename F> class CallableAdapter : public Callable { 00314 public: 00315 CallableAdapter(F func) : func(func) {} 00316 00317 virtual ResultType invoke() const { return func(); } 00318 00319 virtual Callable * clone() const { return new CallableAdapter(*this); } 00320 00321 virtual void clone(void * buffer) const { 00322 new (buffer) CallableAdapter(*this); 00323 } 00324 00325 private: 00326 F func; 00327 }; 00328 00329 detail::TypeWrapper<Callable, CallableAdapter> callableWrapper; 00330 }; 00331 00332 template <typename ResultType> 00333 void swap(Function<ResultType()> & lhs, Function<ResultType()> & rhs) { 00334 lhs.swap(rhs); 00335 } 00336 00337 /// Function implementation for one argument functions. 00338 template <typename ArgumentType, typename ResultType> 00339 class Function<ResultType(ArgumentType)> { 00340 public: 00341 typedef ArgumentType argument_type; 00342 typedef ResultType result_type; 00343 00344 Function() : callableWrapper() {} 00345 00346 Function(None) : callableWrapper() {} 00347 00348 Function(ResultType (*func)(ArgumentType)) : callableWrapper() { 00349 if (func) { 00350 callableWrapper = func; 00351 } 00352 } 00353 00354 template <typename F> Function(F func) : callableWrapper(func) {} 00355 00356 const Function & operator=(None) { 00357 callableWrapper = none; 00358 return *this; 00359 } 00360 00361 const Function & operator=(ResultType (*func)(ArgumentType)) { 00362 if (func) { 00363 callableWrapper = func; 00364 } else { 00365 callableWrapper = none; 00366 } 00367 return *this; 00368 } 00369 00370 template <typename F> const Function & operator=(F func) { 00371 callableWrapper = func; 00372 return *this; 00373 } 00374 00375 void swap(Function & other) { callableWrapper.swap(other.callableWrapper); } 00376 00377 operator SafeBool() const { 00378 return makeSafeBool(callableWrapper.target() != NULL); 00379 } 00380 00381 ResultType operator()(ArgumentType arg) const { 00382 return callableWrapper.target() ? callableWrapper.target()->invoke(arg) 00383 : ResultType(); 00384 } 00385 00386 private: 00387 class Callable { 00388 public: 00389 virtual ~Callable() {} 00390 virtual ResultType invoke(ArgumentType) const = 0; 00391 virtual Callable * clone() const = 0; 00392 virtual void clone(void * buffer) const = 0; 00393 }; 00394 00395 template <typename F> class CallableAdapter : public Callable { 00396 public: 00397 CallableAdapter(F func) : func(func) {} 00398 00399 virtual ResultType invoke(ArgumentType arg) const { return func(arg); } 00400 00401 virtual Callable * clone() const { return new CallableAdapter(*this); } 00402 00403 virtual void clone(void * buffer) const { 00404 new (buffer) CallableAdapter(*this); 00405 } 00406 00407 private: 00408 F func; 00409 }; 00410 00411 detail::TypeWrapper<Callable, CallableAdapter> callableWrapper; 00412 }; 00413 00414 template <typename ArgumentType, typename ResultType> 00415 void swap(Function<ResultType(ArgumentType)> & lhs, 00416 Function<ResultType(ArgumentType)> & rhs) { 00417 lhs.swap(rhs); 00418 } 00419 00420 /// Function implementation for two argument functions. 00421 template <typename FirstArgumentType, typename SecondArgumentType, 00422 typename ResultType> 00423 class Function<ResultType(FirstArgumentType, SecondArgumentType)> { 00424 public: 00425 typedef FirstArgumentType first_argument_type; 00426 typedef SecondArgumentType second_argument_type; 00427 typedef ResultType result_type; 00428 00429 Function() : callableWrapper() {} 00430 00431 Function(None) : callableWrapper() {} 00432 00433 Function(ResultType (*func)(FirstArgumentType, SecondArgumentType)) 00434 : callableWrapper() { 00435 if (func) { 00436 callableWrapper = func; 00437 } 00438 } 00439 00440 template <typename F> Function(F func) : callableWrapper(func) {} 00441 00442 const Function & operator=(None) { 00443 callableWrapper = none; 00444 return *this; 00445 } 00446 00447 const Function & operator=(ResultType (*func)(FirstArgumentType, 00448 SecondArgumentType)) { 00449 if (func) { 00450 callableWrapper = func; 00451 } else { 00452 callableWrapper = none; 00453 } 00454 return *this; 00455 } 00456 00457 template <typename F> const Function & operator=(F func) { 00458 callableWrapper = func; 00459 return *this; 00460 } 00461 00462 void swap(Function & other) { callableWrapper.swap(other.callableWrapper); } 00463 00464 operator SafeBool() const { 00465 return makeSafeBool(callableWrapper.target() != NULL); 00466 } 00467 00468 ResultType operator()(FirstArgumentType arg1, SecondArgumentType arg2) const { 00469 return callableWrapper.target() 00470 ? callableWrapper.target()->invoke(arg1, arg2) 00471 : ResultType(); 00472 } 00473 00474 private: 00475 class Callable { 00476 public: 00477 virtual ~Callable() {} 00478 virtual ResultType invoke(FirstArgumentType, SecondArgumentType) const = 0; 00479 virtual Callable * clone() const = 0; 00480 virtual void clone(void * buffer) const = 0; 00481 }; 00482 00483 template <typename F> class CallableAdapter : public Callable { 00484 public: 00485 CallableAdapter(F func) : func(func) {} 00486 00487 virtual ResultType invoke(FirstArgumentType arg1, 00488 SecondArgumentType arg2) const { 00489 return func(arg1, arg2); 00490 } 00491 00492 virtual Callable * clone() const { return new CallableAdapter(*this); } 00493 00494 virtual void clone(void * buffer) const { 00495 new (buffer) CallableAdapter(*this); 00496 } 00497 00498 private: 00499 F func; 00500 }; 00501 00502 detail::TypeWrapper<Callable, CallableAdapter> callableWrapper; 00503 }; 00504 00505 template <typename FirstArgumentType, typename SecondArgumentType, 00506 typename ResultType> 00507 void swap(Function<ResultType(FirstArgumentType, SecondArgumentType)> & lhs, 00508 Function<ResultType(FirstArgumentType, SecondArgumentType)> & rhs) { 00509 lhs.swap(rhs); 00510 } 00511 00512 /// Function implementation for three argument functions. 00513 template <typename FirstArgumentType, typename SecondArgumentType, 00514 typename ThirdArgumentType, typename ResultType> 00515 class Function<ResultType(FirstArgumentType, SecondArgumentType, 00516 ThirdArgumentType)> { 00517 public: 00518 typedef ResultType result_type; 00519 00520 Function() : callableWrapper() {} 00521 00522 Function(None) : callableWrapper() {} 00523 00524 Function(ResultType (*func)(FirstArgumentType, SecondArgumentType, 00525 ThirdArgumentType)) 00526 : callableWrapper() { 00527 if (func) { 00528 callableWrapper = func; 00529 } 00530 } 00531 00532 template <typename F> Function(F func) : callableWrapper(func) {} 00533 00534 const Function & operator=(None) { 00535 callableWrapper = none; 00536 return *this; 00537 } 00538 00539 const Function & operator=(ResultType (*func)(FirstArgumentType, 00540 SecondArgumentType, 00541 ThirdArgumentType)) { 00542 if (func) { 00543 callableWrapper = func; 00544 } else { 00545 callableWrapper = none; 00546 } 00547 return *this; 00548 } 00549 00550 template <typename F> const Function & operator=(F func) { 00551 callableWrapper = func; 00552 return *this; 00553 } 00554 00555 void swap(Function & other) { callableWrapper.swap(other.callableWrapper); } 00556 00557 operator SafeBool() const { 00558 return makeSafeBool(callableWrapper.target() != NULL); 00559 } 00560 00561 ResultType operator()(FirstArgumentType arg1, SecondArgumentType arg2, 00562 ThirdArgumentType arg3) const { 00563 return callableWrapper.target() 00564 ? callableWrapper.target()->invoke(arg1, arg2, arg3) 00565 : ResultType(); 00566 } 00567 00568 private: 00569 class Callable { 00570 public: 00571 virtual ~Callable() {} 00572 virtual ResultType invoke(FirstArgumentType, SecondArgumentType, 00573 ThirdArgumentType) const = 0; 00574 virtual Callable * clone() const = 0; 00575 virtual void clone(void * buffer) const = 0; 00576 }; 00577 00578 template <typename F> class CallableAdapter : public Callable { 00579 public: 00580 CallableAdapter(F func) : func(func) {} 00581 00582 virtual ResultType invoke(FirstArgumentType arg1, SecondArgumentType arg2, 00583 ThirdArgumentType arg3) const { 00584 return func(arg1, arg2, arg3); 00585 } 00586 00587 virtual Callable * clone() const { return new CallableAdapter(*this); } 00588 00589 virtual void clone(void * buffer) const { 00590 new (buffer) CallableAdapter(*this); 00591 } 00592 00593 private: 00594 F func; 00595 }; 00596 00597 detail::TypeWrapper<Callable, CallableAdapter> callableWrapper; 00598 }; 00599 00600 template <typename FirstArgumentType, typename SecondArgumentType, 00601 typename ThirdArgumentType, typename ResultType> 00602 void swap(Function<ResultType(FirstArgumentType, SecondArgumentType, 00603 ThirdArgumentType)> & lhs, 00604 Function<ResultType(FirstArgumentType, SecondArgumentType, 00605 ThirdArgumentType)> & rhs) { 00606 lhs.swap(rhs); 00607 } 00608 00609 } // namespace MaximInterfaceCore 00610 00611 #endif
Generated on Fri May 29 2020 21:20:48 by
