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