libstdc++
system_error
Go to the documentation of this file.
00001 // <system_error> -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011 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 include/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 namespace std _GLIBCXX_VISIBILITY(default)
00044 {
00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00046 
00047   class error_code;
00048   class error_condition;
00049   class error_category;
00050   class system_error;
00051 
00052   /// is_error_code_enum
00053   template<typename _Tp>
00054     struct is_error_code_enum : public false_type { };
00055 
00056   /// is_error_condition_enum
00057   template<typename _Tp>
00058     struct is_error_condition_enum : public false_type { };
00059 
00060   template<> 
00061     struct is_error_condition_enum<errc>
00062     : public true_type { };
00063 
00064 
00065   /// error_category
00066   class error_category
00067   {
00068   protected:
00069     error_category();
00070 
00071   public:
00072     virtual ~error_category();
00073 
00074     error_category(const error_category&) = delete;
00075     error_category& operator=(const error_category&) = delete;
00076 
00077     virtual const char* 
00078     name() const = 0;
00079 
00080     virtual string 
00081     message(int) const = 0;
00082 
00083     virtual error_condition
00084     default_error_condition(int __i) const;
00085 
00086     virtual bool 
00087     equivalent(int __i, const error_condition& __cond) const;
00088 
00089     virtual bool 
00090     equivalent(const error_code& __code, int __i) const;
00091 
00092     bool 
00093     operator<(const error_category& __other) const
00094     { return less<const error_category*>()(this, &__other); }
00095 
00096     bool 
00097     operator==(const error_category& __other) const
00098     { return this == &__other; }
00099 
00100     bool 
00101     operator!=(const error_category& __other) const
00102     { return this != &__other; }
00103   };
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(__ec.message()), _M_code(__ec) { }
00315 
00316     system_error(error_code __ec, const string& __what)
00317     : runtime_error(__what + ": " + __ec.message()), _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 + (": " + __ec.message())), _M_code(__ec) { }
00324      *
00325      * system_error(int __v, const error_category& __ecat, const char* __what)
00326      * : runtime_error(__what + (": " + __ec.message())),
00327      *   _M_code(error_code(__v, __ecat)) { }
00328      */
00329 
00330     system_error(int __v, const error_category& __ecat)
00331     : runtime_error(error_code(__v, __ecat).message()),
00332       _M_code(__v, __ecat) { }
00333 
00334     system_error(int __v, const error_category& __ecat, const string& __what)
00335     : runtime_error(__what + ": " + error_code(__v, __ecat).message()),
00336       _M_code(__v, __ecat) { }
00337 
00338     virtual ~system_error() throw();
00339 
00340     const error_code& 
00341     code() const throw() { return _M_code; }
00342   };
00343 
00344 _GLIBCXX_END_NAMESPACE_VERSION
00345 } // namespace
00346 
00347 #ifndef _GLIBCXX_COMPATIBILITY_CXX0X
00348 
00349 #include <bits/functional_hash.h>
00350 
00351 namespace std _GLIBCXX_VISIBILITY(default)
00352 {
00353 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00354 
00355   // DR 1182.
00356   /// std::hash specialization for error_code.
00357   template<>
00358     struct hash<error_code>
00359     : public __hash_base<size_t, error_code>
00360     {
00361       size_t
00362       operator()(const error_code& __e) const
00363       {
00364     const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
00365     return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
00366       }
00367     };
00368 
00369 _GLIBCXX_END_NAMESPACE_VERSION
00370 } // namespace
00371 
00372 #endif // _GLIBCXX_COMPATIBILITY_CXX0X
00373 
00374 #endif // __GXX_EXPERIMENTAL_CXX0X__
00375 
00376 #endif // _GLIBCXX_SYSTEM_ERROR