CppCMS
booster/system_error.h
00001 //
00002 //  Copyright (C) 2009-2012 Artyom Beilis (Tonkikh)
00003 //
00004 //  Distributed under the Boost Software License, Version 1.0. (See
00005 //  accompanying file LICENSE_1_0.txt or copy at
00006 //  http://www.boost.org/LICENSE_1_0.txt)
00007 //
00008 #ifndef BOOSTER_SYSTEM_ERROR_H
00009 #define BOOSTER_SYSTEM_ERROR_H
00010 
00011 #include <string>
00012 #include <booster/backtrace.h>
00013 #include <functional>
00014 
00015 #include <booster/config.h>
00016 
00017 namespace booster {
00018 
00023 namespace system {
00024 
00034         class error_category {
00035         public:
00036                 virtual ~error_category()
00037                 {
00038                 }
00042                 virtual char const *name() const = 0;
00046                 virtual std::string message(int ev) const = 0;
00047 
00048                 bool operator==(error_category const &other) const
00049                 {
00050                         return this==&other;
00051                 }
00052                 bool operator!=(error_category const &other) const
00053                 {
00054                         return this!=&other;
00055                 }
00056                 bool operator<(error_category const &other) const
00057                 {
00058                         return std::less<error_category const *>()(this,&other);
00059                 }
00060 
00061         };
00062 
00063         BOOSTER_API error_category const &get_system_category();
00064         static const error_category &system_category = get_system_category();
00065         
00066         #ifdef BOOSTER_WIN32
00067         BOOSTER_API error_category const &get_windows_category();
00068         static const error_category &windows_category = get_system_category();
00069         #endif
00070 
00071         #ifdef BOOSTER_POSIX
00072         BOOSTER_API error_category const &get_posix_category();
00073         static const error_category &posix_category = get_system_category();
00074         #endif
00075 
00076 
00083         class error_code {
00084         public:
00088                 error_code() : 
00089                         value_(0),
00090                         category_(&system_category)
00091                 {
00092                 }
00096                 error_code(int val,error_category const &cat) :
00097                         value_(val),
00098                         category_(&cat)
00099                 {
00100                 }
00104                 int value() const
00105                 {
00106                         return value_;
00107                 }
00111                 const error_category &category() const
00112                 {
00113                         return *category_;
00114                 }
00118                 std::string message() const
00119                 {
00120                         return std::string(category_->name()) + ": " + category_->message(value_);
00121                 }
00125                 operator bool () const
00126                 {
00127                         return value() != 0;
00128                 }
00129         private:
00130                 int value_;
00131                 error_category const *category_;
00132         };
00133 
00137         inline bool operator==(error_code const &left,error_code const &right)
00138         {
00139                 return left.value() == right.value() && left.category() == right.category(); 
00140         }
00144         inline bool operator!=(error_code const &left,error_code const &right)
00145         {
00146                 return !(left==right);
00147         }
00148 
00156         class system_error : public booster::runtime_error {
00157         public:
00161                 system_error(error_code const &e) :
00162                         booster::runtime_error(e.message()),
00163                         error_(e)
00164                 {
00165                 }
00169                 system_error(error_code const &e,std::string const &message) :
00170                         booster::runtime_error(e.message()+": " + message),
00171                         error_(e)
00172                 {
00173                 }
00177                 system_error(error_code const &e,char const *message) :
00178                         booster::runtime_error(e.message()+": " + message),
00179                         error_(e)
00180                 {
00181                 }
00186                 system_error(int ev,error_category const &category,char const *message) :
00187                         booster::runtime_error(
00188                                 std::string(category.name()) 
00189                                 + ": "  + category.message(ev) 
00190                                 + ": "  + message
00191                                 ),
00192                         error_(ev,category)
00193                 {
00194                 }
00199                 system_error(int ev,error_category const &category,std::string const &message) :
00200                         booster::runtime_error(
00201                                 std::string(category.name()) 
00202                                 + ": "  + category.message(ev) 
00203                                 + ": "  + message
00204                                 ),
00205                         error_(ev,category)
00206                 {
00207                 }
00212                 system_error(int ev,error_category const &category) :
00213                         booster::runtime_error(
00214                                 std::string(category.name()) 
00215                                 + ": "  + category.message(ev) 
00216                                 ),
00217                         error_(ev,category)
00218                 {
00219                 }
00223                 error_code const &code() const
00224                 {
00225                         return error_;
00226                 }
00227         private:
00228                 error_code error_;
00229         };
00230 
00231 } // system
00232 } // booster
00233 
00234 
00235 #endif