system_error

Go to the documentation of this file.
00001 // <system_error> -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file system_error
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_SYSTEM_ERROR
00030 #define _GLIBCXX_SYSTEM_ERROR 1
00031 
00032 #pragma GCC system_header
00033 
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <c++0x_warning.h>
00036 #else
00037 
00038 #include <bits/c++config.h>
00039 #include <bits/error_constants.h>
00040 #include <iosfwd>
00041 #include <stdexcept>
00042 
00043 _GLIBCXX_BEGIN_NAMESPACE(std)
00044 
00045   class error_code;
00046   class error_condition;
00047   class error_category;
00048   class system_error;
00049 
00050   /// is_error_code_enum
00051   template<typename _Tp>
00052     struct is_error_code_enum : public false_type { };
00053 
00054   template<> 
00055     struct is_error_code_enum<errc>
00056     : public true_type { };
00057 
00058   /// is_error_condition_enum
00059   template<typename _Tp>
00060     struct is_error_condition_enum : public false_type { };
00061 
00062   template<> 
00063     struct is_error_condition_enum<errc>
00064     : public true_type { };
00065 
00066 
00067   /// error_category
00068   class error_category
00069   {
00070   protected:
00071     error_category() = default;
00072 
00073   public:
00074     virtual ~error_category() { }
00075 
00076     error_category(const error_category&) = delete;
00077     error_category& operator=(const error_category&) = delete;
00078 
00079     virtual const char* 
00080     name() const = 0;
00081 
00082     virtual string 
00083     message(int) const = 0;
00084 
00085     virtual error_condition
00086     default_error_condition(int __i) const;
00087 
00088     virtual bool 
00089     equivalent(int __i, const error_condition& __cond) const;
00090 
00091     virtual bool 
00092     equivalent(const error_code& __code, int __i) const;
00093 
00094     bool 
00095     operator<(const error_category& __other) const
00096     { return less<const error_category*>()(this, &__other); }
00097 
00098     bool 
00099     operator==(const error_category& __other) const
00100     { return this == &__other; }
00101 
00102     bool 
00103     operator!=(const error_category& __other) const
00104     { return this != &__other; }
00105   };
00106 
00107   // DR 890.
00108   const error_category& system_category();
00109   const error_category& generic_category();
00110 
00111   /// error_code
00112   // Implementation-specific error identification
00113   struct error_code
00114   {
00115     error_code()
00116       : _M_value(0), _M_cat(&system_category()) { }
00117 
00118     error_code(int __v, const error_category& __cat)
00119     : _M_value(__v), _M_cat(&__cat) { }
00120 
00121     template<typename _ErrorCodeEnum>
00122       error_code(_ErrorCodeEnum __e,
00123       typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type* = 0)
00124       : _M_value(static_cast<int>(__e)), _M_cat(&generic_category())
00125       { }
00126 
00127     void 
00128     assign(int __v, const error_category& __cat)
00129     {
00130       _M_value = __v;
00131       _M_cat = &__cat; 
00132     }
00133 
00134     void 
00135     clear()
00136     { assign(0, system_category()); }
00137 
00138     // DR 804.
00139     template<typename _ErrorCodeEnum>
00140       typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
00141              error_code&>::type
00142       operator=(_ErrorCodeEnum __e)
00143       {
00144     assign(static_cast<int>(__e), generic_category());
00145     return *this;
00146       }
00147 
00148     int
00149     value() const { return _M_value; }
00150       
00151     const error_category&  
00152     category() const { return *_M_cat; }
00153 
00154     error_condition 
00155     default_error_condition() const;
00156 
00157     string 
00158     message() const
00159     { return category().message(value()); }
00160 
00161     // Safe bool idiom.
00162     // explicit operator bool() const throw()
00163     // { return _M_value != 0; }
00164     typedef void (*__bool_type)();
00165 
00166     static void __not_bool_type() { }
00167 
00168     operator __bool_type() const
00169     { return _M_value != 0 ? &__not_bool_type : false; }
00170 
00171     // DR 804.
00172   private:
00173     int                 _M_value;
00174     const error_category*   _M_cat;
00175   };
00176 
00177   // 19.4.2.6 non-member functions
00178   inline error_code
00179   make_error_code(errc __e)
00180   { return error_code(static_cast<int>(__e), generic_category()); }
00181 
00182   inline bool
00183   operator<(const error_code& __lhs, const error_code& __rhs)
00184   { 
00185     return (__lhs.category() < __rhs.category()
00186         || (__lhs.category() == __rhs.category()
00187         && __lhs.value() < __rhs.value()));
00188   }
00189 
00190   template<typename _CharT, typename _Traits>
00191     basic_ostream<_CharT, _Traits>&
00192     operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
00193     { return (__os << __e.category().name() << ':' << __e.value()); }
00194 
00195 
00196   /// error_condition
00197   // Portable error identification
00198   struct error_condition 
00199   {
00200     error_condition() : _M_value(0), _M_cat(&generic_category()) { }
00201 
00202     error_condition(int __v, const error_category& __cat)     
00203     : _M_value(__v), _M_cat(&__cat) { }
00204 
00205     template<typename _ErrorConditionEnum>
00206       error_condition(_ErrorConditionEnum __e,
00207               typename enable_if<is_error_condition_enum
00208                               <_ErrorConditionEnum>::value>::type* = 0)
00209     : _M_value(static_cast<int>(__e)), _M_cat(&generic_category()) { }
00210 
00211     void
00212     assign(int __v, const error_category& __cat)
00213     {
00214       _M_value = __v;
00215       _M_cat = &__cat;
00216     }
00217 
00218     // DR 804.
00219     template<typename _ErrorConditionEnum>
00220       typename enable_if<is_error_condition_enum
00221              <_ErrorConditionEnum>::value, error_condition&>::type
00222       operator=(_ErrorConditionEnum __e)
00223       {
00224     assign(static_cast<int>(__e), generic_category());
00225     return *this;
00226       }
00227 
00228     void 
00229     clear()
00230     { assign(0, generic_category()); }
00231 
00232     // 19.4.3.4 observers
00233     int 
00234     value() const { return _M_value; }
00235 
00236     const error_category&
00237     category() const { return *_M_cat; }
00238 
00239     string 
00240     message() const
00241     { return category().message(value()); }
00242 
00243     // Safe bool idiom.
00244     // explicit operator bool() const throw()
00245     // { return _M_value != 0; }
00246     typedef void (*__bool_type)();
00247 
00248     static void __not_bool_type() { }
00249 
00250     operator __bool_type() const
00251     { return _M_value != 0 ? &__not_bool_type : false; }
00252 
00253     // DR 804.
00254   private:
00255     int             _M_value;
00256     const error_category*   _M_cat;
00257   };
00258 
00259   // 19.4.3.6 non-member functions
00260   inline error_condition
00261   make_error_condition(errc __e)
00262   { return error_condition(static_cast<int>(__e), generic_category()); }
00263 
00264   inline bool 
00265   operator<(const error_condition& __lhs, const error_condition& __rhs)
00266   {
00267     return (__lhs.category() < __rhs.category()
00268         || (__lhs.category() == __rhs.category()
00269         && __lhs.value() < __rhs.value()));
00270   }
00271 
00272   // 19.4.4 Comparison operators
00273   inline bool
00274   operator==(const error_code& __lhs, const error_code& __rhs)
00275   { return (__lhs.category() == __rhs.category()
00276         && __lhs.value() == __rhs.value()); }
00277 
00278   inline bool
00279   operator==(const error_code& __lhs, const error_condition& __rhs)
00280   {
00281     return (__lhs.category().equivalent(__lhs.value(), __rhs)
00282         || __rhs.category().equivalent(__lhs, __rhs.value()));
00283   }
00284 
00285   inline bool
00286   operator==(const error_condition& __lhs, const error_code& __rhs)
00287   {
00288     return (__rhs.category().equivalent(__rhs.value(), __lhs)
00289         || __lhs.category().equivalent(__rhs, __lhs.value()));
00290   }
00291 
00292   inline bool
00293   operator==(const error_condition& __lhs, const error_condition& __rhs)
00294   {
00295     return (__lhs.category() == __rhs.category()
00296         && __lhs.value() == __rhs.value());
00297   }
00298 
00299   inline bool
00300   operator!=(const error_code& __lhs, const error_code& __rhs)
00301   { return !(__lhs == __rhs); }
00302 
00303   inline bool
00304   operator!=(const error_code& __lhs, const error_condition& __rhs)
00305   { return !(__lhs == __rhs); }
00306 
00307   inline bool
00308   operator!=(const error_condition& __lhs, const error_code& __rhs)
00309   { return !(__lhs == __rhs); }
00310 
00311   inline bool
00312   operator!=(const error_condition& __lhs, const error_condition& __rhs)
00313   { return !(__lhs == __rhs); }
00314 
00315 
00316   /** 
00317    *  @brief Thrown to indicate error code of underlying system.
00318    *
00319    *  @ingroup exceptions
00320    */
00321   class system_error : public std::runtime_error
00322   {
00323   private:
00324     error_code  _M_code;
00325 
00326   public:
00327     system_error(error_code __ec = error_code())
00328     : runtime_error(""), _M_code(__ec) { }
00329 
00330     system_error(error_code __ec, const string& __what)
00331     : runtime_error(__what), _M_code(__ec) { }
00332     
00333     /*
00334      * TODO: Add const char* ctors to all exceptions.
00335      *
00336      * system_error(error_code __ec, const char* __what)
00337      * : runtime_error(__what), _M_code(__ec) { }
00338      *
00339      * system_error(int __v, const error_category& __ecat, const char* __what)
00340      * : runtime_error(__what), _M_code(error_code(__v, __ecat)) { }
00341      */
00342 
00343     system_error(int __v, const error_category& __ecat)
00344     : runtime_error(""), _M_code(error_code(__v, __ecat)) { }
00345 
00346     system_error(int __v, const error_category& __ecat, const string& __what)
00347     : runtime_error(__what), _M_code(error_code(__v, __ecat)) { }
00348 
00349     virtual ~system_error() throw();
00350 
00351     const error_code& 
00352     code() const throw() { return _M_code; }
00353   };
00354 
00355 _GLIBCXX_END_NAMESPACE
00356 
00357 #endif // __GXX_EXPERIMENTAL_CXX0X__
00358 
00359 #endif // _GLIBCXX_SYSTEM_ERROR
00360 

Generated on Tue Apr 21 13:13:34 2009 for libstdc++ by  doxygen 1.5.8