1*e4b17023SJohn Marino// <system_error> -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4*e4b17023SJohn Marino// 5*e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library. This library is free 6*e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the 7*e4b17023SJohn Marino// terms of the GNU General Public License as published by the 8*e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option) 9*e4b17023SJohn Marino// any later version. 10*e4b17023SJohn Marino 11*e4b17023SJohn Marino// This library is distributed in the hope that it will be useful, 12*e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*e4b17023SJohn Marino// GNU General Public License for more details. 15*e4b17023SJohn Marino 16*e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional 17*e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version 18*e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and 21*e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program; 22*e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*e4b17023SJohn Marino// <http://www.gnu.org/licenses/>. 24*e4b17023SJohn Marino 25*e4b17023SJohn Marino/** @file include/system_error 26*e4b17023SJohn Marino * This is a Standard C++ Library header. 27*e4b17023SJohn Marino */ 28*e4b17023SJohn Marino 29*e4b17023SJohn Marino#ifndef _GLIBCXX_SYSTEM_ERROR 30*e4b17023SJohn Marino#define _GLIBCXX_SYSTEM_ERROR 1 31*e4b17023SJohn Marino 32*e4b17023SJohn Marino#pragma GCC system_header 33*e4b17023SJohn Marino 34*e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__ 35*e4b17023SJohn Marino# include <bits/c++0x_warning.h> 36*e4b17023SJohn Marino#else 37*e4b17023SJohn Marino 38*e4b17023SJohn Marino#include <bits/c++config.h> 39*e4b17023SJohn Marino#include <bits/error_constants.h> 40*e4b17023SJohn Marino#include <iosfwd> 41*e4b17023SJohn Marino#include <stdexcept> 42*e4b17023SJohn Marino 43*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 44*e4b17023SJohn Marino{ 45*e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION 46*e4b17023SJohn Marino 47*e4b17023SJohn Marino class error_code; 48*e4b17023SJohn Marino class error_condition; 49*e4b17023SJohn Marino class error_category; 50*e4b17023SJohn Marino class system_error; 51*e4b17023SJohn Marino 52*e4b17023SJohn Marino /// is_error_code_enum 53*e4b17023SJohn Marino template<typename _Tp> 54*e4b17023SJohn Marino struct is_error_code_enum : public false_type { }; 55*e4b17023SJohn Marino 56*e4b17023SJohn Marino /// is_error_condition_enum 57*e4b17023SJohn Marino template<typename _Tp> 58*e4b17023SJohn Marino struct is_error_condition_enum : public false_type { }; 59*e4b17023SJohn Marino 60*e4b17023SJohn Marino template<> 61*e4b17023SJohn Marino struct is_error_condition_enum<errc> 62*e4b17023SJohn Marino : public true_type { }; 63*e4b17023SJohn Marino 64*e4b17023SJohn Marino 65*e4b17023SJohn Marino /// error_category 66*e4b17023SJohn Marino class error_category 67*e4b17023SJohn Marino { 68*e4b17023SJohn Marino protected: 69*e4b17023SJohn Marino error_category() noexcept; 70*e4b17023SJohn Marino 71*e4b17023SJohn Marino public: 72*e4b17023SJohn Marino virtual ~error_category() noexcept; 73*e4b17023SJohn Marino 74*e4b17023SJohn Marino error_category(const error_category&) = delete; 75*e4b17023SJohn Marino error_category& operator=(const error_category&) = delete; 76*e4b17023SJohn Marino 77*e4b17023SJohn Marino virtual const char* 78*e4b17023SJohn Marino name() const noexcept = 0; 79*e4b17023SJohn Marino 80*e4b17023SJohn Marino virtual string 81*e4b17023SJohn Marino message(int) const = 0; 82*e4b17023SJohn Marino 83*e4b17023SJohn Marino virtual error_condition 84*e4b17023SJohn Marino default_error_condition(int __i) const noexcept; 85*e4b17023SJohn Marino 86*e4b17023SJohn Marino virtual bool 87*e4b17023SJohn Marino equivalent(int __i, const error_condition& __cond) const noexcept; 88*e4b17023SJohn Marino 89*e4b17023SJohn Marino virtual bool 90*e4b17023SJohn Marino equivalent(const error_code& __code, int __i) const noexcept; 91*e4b17023SJohn Marino 92*e4b17023SJohn Marino bool 93*e4b17023SJohn Marino operator<(const error_category& __other) const noexcept 94*e4b17023SJohn Marino { return less<const error_category*>()(this, &__other); } 95*e4b17023SJohn Marino 96*e4b17023SJohn Marino bool 97*e4b17023SJohn Marino operator==(const error_category& __other) const noexcept 98*e4b17023SJohn Marino { return this == &__other; } 99*e4b17023SJohn Marino 100*e4b17023SJohn Marino bool 101*e4b17023SJohn Marino operator!=(const error_category& __other) const noexcept 102*e4b17023SJohn Marino { return this != &__other; } 103*e4b17023SJohn Marino }; 104*e4b17023SJohn Marino 105*e4b17023SJohn Marino // DR 890. 106*e4b17023SJohn Marino _GLIBCXX_CONST const error_category& system_category() noexcept; 107*e4b17023SJohn Marino _GLIBCXX_CONST const error_category& generic_category() noexcept; 108*e4b17023SJohn Marino 109*e4b17023SJohn Marino error_code make_error_code(errc) noexcept; 110*e4b17023SJohn Marino 111*e4b17023SJohn Marino template<typename _Tp> 112*e4b17023SJohn Marino struct hash; 113*e4b17023SJohn Marino 114*e4b17023SJohn Marino /// error_code 115*e4b17023SJohn Marino // Implementation-specific error identification 116*e4b17023SJohn Marino struct error_code 117*e4b17023SJohn Marino { 118*e4b17023SJohn Marino error_code() noexcept 119*e4b17023SJohn Marino : _M_value(0), _M_cat(&system_category()) { } 120*e4b17023SJohn Marino 121*e4b17023SJohn Marino error_code(int __v, const error_category& __cat) noexcept 122*e4b17023SJohn Marino : _M_value(__v), _M_cat(&__cat) { } 123*e4b17023SJohn Marino 124*e4b17023SJohn Marino template<typename _ErrorCodeEnum, typename = typename 125*e4b17023SJohn Marino enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type> 126*e4b17023SJohn Marino error_code(_ErrorCodeEnum __e) noexcept 127*e4b17023SJohn Marino { *this = make_error_code(__e); } 128*e4b17023SJohn Marino 129*e4b17023SJohn Marino void 130*e4b17023SJohn Marino assign(int __v, const error_category& __cat) noexcept 131*e4b17023SJohn Marino { 132*e4b17023SJohn Marino _M_value = __v; 133*e4b17023SJohn Marino _M_cat = &__cat; 134*e4b17023SJohn Marino } 135*e4b17023SJohn Marino 136*e4b17023SJohn Marino void 137*e4b17023SJohn Marino clear() noexcept 138*e4b17023SJohn Marino { assign(0, system_category()); } 139*e4b17023SJohn Marino 140*e4b17023SJohn Marino // DR 804. 141*e4b17023SJohn Marino template<typename _ErrorCodeEnum> 142*e4b17023SJohn Marino typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value, 143*e4b17023SJohn Marino error_code&>::type 144*e4b17023SJohn Marino operator=(_ErrorCodeEnum __e) noexcept 145*e4b17023SJohn Marino { return *this = make_error_code(__e); } 146*e4b17023SJohn Marino 147*e4b17023SJohn Marino int 148*e4b17023SJohn Marino value() const noexcept { return _M_value; } 149*e4b17023SJohn Marino 150*e4b17023SJohn Marino const error_category& 151*e4b17023SJohn Marino category() const noexcept { return *_M_cat; } 152*e4b17023SJohn Marino 153*e4b17023SJohn Marino error_condition 154*e4b17023SJohn Marino default_error_condition() const noexcept; 155*e4b17023SJohn Marino 156*e4b17023SJohn Marino string 157*e4b17023SJohn Marino message() const 158*e4b17023SJohn Marino { return category().message(value()); } 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino explicit operator bool() const noexcept 161*e4b17023SJohn Marino { return _M_value != 0 ? true : false; } 162*e4b17023SJohn Marino 163*e4b17023SJohn Marino // DR 804. 164*e4b17023SJohn Marino private: 165*e4b17023SJohn Marino friend class hash<error_code>; 166*e4b17023SJohn Marino 167*e4b17023SJohn Marino int _M_value; 168*e4b17023SJohn Marino const error_category* _M_cat; 169*e4b17023SJohn Marino }; 170*e4b17023SJohn Marino 171*e4b17023SJohn Marino // 19.4.2.6 non-member functions 172*e4b17023SJohn Marino inline error_code 173*e4b17023SJohn Marino make_error_code(errc __e) noexcept 174*e4b17023SJohn Marino { return error_code(static_cast<int>(__e), generic_category()); } 175*e4b17023SJohn Marino 176*e4b17023SJohn Marino inline bool 177*e4b17023SJohn Marino operator<(const error_code& __lhs, const error_code& __rhs) noexcept 178*e4b17023SJohn Marino { 179*e4b17023SJohn Marino return (__lhs.category() < __rhs.category() 180*e4b17023SJohn Marino || (__lhs.category() == __rhs.category() 181*e4b17023SJohn Marino && __lhs.value() < __rhs.value())); 182*e4b17023SJohn Marino } 183*e4b17023SJohn Marino 184*e4b17023SJohn Marino template<typename _CharT, typename _Traits> 185*e4b17023SJohn Marino basic_ostream<_CharT, _Traits>& 186*e4b17023SJohn Marino operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) 187*e4b17023SJohn Marino { return (__os << __e.category().name() << ':' << __e.value()); } 188*e4b17023SJohn Marino 189*e4b17023SJohn Marino error_condition make_error_condition(errc) noexcept; 190*e4b17023SJohn Marino 191*e4b17023SJohn Marino /// error_condition 192*e4b17023SJohn Marino // Portable error identification 193*e4b17023SJohn Marino struct error_condition 194*e4b17023SJohn Marino { 195*e4b17023SJohn Marino error_condition() noexcept 196*e4b17023SJohn Marino : _M_value(0), _M_cat(&generic_category()) { } 197*e4b17023SJohn Marino 198*e4b17023SJohn Marino error_condition(int __v, const error_category& __cat) noexcept 199*e4b17023SJohn Marino : _M_value(__v), _M_cat(&__cat) { } 200*e4b17023SJohn Marino 201*e4b17023SJohn Marino template<typename _ErrorConditionEnum, typename = typename 202*e4b17023SJohn Marino enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type> 203*e4b17023SJohn Marino error_condition(_ErrorConditionEnum __e) noexcept 204*e4b17023SJohn Marino { *this = make_error_condition(__e); } 205*e4b17023SJohn Marino 206*e4b17023SJohn Marino void 207*e4b17023SJohn Marino assign(int __v, const error_category& __cat) noexcept 208*e4b17023SJohn Marino { 209*e4b17023SJohn Marino _M_value = __v; 210*e4b17023SJohn Marino _M_cat = &__cat; 211*e4b17023SJohn Marino } 212*e4b17023SJohn Marino 213*e4b17023SJohn Marino // DR 804. 214*e4b17023SJohn Marino template<typename _ErrorConditionEnum> 215*e4b17023SJohn Marino typename enable_if<is_error_condition_enum 216*e4b17023SJohn Marino <_ErrorConditionEnum>::value, error_condition&>::type 217*e4b17023SJohn Marino operator=(_ErrorConditionEnum __e) noexcept 218*e4b17023SJohn Marino { return *this = make_error_condition(__e); } 219*e4b17023SJohn Marino 220*e4b17023SJohn Marino void 221*e4b17023SJohn Marino clear() noexcept 222*e4b17023SJohn Marino { assign(0, generic_category()); } 223*e4b17023SJohn Marino 224*e4b17023SJohn Marino // 19.4.3.4 observers 225*e4b17023SJohn Marino int 226*e4b17023SJohn Marino value() const noexcept { return _M_value; } 227*e4b17023SJohn Marino 228*e4b17023SJohn Marino const error_category& 229*e4b17023SJohn Marino category() const noexcept { return *_M_cat; } 230*e4b17023SJohn Marino 231*e4b17023SJohn Marino string 232*e4b17023SJohn Marino message() const 233*e4b17023SJohn Marino { return category().message(value()); } 234*e4b17023SJohn Marino 235*e4b17023SJohn Marino explicit operator bool() const noexcept 236*e4b17023SJohn Marino { return _M_value != 0 ? true : false; } 237*e4b17023SJohn Marino 238*e4b17023SJohn Marino // DR 804. 239*e4b17023SJohn Marino private: 240*e4b17023SJohn Marino int _M_value; 241*e4b17023SJohn Marino const error_category* _M_cat; 242*e4b17023SJohn Marino }; 243*e4b17023SJohn Marino 244*e4b17023SJohn Marino // 19.4.3.6 non-member functions 245*e4b17023SJohn Marino inline error_condition 246*e4b17023SJohn Marino make_error_condition(errc __e) noexcept 247*e4b17023SJohn Marino { return error_condition(static_cast<int>(__e), generic_category()); } 248*e4b17023SJohn Marino 249*e4b17023SJohn Marino inline bool 250*e4b17023SJohn Marino operator<(const error_condition& __lhs, 251*e4b17023SJohn Marino const error_condition& __rhs) noexcept 252*e4b17023SJohn Marino { 253*e4b17023SJohn Marino return (__lhs.category() < __rhs.category() 254*e4b17023SJohn Marino || (__lhs.category() == __rhs.category() 255*e4b17023SJohn Marino && __lhs.value() < __rhs.value())); 256*e4b17023SJohn Marino } 257*e4b17023SJohn Marino 258*e4b17023SJohn Marino // 19.4.4 Comparison operators 259*e4b17023SJohn Marino inline bool 260*e4b17023SJohn Marino operator==(const error_code& __lhs, const error_code& __rhs) noexcept 261*e4b17023SJohn Marino { return (__lhs.category() == __rhs.category() 262*e4b17023SJohn Marino && __lhs.value() == __rhs.value()); } 263*e4b17023SJohn Marino 264*e4b17023SJohn Marino inline bool 265*e4b17023SJohn Marino operator==(const error_code& __lhs, const error_condition& __rhs) noexcept 266*e4b17023SJohn Marino { 267*e4b17023SJohn Marino return (__lhs.category().equivalent(__lhs.value(), __rhs) 268*e4b17023SJohn Marino || __rhs.category().equivalent(__lhs, __rhs.value())); 269*e4b17023SJohn Marino } 270*e4b17023SJohn Marino 271*e4b17023SJohn Marino inline bool 272*e4b17023SJohn Marino operator==(const error_condition& __lhs, const error_code& __rhs) noexcept 273*e4b17023SJohn Marino { 274*e4b17023SJohn Marino return (__rhs.category().equivalent(__rhs.value(), __lhs) 275*e4b17023SJohn Marino || __lhs.category().equivalent(__rhs, __lhs.value())); 276*e4b17023SJohn Marino } 277*e4b17023SJohn Marino 278*e4b17023SJohn Marino inline bool 279*e4b17023SJohn Marino operator==(const error_condition& __lhs, 280*e4b17023SJohn Marino const error_condition& __rhs) noexcept 281*e4b17023SJohn Marino { 282*e4b17023SJohn Marino return (__lhs.category() == __rhs.category() 283*e4b17023SJohn Marino && __lhs.value() == __rhs.value()); 284*e4b17023SJohn Marino } 285*e4b17023SJohn Marino 286*e4b17023SJohn Marino inline bool 287*e4b17023SJohn Marino operator!=(const error_code& __lhs, const error_code& __rhs) noexcept 288*e4b17023SJohn Marino { return !(__lhs == __rhs); } 289*e4b17023SJohn Marino 290*e4b17023SJohn Marino inline bool 291*e4b17023SJohn Marino operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept 292*e4b17023SJohn Marino { return !(__lhs == __rhs); } 293*e4b17023SJohn Marino 294*e4b17023SJohn Marino inline bool 295*e4b17023SJohn Marino operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept 296*e4b17023SJohn Marino { return !(__lhs == __rhs); } 297*e4b17023SJohn Marino 298*e4b17023SJohn Marino inline bool 299*e4b17023SJohn Marino operator!=(const error_condition& __lhs, 300*e4b17023SJohn Marino const error_condition& __rhs) noexcept 301*e4b17023SJohn Marino { return !(__lhs == __rhs); } 302*e4b17023SJohn Marino 303*e4b17023SJohn Marino 304*e4b17023SJohn Marino /** 305*e4b17023SJohn Marino * @brief Thrown to indicate error code of underlying system. 306*e4b17023SJohn Marino * 307*e4b17023SJohn Marino * @ingroup exceptions 308*e4b17023SJohn Marino */ 309*e4b17023SJohn Marino class system_error : public std::runtime_error 310*e4b17023SJohn Marino { 311*e4b17023SJohn Marino private: 312*e4b17023SJohn Marino error_code _M_code; 313*e4b17023SJohn Marino 314*e4b17023SJohn Marino public: 315*e4b17023SJohn Marino system_error(error_code __ec = error_code()) 316*e4b17023SJohn Marino : runtime_error(__ec.message()), _M_code(__ec) { } 317*e4b17023SJohn Marino 318*e4b17023SJohn Marino system_error(error_code __ec, const string& __what) 319*e4b17023SJohn Marino : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { } 320*e4b17023SJohn Marino 321*e4b17023SJohn Marino /* 322*e4b17023SJohn Marino * TODO: Add const char* ctors to all exceptions. 323*e4b17023SJohn Marino * 324*e4b17023SJohn Marino * system_error(error_code __ec, const char* __what) 325*e4b17023SJohn Marino * : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { } 326*e4b17023SJohn Marino * 327*e4b17023SJohn Marino * system_error(int __v, const error_category& __ecat, const char* __what) 328*e4b17023SJohn Marino * : runtime_error(__what + (": " + __ec.message())), 329*e4b17023SJohn Marino * _M_code(error_code(__v, __ecat)) { } 330*e4b17023SJohn Marino */ 331*e4b17023SJohn Marino 332*e4b17023SJohn Marino system_error(int __v, const error_category& __ecat) 333*e4b17023SJohn Marino : runtime_error(error_code(__v, __ecat).message()), 334*e4b17023SJohn Marino _M_code(__v, __ecat) { } 335*e4b17023SJohn Marino 336*e4b17023SJohn Marino system_error(int __v, const error_category& __ecat, const string& __what) 337*e4b17023SJohn Marino : runtime_error(__what + ": " + error_code(__v, __ecat).message()), 338*e4b17023SJohn Marino _M_code(__v, __ecat) { } 339*e4b17023SJohn Marino 340*e4b17023SJohn Marino virtual ~system_error() noexcept; 341*e4b17023SJohn Marino 342*e4b17023SJohn Marino const error_code& 343*e4b17023SJohn Marino code() const noexcept { return _M_code; } 344*e4b17023SJohn Marino }; 345*e4b17023SJohn Marino 346*e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION 347*e4b17023SJohn Marino} // namespace 348*e4b17023SJohn Marino 349*e4b17023SJohn Marino#ifndef _GLIBCXX_COMPATIBILITY_CXX0X 350*e4b17023SJohn Marino 351*e4b17023SJohn Marino#include <bits/functional_hash.h> 352*e4b17023SJohn Marino 353*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 354*e4b17023SJohn Marino{ 355*e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION 356*e4b17023SJohn Marino 357*e4b17023SJohn Marino // DR 1182. 358*e4b17023SJohn Marino /// std::hash specialization for error_code. 359*e4b17023SJohn Marino template<> 360*e4b17023SJohn Marino struct hash<error_code> 361*e4b17023SJohn Marino : public __hash_base<size_t, error_code> 362*e4b17023SJohn Marino { 363*e4b17023SJohn Marino size_t 364*e4b17023SJohn Marino operator()(const error_code& __e) const noexcept 365*e4b17023SJohn Marino { 366*e4b17023SJohn Marino const size_t __tmp = std::_Hash_impl::hash(__e._M_value); 367*e4b17023SJohn Marino return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp); 368*e4b17023SJohn Marino } 369*e4b17023SJohn Marino }; 370*e4b17023SJohn Marino 371*e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION 372*e4b17023SJohn Marino} // namespace 373*e4b17023SJohn Marino 374*e4b17023SJohn Marino#endif // _GLIBCXX_COMPATIBILITY_CXX0X 375*e4b17023SJohn Marino 376*e4b17023SJohn Marino#endif // __GXX_EXPERIMENTAL_CXX0X__ 377*e4b17023SJohn Marino 378*e4b17023SJohn Marino#endif // _GLIBCXX_SYSTEM_ERROR 379