# system_error

Go to the documentation of this file.

    00001 // <system_error> -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008, 2009, 2010 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 <bits/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();
    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   inline error_category::error_category() = default;
    00104
    00105   // DR 890.
    00106   _GLIBCXX_CONST const error_category& system_category() throw();
    00107   _GLIBCXX_CONST const error_category& generic_category() throw();
    00108
    00109   error_code make_error_code(errc);
    00110
    00111   template<typename _Tp>
    00112     struct hash;
    00113
    00114   /// error_code
    00115   // Implementation-specific error identification
    00116   struct error_code
    00117   {
    00118     error_code()
    00119     : _M_value(0), _M_cat(&system_category()) { }
    00120
    00121     error_code(int __v, const error_category& __cat)
    00122     : _M_value(__v), _M_cat(&__cat) { }
    00123
    00124     template<typename _ErrorCodeEnum>
    00125       error_code(_ErrorCodeEnum __e,
    00126       typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type* = 0)
    00127       { *this = make_error_code(__e); }
    00128
    00129     void
    00130     assign(int __v, const error_category& __cat)
    00131     {
    00132       _M_value = __v;
    00133       _M_cat = &__cat;
    00134     }
    00135
    00136     void
    00137     clear()
    00138     { assign(0, system_category()); }
    00139
    00140     // DR 804.
    00141     template<typename _ErrorCodeEnum>
    00142       typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
    00143              error_code&>::type
    00144       operator=(_ErrorCodeEnum __e)
    00145       { return *this = make_error_code(__e); }
    00146
    00147     int
    00148     value() const { return _M_value; }
    00149
    00150     const error_category&
    00151     category() const { return *_M_cat; }
    00152
    00153     error_condition
    00154     default_error_condition() const;
    00155
    00156     string
    00157     message() const
    00158     { return category().message(value()); }
    00159
    00160     explicit operator bool() const
    00161     { return _M_value != 0 ? true : false; }
    00162
    00163     // DR 804.
    00164   private:
    00165     friend class hash<error_code>;
    00166
    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     explicit operator bool() const
    00237     { return _M_value != 0 ? true : false; }
    00238
    00239     // DR 804.
    00240   private:
    00241     int             _M_value;
    00242     const error_category*   _M_cat;
    00243   };
    00244
    00245   // 19.4.3.6 non-member functions
    00246   inline error_condition
    00247   make_error_condition(errc __e)
    00248   { return error_condition(static_cast<int>(__e), generic_category()); }
    00249
    00250   inline bool
    00251   operator<(const error_condition& __lhs, const error_condition& __rhs)
    00252   {
    00253     return (__lhs.category() < __rhs.category()
    00254         || (__lhs.category() == __rhs.category()
    00255         && __lhs.value() < __rhs.value()));
    00256   }
    00257
    00258   // 19.4.4 Comparison operators
    00259   inline bool
    00260   operator==(const error_code& __lhs, const error_code& __rhs)
    00261   { return (__lhs.category() == __rhs.category()
    00262         && __lhs.value() == __rhs.value()); }
    00263
    00264   inline bool
    00265   operator==(const error_code& __lhs, const error_condition& __rhs)
    00266   {
    00267     return (__lhs.category().equivalent(__lhs.value(), __rhs)
    00268         || __rhs.category().equivalent(__lhs, __rhs.value()));
    00269   }
    00270
    00271   inline bool
    00272   operator==(const error_condition& __lhs, const error_code& __rhs)
    00273   {
    00274     return (__rhs.category().equivalent(__rhs.value(), __lhs)
    00275         || __lhs.category().equivalent(__rhs, __lhs.value()));
    00276   }
    00277
    00278   inline bool
    00279   operator==(const error_condition& __lhs, const error_condition& __rhs)
    00280   {
    00281     return (__lhs.category() == __rhs.category()
    00282         && __lhs.value() == __rhs.value());
    00283   }
    00284
    00285   inline bool
    00286   operator!=(const error_code& __lhs, const error_code& __rhs)
    00287   { return !(__lhs == __rhs); }
    00288
    00289   inline bool
    00290   operator!=(const error_code& __lhs, const error_condition& __rhs)
    00291   { return !(__lhs == __rhs); }
    00292
    00293   inline bool
    00294   operator!=(const error_condition& __lhs, const error_code& __rhs)
    00295   { return !(__lhs == __rhs); }
    00296
    00297   inline bool
    00298   operator!=(const error_condition& __lhs, const error_condition& __rhs)
    00299   { return !(__lhs == __rhs); }
    00300
    00301
    00302   /**
    00303    *  @brief Thrown to indicate error code of underlying system.
    00304    *
    00305    *  @ingroup exceptions
    00306    */
    00307   class system_error : public std::runtime_error
    00308   {
    00309   private:
    00310     error_code  _M_code;
    00311
    00312   public:
    00313     system_error(error_code __ec = error_code())
    00314     : runtime_error(""), _M_code(__ec) { }
    00315
    00316     system_error(error_code __ec, const string& __what)
    00317     : runtime_error(__what), _M_code(__ec) { }
    00318
    00319     /*
    00320      * TODO: Add const char* ctors to all exceptions.
    00321      *
    00322      * system_error(error_code __ec, const char* __what)
    00323      * : runtime_error(__what), _M_code(__ec) { }
    00324      *
    00325      * system_error(int __v, const error_category& __ecat, const char* __what)
    00326      * : runtime_error(__what), _M_code(error_code(__v, __ecat)) { }
    00327      */
    00328
    00329     system_error(int __v, const error_category& __ecat)
    00330     : runtime_error(""), _M_code(error_code(__v, __ecat)) { }
    00331
    00332     system_error(int __v, const error_category& __ecat, const string& __what)
    00333     : runtime_error(__what), _M_code(error_code(__v, __ecat)) { }
    00334
    00335     virtual ~system_error() throw();
    00336
    00337     const error_code&
    00338     code() const throw() { return _M_code; }
    00339   };
    00340
    00341 _GLIBCXX_END_NAMESPACE
    00342
    00343 #ifndef _GLIBCXX_COMPATIBILITY_CXX0X
    00344
    00345 #include <bits/functional_hash.h>
    00346
    00347 _GLIBCXX_BEGIN_NAMESPACE(std)
    00348
    00349   // DR 1182.
    00350   /// std::hash specialization for error_code.
    00351   template<>
    00352     struct hash<error_code>
    00353     : public std::unary_function<error_code, size_t>
    00354     {
    00355       size_t
    00356       operator()(const error_code& __e) const
    00357       {
    00358     const size_t __tmp = std::_Fnv_hash::hash(__e._M_value);
    00359     return std::_Fnv_hash::__hash_combine(__e._M_cat, __tmp);
    00360       }
    00361     };
    00362
    00363 _GLIBCXX_END_NAMESPACE
    00364
    00365 #endif // _GLIBCXX_COMPATIBILITY_CXX0X
    00366
    00367 #endif // __GXX_EXPERIMENTAL_CXX0X__
    00368
    00369 #endif // _GLIBCXX_SYSTEM_ERROR
    00370