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

Revision:
8:5ea891c7d1a1
Parent:
7:9cd16581b578
Child:
11:3f3bf6bf5e6c
--- a/MaximInterfaceCore/Function.hpp	Mon Jul 22 11:44:07 2019 -0500
+++ b/MaximInterfaceCore/Function.hpp	Mon Sep 16 11:13:37 2019 -0500
@@ -1,5 +1,5 @@
 /*******************************************************************************
-* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
+* Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -30,10 +30,11 @@
 * ownership rights.
 *******************************************************************************/
 
-#ifndef MaximInterfaceCore_Function
-#define MaximInterfaceCore_Function
+#ifndef MaximInterfaceCore_Function_hpp
+#define MaximInterfaceCore_Function_hpp
 
 #include <stddef.h>
+#include "None.hpp"
 #include "SafeBool.hpp"
 #include "type_traits.hpp"
 
@@ -112,6 +113,8 @@
 public:
   TypeWrapper() : currentTarget(NULL) {}
 
+  TypeWrapper(None) : currentTarget(NULL) {}
+
   TypeWrapper(const TypeWrapper & other) {
     if (other.currentTarget == other.internalTarget) {
       other.currentTarget->clone(internalTarget);
@@ -142,6 +145,11 @@
     }
   }
 
+  const TypeWrapper & operator=(None) {
+    TypeWrapper().swap(*this);
+    return *this;
+  }
+
   const TypeWrapper & operator=(const TypeWrapper & rhs) {
     TypeWrapper(rhs).swap(*this);
     return *this;
@@ -152,8 +160,6 @@
     return *this;
   }
 
-  void clear() { TypeWrapper().swap(*this); }
-
   void swap(TypeWrapper & other) {
     if (this == &other) {
       return;
@@ -201,6 +207,8 @@
 public:
   TypeWrapper() : currentTarget(NULL) {}
 
+  TypeWrapper(None) : currentTarget(NULL) {}
+
   TypeWrapper(const TypeWrapper & other) {
     if (other.currentTarget) {
       currentTarget = other.currentTarget->clone();
@@ -215,6 +223,11 @@
 
   ~TypeWrapper() { delete currentTarget; }
 
+  const TypeWrapper & operator=(None) {
+    TypeWrapper().swap(*this);
+    return *this;
+  }
+
   const TypeWrapper & operator=(const TypeWrapper & rhs) {
     TypeWrapper(rhs).swap(*this);
     return *this;
@@ -225,8 +238,6 @@
     return *this;
   }
 
-  void clear() { TypeWrapper().swap(*this); }
-
   void swap(TypeWrapper & other) {
     using std::swap;
     swap(currentTarget, other.currentTarget);
@@ -240,15 +251,19 @@
 
 } // namespace detail
 
-// Function wrapper similar to std::function for 0-3 argument functions.
+/// %Function wrapper similar to std::function for 0-3 argument functions.
 template <typename> class Function;
 
-// Function implementation for zero argument functions.
+/// Function implementation for zero argument functions.
 template <typename ResultType> class Function<ResultType()> {
 public:
   typedef ResultType result_type;
 
-  Function(ResultType (*func)() = NULL) : callableWrapper() {
+  Function() : callableWrapper() {}
+
+  Function(None) : callableWrapper() {}
+
+  Function(ResultType (*func)()) : callableWrapper() {
     if (func) {
       callableWrapper = func;
     }
@@ -256,11 +271,16 @@
 
   template <typename F> Function(F func) : callableWrapper(func) {}
 
+  const Function & operator=(None) {
+    callableWrapper = none;
+    return *this;
+  }
+
   const Function & operator=(ResultType (*func)()) {
     if (func) {
       callableWrapper = func;
     } else {
-      callableWrapper.clear();
+      callableWrapper = none;
     }
     return *this;
   }
@@ -314,14 +334,18 @@
   lhs.swap(rhs);
 }
 
-// Function implementation for one argument functions.
+/// Function implementation for one argument functions.
 template <typename ArgumentType, typename ResultType>
 class Function<ResultType(ArgumentType)> {
 public:
   typedef ArgumentType argument_type;
   typedef ResultType result_type;
 
-  Function(ResultType (*func)(ArgumentType) = NULL) : callableWrapper() {
+  Function() : callableWrapper() {}
+
+  Function(None) : callableWrapper() {}
+
+  Function(ResultType (*func)(ArgumentType)) : callableWrapper() {
     if (func) {
       callableWrapper = func;
     }
@@ -329,11 +353,16 @@
 
   template <typename F> Function(F func) : callableWrapper(func) {}
 
+  const Function & operator=(None) {
+    callableWrapper = none;
+    return *this;
+  }
+
   const Function & operator=(ResultType (*func)(ArgumentType)) {
     if (func) {
       callableWrapper = func;
     } else {
-      callableWrapper.clear();
+      callableWrapper = none;
     }
     return *this;
   }
@@ -388,7 +417,7 @@
   lhs.swap(rhs);
 }
 
-// Function implementation for two argument functions.
+/// Function implementation for two argument functions.
 template <typename FirstArgumentType, typename SecondArgumentType,
           typename ResultType>
 class Function<ResultType(FirstArgumentType, SecondArgumentType)> {
@@ -397,7 +426,11 @@
   typedef SecondArgumentType second_argument_type;
   typedef ResultType result_type;
 
-  Function(ResultType (*func)(FirstArgumentType, SecondArgumentType) = NULL)
+  Function() : callableWrapper() {}
+
+  Function(None) : callableWrapper() {}
+
+  Function(ResultType (*func)(FirstArgumentType, SecondArgumentType))
       : callableWrapper() {
     if (func) {
       callableWrapper = func;
@@ -406,12 +439,17 @@
 
   template <typename F> Function(F func) : callableWrapper(func) {}
 
+  const Function & operator=(None) {
+    callableWrapper = none;
+    return *this;
+  }
+
   const Function & operator=(ResultType (*func)(FirstArgumentType,
                                                 SecondArgumentType)) {
     if (func) {
       callableWrapper = func;
     } else {
-      callableWrapper.clear();
+      callableWrapper = none;
     }
     return *this;
   }
@@ -472,7 +510,7 @@
   lhs.swap(rhs);
 }
 
-// Function implementation for three argument functions.
+/// Function implementation for three argument functions.
 template <typename FirstArgumentType, typename SecondArgumentType,
           typename ThirdArgumentType, typename ResultType>
 class Function<ResultType(FirstArgumentType, SecondArgumentType,
@@ -480,8 +518,12 @@
 public:
   typedef ResultType result_type;
 
+  Function() : callableWrapper() {}
+
+  Function(None) : callableWrapper() {}
+
   Function(ResultType (*func)(FirstArgumentType, SecondArgumentType,
-                              ThirdArgumentType) = NULL)
+                              ThirdArgumentType))
       : callableWrapper() {
     if (func) {
       callableWrapper = func;
@@ -490,13 +532,18 @@
 
   template <typename F> Function(F func) : callableWrapper(func) {}
 
+  const Function & operator=(None) {
+    callableWrapper = none;
+    return *this;
+  }
+
   const Function & operator=(ResultType (*func)(FirstArgumentType,
                                                 SecondArgumentType,
                                                 ThirdArgumentType)) {
     if (func) {
       callableWrapper = func;
     } else {
-      callableWrapper.clear();
+      callableWrapper = none;
     }
     return *this;
   }