Aleksandrs Gumenuks / MaximInterface_Extended

Dependents:   mbed_DS28EC20_GPIO

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Function.hpp Source File

Function.hpp

00001 /*******************************************************************************
00002 * Copyright (C) 2017 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 MaximInterface_Function
00034 #define MaximInterface_Function
00035 
00036 #include <stddef.h>
00037 #include "SafeBool.hpp"
00038 #include "type_traits.hpp"
00039 
00040 // Include for std::swap.
00041 #include <algorithm>
00042 #include <utility>
00043 
00044 namespace MaximInterface {
00045 namespace detail {
00046 
00047 // Provides char buffer storage for a given type.
00048 // Suitability of alignment for type should be verified with alignment_of.
00049 template <typename Type, size_t TypeSize> union TypeStorage {
00050 public:
00051   operator const Type *() const { return reinterpret_cast<const Type *>(data); }
00052 
00053   operator Type *() {
00054     return const_cast<Type *>(
00055         static_cast<const Type *>(static_cast<const TypeStorage &>(*this)));
00056   }
00057 
00058   const Type & operator*() const { return **this; }
00059 
00060   Type & operator*() {
00061     return const_cast<Type &>(
00062         static_cast<const TypeStorage &>(*this).operator*());
00063   }
00064 
00065   const Type * operator->() const { return *this; }
00066 
00067   Type * operator->() {
00068     return const_cast<Type *>(
00069         static_cast<const TypeStorage &>(*this).operator->());
00070   }
00071 
00072 private:
00073   char data[TypeSize];
00074   long double aligner1;
00075   long int aligner2;
00076   void * aligner3;
00077 };
00078 
00079 // Computes the internal target size for TypeStorage based on a desired total
00080 // size. No internal storage will be allocated if the requested size is smaller
00081 // than the required data elements of TypeWrapper or if the requested size is
00082 // smaller than minimum size of TypeStorage.
00083 template <typename Target, size_t totalSize> class TypeWrapperTotalSize {
00084 private:
00085   typedef TypeStorage<Target, 1> MinSizeStorage;
00086   
00087   static const size_t otherDataSize = sizeof(Target *);
00088   
00089   // Round down to be a multiple of alignment_of<MinSizeTargetStorage>::value.
00090   static const size_t internalTargetRawSize =
00091       (totalSize - otherDataSize) / alignment_of<MinSizeStorage>::value *
00092       alignment_of<MinSizeStorage>::value;
00093 
00094 public:
00095   // Use internal storage if internalTargetRawSize is valid and at least as
00096   // large as the minimum size of TypeStorage.
00097   static const size_t internalTargetSize =
00098       ((totalSize > otherDataSize) &&
00099        (internalTargetRawSize >= sizeof(MinSizeStorage)))
00100           ? internalTargetRawSize
00101           : 0;
00102 };
00103 
00104 // Basic type erasure implementation with small object optimization.
00105 template <typename Target, template <typename> class TargetAdapter,
00106           size_t internalTargetSize =
00107               TypeWrapperTotalSize<Target, 32>::internalTargetSize>
00108 class TypeWrapper {
00109 private:
00110   typedef TypeStorage<Target, internalTargetSize> TargetStorage;
00111 
00112 public:
00113   TypeWrapper() : currentTarget(NULL) {}
00114 
00115   TypeWrapper(const TypeWrapper & other) {
00116     if (other.currentTarget == other.internalTarget) {
00117       other.currentTarget->clone(internalTarget);
00118       currentTarget = internalTarget;
00119     } else if (other.currentTarget) {
00120       currentTarget = other.currentTarget->clone();
00121     } else {
00122       currentTarget = NULL;
00123     }
00124   }
00125 
00126   template <typename Source> TypeWrapper(Source source) {
00127     if (sizeof(TargetAdapter<Source>) <= internalTargetSize &&
00128         alignment_of<TargetAdapter<Source> >::value <=
00129             alignment_of<TargetStorage>::value) {
00130       new (internalTarget) TargetAdapter<Source>(source);
00131       currentTarget = internalTarget;
00132     } else {
00133       currentTarget = new TargetAdapter<Source>(source);
00134     }
00135   }
00136 
00137   ~TypeWrapper() {
00138     if (currentTarget == internalTarget) {
00139       currentTarget->~Target();
00140     } else {
00141       delete currentTarget;
00142     }
00143   }
00144 
00145   const TypeWrapper & operator=(const TypeWrapper & rhs) {
00146     TypeWrapper(rhs).swap(*this);
00147     return *this;
00148   }
00149 
00150   template <typename Source> const TypeWrapper & operator=(Source source) {
00151     TypeWrapper(source).swap(*this);
00152     return *this;
00153   }
00154 
00155   void clear() { TypeWrapper().swap(*this); }
00156 
00157   void swap(TypeWrapper & other) {
00158     if (this == &other) {
00159       return;
00160     }
00161 
00162     if (currentTarget == internalTarget &&
00163         other.currentTarget == other.internalTarget) {
00164       TargetStorage temp;
00165       currentTarget->clone(temp);
00166       currentTarget->~Target();
00167       currentTarget = NULL;
00168       other.currentTarget->clone(internalTarget);
00169       other.currentTarget->~Target();
00170       other.currentTarget = NULL;
00171       currentTarget = internalTarget;
00172       temp->clone(other.internalTarget);
00173       temp->~Target();
00174       other.currentTarget = other.internalTarget;
00175     } else if (currentTarget == internalTarget) {
00176       currentTarget->clone(other.internalTarget);
00177       currentTarget->~Target();
00178       currentTarget = other.currentTarget;
00179       other.currentTarget = other.internalTarget;
00180     } else if (other.currentTarget == other.internalTarget) {
00181       other.currentTarget->clone(internalTarget);
00182       other.currentTarget->~Target();
00183       other.currentTarget = currentTarget;
00184       currentTarget = internalTarget;
00185     } else {
00186       using std::swap;
00187       swap(currentTarget, other.currentTarget);
00188     }
00189   }
00190 
00191   const Target * target() const { return currentTarget; }
00192 
00193 private:
00194   TargetStorage internalTarget;
00195   Target * currentTarget;
00196 };
00197 
00198 // TypeWrapper specialization with no internal storage space.
00199 template <typename Target, template <typename> class TargetAdapter>
00200 class TypeWrapper<Target, TargetAdapter, 0> {
00201 public:
00202   TypeWrapper() : currentTarget(NULL) {}
00203 
00204   TypeWrapper(const TypeWrapper & other) {
00205     if (other.currentTarget) {
00206       currentTarget = other.currentTarget->clone();
00207     } else {
00208       currentTarget = NULL;
00209     }
00210   }
00211 
00212   template <typename Source>
00213   TypeWrapper(Source source)
00214       : currentTarget(new TargetAdapter<Source>(source)) {}
00215 
00216   ~TypeWrapper() { delete currentTarget; }
00217 
00218   const TypeWrapper & operator=(const TypeWrapper & rhs) {
00219     TypeWrapper(rhs).swap(*this);
00220     return *this;
00221   }
00222 
00223   template <typename Source> const TypeWrapper & operator=(Source source) {
00224     TypeWrapper(source).swap(*this);
00225     return *this;
00226   }
00227 
00228   void clear() { TypeWrapper().swap(*this); }
00229 
00230   void swap(TypeWrapper & other) {
00231     using std::swap;
00232     swap(currentTarget, other.currentTarget);
00233   }
00234 
00235   const Target * target() const { return currentTarget; }
00236 
00237 private:
00238   Target * currentTarget;
00239 };
00240 
00241 } // namespace detail
00242 
00243 // Function wrapper similar to std::function for 0-3 argument functions.
00244 template <typename> class Function;
00245 
00246 // Function implementation for zero argument functions.
00247 template <typename ResultType> class Function<ResultType()> {
00248 public:
00249   typedef ResultType result_type;
00250 
00251   Function(ResultType (*func)() = NULL) : callableWrapper() {
00252     if (func) {
00253       callableWrapper = func;
00254     }
00255   }
00256 
00257   template <typename F> Function(F func) : callableWrapper(func) {}
00258 
00259   const Function & operator=(ResultType (*func)()) {
00260     if (func) {
00261       callableWrapper = func;
00262     } else {
00263       callableWrapper.clear();
00264     }
00265     return *this;
00266   }
00267 
00268   template <typename F> const Function & operator=(F func) {
00269     callableWrapper = func;
00270     return *this;
00271   }
00272 
00273   void swap(Function & other) { callableWrapper.swap(other.callableWrapper); }
00274 
00275   operator SafeBool() const {
00276     return makeSafeBool(callableWrapper.target() != NULL);
00277   }
00278 
00279   ResultType operator()() const {
00280     return callableWrapper.target() ? callableWrapper.target()->invoke()
00281                                     : ResultType();
00282   }
00283 
00284 private:
00285   class Callable {
00286   public:
00287     virtual ~Callable() {}
00288     virtual ResultType invoke() const = 0;
00289     virtual Callable * clone() const = 0;
00290     virtual void clone(void * buffer) const = 0;
00291   };
00292 
00293   template <typename F> class CallableAdapter : public Callable {
00294   public:
00295     CallableAdapter(F func) : func(func) {}
00296 
00297     virtual ResultType invoke() const { return func(); }
00298 
00299     virtual Callable * clone() const { return new CallableAdapter(*this); }
00300 
00301     virtual void clone(void * buffer) const {
00302       new (buffer) CallableAdapter(*this);
00303     }
00304 
00305   private:
00306     F func;
00307   };
00308 
00309   detail::TypeWrapper<Callable, CallableAdapter> callableWrapper;
00310 };
00311 
00312 template <typename ResultType>
00313 inline void swap(Function<ResultType()> & lhs, Function<ResultType()> & rhs) {
00314   lhs.swap(rhs);
00315 }
00316 
00317 // Function implementation for one argument functions.
00318 template <typename ArgumentType, typename ResultType>
00319 class Function<ResultType(ArgumentType)> {
00320 public:
00321   typedef ArgumentType argument_type;
00322   typedef ResultType result_type;
00323 
00324   Function(ResultType (*func)(ArgumentType) = NULL) : callableWrapper() {
00325     if (func) {
00326       callableWrapper = func;
00327     }
00328   }
00329 
00330   template <typename F> Function(F func) : callableWrapper(func) {}
00331 
00332   const Function & operator=(ResultType (*func)(ArgumentType)) {
00333     if (func) {
00334       callableWrapper = func;
00335     } else {
00336       callableWrapper.clear();
00337     }
00338     return *this;
00339   }
00340 
00341   template <typename F> const Function & operator=(F func) {
00342     callableWrapper = func;
00343     return *this;
00344   }
00345 
00346   void swap(Function & other) { callableWrapper.swap(other.callableWrapper); }
00347 
00348   operator SafeBool() const {
00349     return makeSafeBool(callableWrapper.target() != NULL);
00350   }
00351 
00352   ResultType operator()(ArgumentType arg) const {
00353     return callableWrapper.target() ? callableWrapper.target()->invoke(arg)
00354                                     : ResultType();
00355   }
00356 
00357 private:
00358   class Callable {
00359   public:
00360     virtual ~Callable() {}
00361     virtual ResultType invoke(ArgumentType) const = 0;
00362     virtual Callable * clone() const = 0;
00363     virtual void clone(void * buffer) const = 0;
00364   };
00365 
00366   template <typename F> class CallableAdapter : public Callable {
00367   public:
00368     CallableAdapter(F func) : func(func) {}
00369 
00370     virtual ResultType invoke(ArgumentType arg) const { return func(arg); }
00371 
00372     virtual Callable * clone() const { return new CallableAdapter(*this); }
00373 
00374     virtual void clone(void * buffer) const {
00375       new (buffer) CallableAdapter(*this);
00376     }
00377 
00378   private:
00379     F func;
00380   };
00381 
00382   detail::TypeWrapper<Callable, CallableAdapter> callableWrapper;
00383 };
00384 
00385 template <typename ArgumentType, typename ResultType>
00386 inline void swap(Function<ResultType(ArgumentType)> & lhs,
00387                  Function<ResultType(ArgumentType)> & rhs) {
00388   lhs.swap(rhs);
00389 }
00390 
00391 // Function implementation for two argument functions.
00392 template <typename FirstArgumentType, typename SecondArgumentType,
00393           typename ResultType>
00394 class Function<ResultType(FirstArgumentType, SecondArgumentType)> {
00395 public:
00396   typedef FirstArgumentType first_argument_type;
00397   typedef SecondArgumentType second_argument_type;
00398   typedef ResultType result_type;
00399 
00400   Function(ResultType (*func)(FirstArgumentType, SecondArgumentType) = NULL)
00401       : callableWrapper() {
00402     if (func) {
00403       callableWrapper = func;
00404     }
00405   }
00406 
00407   template <typename F> Function(F func) : callableWrapper(func) {}
00408 
00409   const Function & operator=(ResultType (*func)(FirstArgumentType,
00410                                                 SecondArgumentType)) {
00411     if (func) {
00412       callableWrapper = func;
00413     } else {
00414       callableWrapper.clear();
00415     }
00416     return *this;
00417   }
00418 
00419   template <typename F> const Function & operator=(F func) {
00420     callableWrapper = func;
00421     return *this;
00422   }
00423 
00424   void swap(Function & other) { callableWrapper.swap(other.callableWrapper); }
00425 
00426   operator SafeBool() const {
00427     return makeSafeBool(callableWrapper.target() != NULL);
00428   }
00429 
00430   ResultType operator()(FirstArgumentType arg1, SecondArgumentType arg2) const {
00431     return callableWrapper.target()
00432                ? callableWrapper.target()->invoke(arg1, arg2)
00433                : ResultType();
00434   }
00435 
00436 private:
00437   class Callable {
00438   public:
00439     virtual ~Callable() {}
00440     virtual ResultType invoke(FirstArgumentType, SecondArgumentType) const = 0;
00441     virtual Callable * clone() const = 0;
00442     virtual void clone(void * buffer) const = 0;
00443   };
00444 
00445   template <typename F> class CallableAdapter : public Callable {
00446   public:
00447     CallableAdapter(F func) : func(func) {}
00448 
00449     virtual ResultType invoke(FirstArgumentType arg1,
00450                               SecondArgumentType arg2) const {
00451       return func(arg1, arg2);
00452     }
00453 
00454     virtual Callable * clone() const { return new CallableAdapter(*this); }
00455 
00456     virtual void clone(void * buffer) const {
00457       new (buffer) CallableAdapter(*this);
00458     }
00459 
00460   private:
00461     F func;
00462   };
00463 
00464   detail::TypeWrapper<Callable, CallableAdapter> callableWrapper;
00465 };
00466 
00467 template <typename FirstArgumentType, typename SecondArgumentType,
00468           typename ResultType>
00469 inline void
00470 swap(Function<ResultType(FirstArgumentType, SecondArgumentType)> & lhs,
00471      Function<ResultType(FirstArgumentType, SecondArgumentType)> & rhs) {
00472   lhs.swap(rhs);
00473 }
00474 
00475 // Function implementation for three argument functions.
00476 template <typename FirstArgumentType, typename SecondArgumentType,
00477           typename ThirdArgumentType, typename ResultType>
00478 class Function<ResultType(FirstArgumentType, SecondArgumentType,
00479                           ThirdArgumentType)> {
00480 public:
00481   typedef ResultType result_type;
00482 
00483   Function(ResultType (*func)(FirstArgumentType, SecondArgumentType,
00484                               ThirdArgumentType) = NULL)
00485       : callableWrapper() {
00486     if (func) {
00487       callableWrapper = func;
00488     }
00489   }
00490 
00491   template <typename F> Function(F func) : callableWrapper(func) {}
00492 
00493   const Function & operator=(ResultType (*func)(FirstArgumentType,
00494                                                 SecondArgumentType,
00495                                                 ThirdArgumentType)) {
00496     if (func) {
00497       callableWrapper = func;
00498     } else {
00499       callableWrapper.clear();
00500     }
00501     return *this;
00502   }
00503 
00504   template <typename F> const Function & operator=(F func) {
00505     callableWrapper = func;
00506     return *this;
00507   }
00508 
00509   void swap(Function & other) { callableWrapper.swap(other.callableWrapper); }
00510 
00511   operator SafeBool() const {
00512     return makeSafeBool(callableWrapper.target() != NULL);
00513   }
00514 
00515   ResultType operator()(FirstArgumentType arg1, SecondArgumentType arg2,
00516                         ThirdArgumentType arg3) const {
00517     return callableWrapper.target()
00518                ? callableWrapper.target()->invoke(arg1, arg2, arg3)
00519                : ResultType();
00520   }
00521 
00522 private:
00523   class Callable {
00524   public:
00525     virtual ~Callable() {}
00526     virtual ResultType invoke(FirstArgumentType, SecondArgumentType,
00527                               ThirdArgumentType) const = 0;
00528     virtual Callable * clone() const = 0;
00529     virtual void clone(void * buffer) const = 0;
00530   };
00531 
00532   template <typename F> class CallableAdapter : public Callable {
00533   public:
00534     CallableAdapter(F func) : func(func) {}
00535 
00536     virtual ResultType invoke(FirstArgumentType arg1, SecondArgumentType arg2,
00537                               ThirdArgumentType arg3) const {
00538       return func(arg1, arg2, arg3);
00539     }
00540 
00541     virtual Callable * clone() const { return new CallableAdapter(*this); }
00542 
00543     virtual void clone(void * buffer) const {
00544       new (buffer) CallableAdapter(*this);
00545     }
00546 
00547   private:
00548     F func;
00549   };
00550 
00551   detail::TypeWrapper<Callable, CallableAdapter> callableWrapper;
00552 };
00553 
00554 template <typename FirstArgumentType, typename SecondArgumentType,
00555           typename ThirdArgumentType, typename ResultType>
00556 inline void swap(Function<ResultType(FirstArgumentType, SecondArgumentType,
00557                                      ThirdArgumentType)> & lhs,
00558                  Function<ResultType(FirstArgumentType, SecondArgumentType,
00559                                      ThirdArgumentType)> & rhs) {
00560   lhs.swap(rhs);
00561 }
00562 
00563 } // namespace MaximInterface
00564 
00565 #endif