Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Function.hpp Source File

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