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 system_error.hpp Source File

system_error.hpp

Go to the documentation of this file.
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 /// @file
00034 /// @brief
00035 /// Error handling constructs similar to std::error_code, std::error_condition,
00036 /// and std::error_category.
00037 
00038 #ifndef MaximInterfaceCore_system_error_hpp
00039 #define MaximInterfaceCore_system_error_hpp
00040 
00041 #include <stddef.h>
00042 #include <stdexcept>
00043 #include <string>
00044 #include "Config.hpp"
00045 #include "SafeBool.hpp"
00046 #include "type_traits.hpp"
00047 #include "Uncopyable.hpp"
00048 
00049 namespace MaximInterfaceCore {
00050 
00051 class error_condition;
00052 class error_code;
00053 
00054 /// Error category interface.
00055 class error_category : private Uncopyable {
00056 public:
00057   virtual ~error_category() {}
00058 
00059   virtual const char * name() const = 0;
00060 
00061   MaximInterfaceCore_EXPORT virtual error_condition
00062   default_error_condition(int code) const;
00063 
00064   MaximInterfaceCore_EXPORT virtual bool
00065   equivalent(int code, const error_condition & condition) const;
00066 
00067   MaximInterfaceCore_EXPORT virtual bool equivalent(const error_code & code,
00068                                                     int condition) const;
00069 
00070   virtual std::string message(int condition) const = 0;
00071 };
00072 
00073 inline bool operator==(const error_category & lhs, const error_category & rhs) {
00074   return &lhs == &rhs;
00075 }
00076 
00077 inline bool operator!=(const error_category & lhs, const error_category & rhs) {
00078   return !operator==(lhs, rhs);
00079 }
00080 
00081 inline bool operator<(const error_category & lhs, const error_category & rhs) {
00082   return &lhs < &rhs;
00083 }
00084 
00085 /// Default error category.
00086 MaximInterfaceCore_EXPORT const error_category & system_category();
00087 
00088 /// Checks if an enum type is implicitly convertible to an error_condition.
00089 template <typename T> struct is_error_condition_enum : false_type {};
00090 
00091 /// @brief
00092 /// Used for classifying groups of error_code into higher-level error conditions
00093 /// through the error_category::equivalent methods.
00094 class error_condition {
00095 public:
00096   error_condition() : value_(0), category_(&system_category()) {}
00097 
00098   error_condition(int value, const error_category & category)
00099       : value_(value), category_(&category) {}
00100 
00101   template <typename ErrorConditionEnum>
00102   error_condition(
00103       ErrorConditionEnum e,
00104       typename enable_if<
00105           is_error_condition_enum<ErrorConditionEnum>::value>::type * = NULL) {
00106     *this = make_error_condition(e);
00107   }
00108 
00109   template <typename ErrorConditionEnum>
00110   typename enable_if<is_error_condition_enum<ErrorConditionEnum>::value,
00111                      error_condition &>::type
00112   operator=(ErrorConditionEnum e) {
00113     *this = make_error_condition(e);
00114     return *this;
00115   }
00116 
00117   void assign(int value, const error_category & category) {
00118     value_ = value;
00119     category_ = &category;
00120   }
00121 
00122   void clear() {
00123     value_ = 0;
00124     category_ = &system_category();
00125   }
00126 
00127   int value() const { return value_; }
00128 
00129   const error_category & category() const { return *category_; }
00130 
00131   std::string message() const { return category().message(value()); }
00132 
00133   operator SafeBool() const { return makeSafeBool(value() != 0); }
00134 
00135 private:
00136   int value_;
00137   const error_category * category_;
00138 };
00139 
00140 inline bool operator==(const error_condition & lhs,
00141                        const error_condition & rhs) {
00142   return (lhs.value() == rhs.value()) && (lhs.category() == rhs.category());
00143 }
00144 
00145 inline bool operator!=(const error_condition & lhs,
00146                        const error_condition & rhs) {
00147   return !operator==(lhs, rhs);
00148 }
00149 
00150 inline bool operator<(const error_condition & lhs,
00151                       const error_condition & rhs) {
00152   return (lhs.category() < rhs.category()) ||
00153          ((lhs.category() == rhs.category()) && (lhs.value() < rhs.value()));
00154 }
00155 
00156 /// Checks if an enum type is implicitly convertible to an error_code.
00157 template <typename T> struct is_error_code_enum : false_type {};
00158 
00159 /// @brief Holds a raw error code produced by a subsystem.
00160 /// @details
00161 /// An error_code is composed of a pair of values: a category of errors, usually
00162 /// one per subsystem, and a number representing a specific error value within
00163 /// that category. While not required, zero is typically used as the success
00164 /// value so that the boolean conversion can be used as a failure test.
00165 class error_code {
00166 public:
00167   error_code() : value_(0), category_(&system_category()) {}
00168 
00169   error_code(int value, const error_category & category)
00170       : value_(value), category_(&category) {}
00171 
00172   template <typename ErrorCodeEnum>
00173   error_code(
00174       ErrorCodeEnum e,
00175       typename enable_if<is_error_code_enum<ErrorCodeEnum>::value>::type * =
00176           NULL) {
00177     *this = make_error_code(e);
00178   }
00179 
00180   template <typename ErrorCodeEnum>
00181   typename enable_if<is_error_code_enum<ErrorCodeEnum>::value,
00182                      error_code &>::type
00183   operator=(ErrorCodeEnum e) {
00184     *this = make_error_code(e);
00185     return *this;
00186   }
00187 
00188   void assign(int value, const error_category & category) {
00189     value_ = value;
00190     category_ = &category;
00191   }
00192 
00193   void clear() {
00194     value_ = 0;
00195     category_ = &system_category();
00196   }
00197 
00198   int value() const { return value_; }
00199 
00200   const error_category & category() const { return *category_; }
00201 
00202   error_condition default_error_condition() const {
00203     return category().default_error_condition(value());
00204   }
00205 
00206   std::string message() const { return category().message(value()); }
00207 
00208   operator SafeBool() const { return makeSafeBool(value() != 0); }
00209 
00210 private:
00211   int value_;
00212   const error_category * category_;
00213 };
00214 
00215 inline bool operator==(const error_code & lhs, const error_code & rhs) {
00216   return (lhs.value() == rhs.value()) && (lhs.category() == rhs.category());
00217 }
00218 
00219 inline bool operator!=(const error_code & lhs, const error_code & rhs) {
00220   return !operator==(lhs, rhs);
00221 }
00222 
00223 inline bool operator<(const error_code & lhs, const error_code & rhs) {
00224   return (lhs.category() < rhs.category()) ||
00225          ((lhs.category() == rhs.category()) && (lhs.value() < rhs.value()));
00226 }
00227 
00228 template <typename CharT, typename Traits>
00229 std::basic_ostream<CharT, Traits> &
00230 operator<<(std::basic_ostream<CharT, Traits> & os, const error_code & ec) {
00231   os << ec.category().name() << ':' << ec.value();
00232   return os;
00233 }
00234 
00235 inline bool operator==(const error_code & lhs, const error_condition & rhs) {
00236   return lhs.category().equivalent(lhs.value(), rhs) ||
00237          rhs.category().equivalent(lhs, rhs.value());
00238 }
00239 
00240 inline bool operator!=(const error_code & lhs, const error_condition & rhs) {
00241   return !operator==(lhs, rhs);
00242 }
00243 
00244 inline bool operator==(const error_condition & lhs, const error_code & rhs) {
00245   return operator==(rhs, lhs);
00246 }
00247 
00248 inline bool operator!=(const error_condition & lhs, const error_code & rhs) {
00249   return !operator==(lhs, rhs);
00250 }
00251 
00252 /// Wrapper for throwing error_code as an exception.
00253 class system_error : public std::runtime_error {
00254 public:
00255   MaximInterfaceCore_EXPORT system_error(const error_code & ec);
00256 
00257   MaximInterfaceCore_EXPORT system_error(const error_code & ec,
00258                                          const std::string & what_arg);
00259 
00260   MaximInterfaceCore_EXPORT system_error(const error_code & ec,
00261                                          const char * what_arg);
00262 
00263   MaximInterfaceCore_EXPORT system_error(int ev, const error_category & ecat);
00264 
00265   MaximInterfaceCore_EXPORT system_error(int ev, const error_category & ecat,
00266                                          const std::string & what_arg);
00267 
00268   MaximInterfaceCore_EXPORT system_error(int ev, const error_category & ecat,
00269                                          const char * what_arg);
00270 
00271   const error_code & code() const { return code_; }
00272 
00273 private:
00274   error_code code_;
00275 };
00276 
00277 } // namespace MaximInterfaceCore
00278 
00279 #endif