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   /// is_error_condition_enum
00055   template<typename _Tp>
00056     struct is_error_condition_enum : public false_type { };
00057 
00058   template<> 
00059     struct is_error_condition_enum<errc>
00060     : public true_type { };
00061 
00062 
00063   /// error_category
00064   class error_category
00065   {
00066   protected:
00067     error_category() = default;
00068 
00069   public:
00070     virtual ~error_category() { }
00071 
00072     error_category(const error_category&) = delete;
00073     error_category& operator=(const error_category&) = delete;
00074 
00075     virtual const char* 
00076     name() const = 0;
00077 
00078     virtual string 
00079     message(int) const = 0;
00080 
00081     virtual error_condition
00082     default_error_condition(int __i) const;
00083 
00084     virtual bool 
00085     equivalent(int __i, const error_condition& __cond) const;
00086 
00087     virtual bool 
00088     equivalent(const error_code& __code, int __i) const;
00089 
00090     bool 
00091     operator<(const error_category& __other) const
00092     { return less<const error_category*>()(this, &__other); }
00093 
00094     bool 
00095     operator==(const error_category& __other) const
00096     { return this == &__other; }
00097 
00098     bool 
00099     operator!=(const error_category& __other) const
00100     { return this != &__other; }
00101   };
00102 
00103   // DR 890.
00104   const error_category& system_category();
00105   const error_category& generic_category();
00106 
00107   error_code make_error_code(errc);
00108 
00109   /// error_code
00110   // Implementation-specific error identification
00111   struct error_code
00112   {
00113     error_code()
00114     : _M_value(0), _M_cat(&system_category()) { }
00115 
00116     error_code(int __v, const error_category& __cat)
00117     : _M_value(__v), _M_cat(&__cat) { }
00118 
00119     template<typename _ErrorCodeEnum>
00120       error_code(_ErrorCodeEnum __e,
00121       typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type* = 0)
00122       { *this = make_error_code(__e); }
00123 
00124     void 
00125     assign(int __v, const error_category& __cat)
00126     {
00127       _M_value = __v;
00128       _M_cat = &__cat; 
00129     }
00130 
00131     void 
00132     clear()
00133     { assign(0, system_category()); }
00134 
00135     // DR 804.
00136     template<typename _ErrorCodeEnum>
00137       typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
00138              error_code&>::type
00139       operator=(_ErrorCodeEnum __e)
00140       { return *this = make_error_code(__e); }
00141 
00142     int
00143     value() const { return _M_value; }
00144       
00145     const error_category&  
00146     category() const { return *_M_cat; }
00147 
00148     error_condition 
00149     default_error_condition() const;
00150 
00151     string 
00152     message() const
00153     { return category().message(value()); }
00154 
00155     // Safe bool idiom.
00156     // explicit operator bool() const throw()
00157     // { return _M_value != 0; }
00158     typedef void (*__bool_type)();
00159 
00160     static void __not_bool_type() { }
00161 
00162     operator __bool_type() const
00163     { return _M_value != 0 ? &__not_bool_type : false; }
00164 
00165     // DR 804.
00166   private:
00167     int                 _M_value;
00168     const error_category*   _M_cat;
00169   };
00170 
00171   // 19.4.2.6 non-member functions
00172   inline error_code
00173   make_error_code(errc __e)
00174   { return error_code(static_cast<int>(__e), generic_category()); }
00175 
00176   inline bool
00177   operator<(const error_code& __lhs, const error_code& __rhs)
00178   { 
00179     return (__lhs.category() < __rhs.category()
00180         || (__lhs.category() == __rhs.category()
00181         && __lhs.value() < __rhs.value()));
00182   }
00183 
00184   template<typename _CharT, typename _Traits>
00185     basic_ostream<_CharT, _Traits>&
00186     operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
00187     { return (__os << __e.category().name() << ':' << __e.value()); }
00188 
00189   error_condition make_error_condition(errc);
00190 
00191   /// error_condition
00192   // Portable error identification
00193   struct error_condition 
00194   {
00195     error_condition()
00196     : _M_value(0), _M_cat(&generic_category()) { }
00197 
00198     error_condition(int __v, const error_category& __cat)     
00199     : _M_value(__v), _M_cat(&__cat) { }
00200 
00201     template<typename _ErrorConditionEnum>
00202       error_condition(_ErrorConditionEnum __e,
00203               typename enable_if<is_error_condition_enum
00204                               <_ErrorConditionEnum>::value>::type* = 0)
00205       { *this = make_error_condition(__e); }
00206 
00207     void
00208     assign(int __v, const error_category& __cat)
00209     {
00210       _M_value = __v;
00211       _M_cat = &__cat;
00212     }
00213 
00214     // DR 804.
00215     template<typename _ErrorConditionEnum>
00216       typename enable_if<is_error_condition_enum
00217              <_ErrorConditionEnum>::value, error_condition&>::type
00218       operator=(_ErrorConditionEnum __e)
00219       { return *this = make_error_condition(__e); }
00220 
00221     void 
00222     clear()
00223     { assign(0, generic_category()); }
00224 
00225     // 19.4.3.4 observers
00226     int 
00227     value() const { return _M_value; }
00228 
00229     const error_category&
00230     category() const { return *_M_cat; }
00231 
00232     string 
00233     message() const
00234     { return category().message(value()); }
00235 
00236     // Safe bool idiom.
00237     // explicit operator bool() const throw()
00238     // { return _M_value != 0; }
00239     typedef void (*__bool_type)();
00240 
00241     static void __not_bool_type() { }
00242 
00243     operator __bool_type() const
00244     { return _M_value != 0 ? &__not_bool_type : false; }
00245 
00246     // DR 804.
00247   private:
00248     int             _M_value;
00249     const error_category*   _M_cat;
00250   };
00251 
00252   // 19.4.3.6 non-member functions
00253   inline error_condition
00254   make_error_condition(errc __e)
00255   { return error_condition(static_cast<int>(__e), generic_category()); }
00256 
00257   inline bool 
00258   operator<(const error_condition& __lhs, const error_condition& __rhs)
00259   {
00260     return (__lhs.category() < __rhs.category()
00261         || (__lhs.category() == __rhs.category()
00262         && __lhs.value() < __rhs.value()));
00263   }
00264 
00265   // 19.4.4 Comparison operators
00266   inline bool
00267   operator==(const error_code& __lhs, const error_code& __rhs)
00268   { return (__lhs.category() == __rhs.category()
00269         && __lhs.value() == __rhs.value()); }
00270 
00271   inline bool
00272   operator==(const error_code& __lhs, const error_condition& __rhs)
00273   {
00274     return (__lhs.category().equivalent(__lhs.value(), __rhs)
00275         || __rhs.category().equivalent(__lhs, __rhs.value()));
00276   }
00277 
00278   inline bool
00279   operator==(const error_condition& __lhs, const error_code& __rhs)
00280   {
00281     return (__rhs.category().equivalent(__rhs.value(), __lhs)
00282         || __lhs.category().equivalent(__rhs, __lhs.value()));
00283   }
00284 
00285   inline bool
00286   operator==(const error_condition& __lhs, const error_condition& __rhs)
00287   {
00288     return (__lhs.category() == __rhs.category()
00289         && __lhs.value() == __rhs.value());
00290   }
00291 
00292   inline bool
00293   operator!=(const error_code& __lhs, const error_code& __rhs)
00294   { return !(__lhs == __rhs); }
00295 
00296   inline bool
00297   operator!=(const error_code& __lhs, const error_condition& __rhs)
00298   { return !(__lhs == __rhs); }
00299 
00300   inline bool
00301   operator!=(const error_condition& __lhs, const error_code& __rhs)
00302   { return !(__lhs == __rhs); }
00303 
00304   inline bool
00305   operator!=(const error_condition& __lhs, const error_condition& __rhs)
00306   { return !(__lhs == __rhs); }
00307 
00308 
00309   /** 
00310    *  @brief Thrown to indicate error code of underlying system.
00311    *
00312    *  @ingroup exceptions
00313    */
00314   class system_error : public std::runtime_error
00315   {
00316   private:
00317     error_code  _M_code;
00318 
00319   public:
00320     system_error(error_code __ec = error_code())
00321     : runtime_error(""), _M_code(__ec) { }
00322 
00323     system_error(error_code __ec, const string& __what)
00324     : runtime_error(__what), _M_code(__ec) { }
00325     
00326     /*
00327      * TODO: Add const char* ctors to all exceptions.
00328      *
00329      * system_error(error_code __ec, const char* __what)
00330      * : runtime_error(__what), _M_code(__ec) { }
00331      *
00332      * system_error(int __v, const error_category& __ecat, const char* __what)
00333      * : runtime_error(__what), _M_code(error_code(__v, __ecat)) { }
00334      */
00335 
00336     system_error(int __v, const error_category& __ecat)
00337     : runtime_error(""), _M_code(error_code(__v, __ecat)) { }
00338 
00339     system_error(int __v, const error_category& __ecat, const string& __what)
00340     : runtime_error(__what), _M_code(error_code(__v, __ecat)) { }
00341 
00342     virtual ~system_error() throw();
00343 
00344     const error_code& 
00345     code() const throw() { return _M_code; }
00346   };
00347 
00348 _GLIBCXX_END_NAMESPACE
00349 
00350 #endif // __GXX_EXPERIMENTAL_CXX0X__
00351 
00352 #endif // _GLIBCXX_SYSTEM_ERROR
00353 

Generated on Thu Jul 23 21:16:28 2009 for libstdc++ by  doxygen 1.5.8