# 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