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