system_error revision 355940
111820Sjulian// -*- C++ -*-
211820Sjulian//===---------------------------- system_error ----------------------------===//
311820Sjulian//
411820Sjulian// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
511820Sjulian// See https://llvm.org/LICENSE.txt for license information.
611820Sjulian// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
711820Sjulian//
811820Sjulian//===----------------------------------------------------------------------===//
911820Sjulian
1011820Sjulian#ifndef _LIBCPP_SYSTEM_ERROR
1111820Sjulian#define _LIBCPP_SYSTEM_ERROR
1211820Sjulian
1311820Sjulian/*
1411820Sjulian    system_error synopsis
1511820Sjulian
1611820Sjuliannamespace std
1711820Sjulian{
1811820Sjulian
1911820Sjulianclass error_category
2011820Sjulian{
2111820Sjulianpublic:
2211820Sjulian    virtual ~error_category() noexcept;
2311820Sjulian
2411820Sjulian    constexpr error_category();
2511820Sjulian    error_category(const error_category&) = delete;
2611820Sjulian    error_category& operator=(const error_category&) = delete;
2711820Sjulian
2811820Sjulian    virtual const char* name() const noexcept = 0;
2911820Sjulian    virtual error_condition default_error_condition(int ev) const noexcept;
3011820Sjulian    virtual bool equivalent(int code, const error_condition& condition) const noexcept;
3111820Sjulian    virtual bool equivalent(const error_code& code, int condition) const noexcept;
3211820Sjulian    virtual string message(int ev) const = 0;
3311820Sjulian
3411820Sjulian    bool operator==(const error_category& rhs) const noexcept;
3511820Sjulian    bool operator!=(const error_category& rhs) const noexcept;
3611820Sjulian    bool operator<(const error_category& rhs) const noexcept;
3711820Sjulian};
3850479Speter
3911820Sjulianconst error_category& generic_category() noexcept;
4011820Sjulianconst error_category& system_category() noexcept;
4111820Sjulian
42122760Strhodestemplate <class T> struct is_error_code_enum
4311820Sjulian    : public false_type {};
4411820Sjulian
4511820Sjuliantemplate <class T> struct is_error_condition_enum
4611820Sjulian    : public false_type {};
4711820Sjulian
4811820Sjuliantemplate <class _Tp>
4911820Sjulianinline constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; // C++17
5011820Sjulian
5111820Sjuliantemplate <class _Tp>
5211820Sjulianinline constexpr size_t is_error_code_enum_v = is_error_code_enum<_Tp>::value; // C++17
5320287Swollman
5411820Sjulianclass error_code
5511820Sjulian{
5611820Sjulianpublic:
5711820Sjulian    // constructors:
5859218Simp    error_code() noexcept;
5911820Sjulian    error_code(int val, const error_category& cat) noexcept;
60122760Strhodes    template <class ErrorCodeEnum>
6111820Sjulian        error_code(ErrorCodeEnum e) noexcept;
6211820Sjulian
6311820Sjulian    // modifiers:
6411820Sjulian    void assign(int val, const error_category& cat) noexcept;
6511820Sjulian    template <class ErrorCodeEnum>
6611820Sjulian        error_code& operator=(ErrorCodeEnum e) noexcept;
6711820Sjulian    void clear() noexcept;
6811820Sjulian
6911820Sjulian    // observers:
7011820Sjulian    int value() const noexcept;
7111820Sjulian    const error_category& category() const noexcept;
7211820Sjulian    error_condition default_error_condition() const noexcept;
7311820Sjulian    string message() const;
7411820Sjulian    explicit operator bool() const noexcept;
7511820Sjulian};
7611820Sjulian
7711820Sjulian// non-member functions:
7811820Sjulianbool operator<(const error_code& lhs, const error_code& rhs) noexcept;
7911820Sjuliantemplate <class charT, class traits>
8011820Sjulian    basic_ostream<charT,traits>&
8111820Sjulian    operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
8211820Sjulian
8311820Sjulianclass error_condition
84128186Sluigi{
8511820Sjulianpublic:
8611820Sjulian    // constructors:
8711820Sjulian    error_condition() noexcept;
8811820Sjulian    error_condition(int val, const error_category& cat) noexcept;
8911820Sjulian    template <class ErrorConditionEnum>
9011820Sjulian        error_condition(ErrorConditionEnum e) noexcept;
9111820Sjulian
9211820Sjulian    // modifiers:
9311820Sjulian    void assign(int val, const error_category& cat) noexcept;
9411820Sjulian    template <class ErrorConditionEnum>
9511820Sjulian        error_condition& operator=(ErrorConditionEnum e) noexcept;
9611820Sjulian    void clear() noexcept;
9711820Sjulian
9811820Sjulian    // observers:
9911820Sjulian    int value() const noexcept;
10011820Sjulian    const error_category& category() const noexcept;
10111820Sjulian    string message() const noexcept;
102128186Sluigi    explicit operator bool() const noexcept;
10311820Sjulian};
10411820Sjulian
10511820Sjulianbool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
10611820Sjulian
10711820Sjulianclass system_error
10811820Sjulian    : public runtime_error
10911820Sjulian{
11011820Sjulianpublic:
11111820Sjulian    system_error(error_code ec, const string& what_arg);
11211820Sjulian    system_error(error_code ec, const char* what_arg);
11311820Sjulian    system_error(error_code ec);
11411820Sjulian    system_error(int ev, const error_category& ecat, const string& what_arg);
11511820Sjulian    system_error(int ev, const error_category& ecat, const char* what_arg);
11611820Sjulian    system_error(int ev, const error_category& ecat);
11711820Sjulian
11811820Sjulian    const error_code& code() const noexcept;
11911820Sjulian    const char* what() const noexcept;
12011820Sjulian};
12111820Sjulian
12211820Sjuliantemplate <> struct is_error_condition_enum<errc>
12311820Sjulian    : true_type { }
12411820Sjulian
12511820Sjulianerror_code make_error_code(errc e) noexcept;
12611820Sjulianerror_condition make_error_condition(errc e) noexcept;
12711820Sjulian
12811820Sjulian// Comparison operators:
12911820Sjulianbool operator==(const error_code& lhs, const error_code& rhs) noexcept;
13011820Sjulianbool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
13111820Sjulianbool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
13211820Sjulianbool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
13311820Sjulianbool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
13411820Sjulianbool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
13511820Sjulianbool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
13611820Sjulianbool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
13711820Sjulian
13811820Sjuliantemplate <> struct hash<std::error_code>;
13911820Sjuliantemplate <> struct hash<std::error_condition>;
14011820Sjulian
14111820Sjulian}  // std
14211820Sjulian
14311820Sjulian*/
14411820Sjulian
14511820Sjulian#include <__errc>
14611820Sjulian#include <type_traits>
14711820Sjulian#include <stdexcept>
14811820Sjulian#include <__functional_base>
14911820Sjulian#include <string>
15011820Sjulian
15111820Sjulian#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15211820Sjulian#pragma GCC system_header
15311820Sjulian#endif
15411820Sjulian
15511820Sjulian_LIBCPP_BEGIN_NAMESPACE_STD
15611820Sjulian
15711820Sjulian// is_error_code_enum
15811820Sjulian
15911820Sjuliantemplate <class _Tp>
16011820Sjulianstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum
16111820Sjulian    : public false_type {};
16211820Sjulian
16311820Sjulian#if _LIBCPP_STD_VER > 14
16411820Sjuliantemplate <class _Tp>
16511820Sjulian_LIBCPP_INLINE_VAR constexpr size_t is_error_code_enum_v = is_error_code_enum<_Tp>::value;
16611820Sjulian#endif
16711820Sjulian
16811820Sjulian// is_error_condition_enum
16911820Sjulian
17011820Sjuliantemplate <class _Tp>
17111820Sjulianstruct _LIBCPP_TEMPLATE_VIS is_error_condition_enum
17211820Sjulian    : public false_type {};
17311820Sjulian
17411820Sjulian#if _LIBCPP_STD_VER > 14
17511820Sjuliantemplate <class _Tp>
17611820Sjulian_LIBCPP_INLINE_VAR constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value;
17711820Sjulian#endif
17811820Sjulian
17911820Sjuliantemplate <>
18011820Sjulianstruct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc>
18111820Sjulian    : true_type { };
18211820Sjulian
18343713Sjhay#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
18443713Sjhaytemplate <>
18543713Sjhaystruct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx>
18611820Sjulian    : true_type { };
18711820Sjulian#endif
18811820Sjulian
18911820Sjulianclass _LIBCPP_TYPE_VIS error_condition;
19011820Sjulianclass _LIBCPP_TYPE_VIS error_code;
19111820Sjulian
19211820Sjulian// class error_category
19311820Sjulian
19411820Sjulianclass _LIBCPP_HIDDEN __do_message;
19511820Sjulian
19611820Sjulianclass _LIBCPP_TYPE_VIS error_category
19711820Sjulian{
19811820Sjulianpublic:
19911820Sjulian    virtual ~error_category() _NOEXCEPT;
20011820Sjulian
20111820Sjulian#if defined(_LIBCPP_BUILDING_LIBRARY) && \
20211820Sjulian    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
20311820Sjulian    error_category() _NOEXCEPT;
20411820Sjulian#else
20511820Sjulian    _LIBCPP_INLINE_VISIBILITY
20611820Sjulian    _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT
20711820Sjulian#endif
20811820Sjulianprivate:
20911820Sjulian    error_category(const error_category&);// = delete;
21011820Sjulian    error_category& operator=(const error_category&);// = delete;
21111820Sjulian
21211820Sjulianpublic:
21311820Sjulian    virtual const char* name() const _NOEXCEPT = 0;
21411820Sjulian    virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
21511820Sjulian    virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
21611820Sjulian    virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
21711820Sjulian    virtual string message(int __ev) const = 0;
21811820Sjulian
21911820Sjulian    _LIBCPP_INLINE_VISIBILITY
22011820Sjulian    bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;}
22111820Sjulian
22211820Sjulian    _LIBCPP_INLINE_VISIBILITY
22311820Sjulian    bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);}
22411820Sjulian
22511820Sjulian    _LIBCPP_INLINE_VISIBILITY
22611820Sjulian    bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;}
22711820Sjulian
22811820Sjulian    friend class _LIBCPP_HIDDEN __do_message;
22911820Sjulian};
23011820Sjulian
23111820Sjulianclass _LIBCPP_HIDDEN __do_message
23211820Sjulian    : public error_category
23311820Sjulian{
23411820Sjulianpublic:
23511820Sjulian    virtual string message(int ev) const;
23611820Sjulian};
23711820Sjulian
23811820Sjulian_LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT;
23914165Sjulian_LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT;
24011820Sjulian
24111820Sjulianclass _LIBCPP_TYPE_VIS error_condition
24211820Sjulian{
24311820Sjulian    int __val_;
24411820Sjulian    const error_category* __cat_;
24511820Sjulianpublic:
24611820Sjulian    _LIBCPP_INLINE_VISIBILITY
24711820Sjulian    error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {}
24811820Sjulian
24911820Sjulian    _LIBCPP_INLINE_VISIBILITY
25011820Sjulian    error_condition(int __val, const error_category& __cat) _NOEXCEPT
25111820Sjulian        : __val_(__val), __cat_(&__cat) {}
25211820Sjulian
25311820Sjulian    template <class _Ep>
254122760Strhodes        _LIBCPP_INLINE_VISIBILITY
25511820Sjulian        error_condition(_Ep __e,
25611820Sjulian              typename enable_if<is_error_condition_enum<_Ep>::value>::type* = 0
25711820Sjulian                                                                     ) _NOEXCEPT
25811820Sjulian            {*this = make_error_condition(__e);}
25911820Sjulian
26011820Sjulian    _LIBCPP_INLINE_VISIBILITY
26111820Sjulian    void assign(int __val, const error_category& __cat) _NOEXCEPT
26214165Sjulian    {
26314165Sjulian        __val_ = __val;
26414165Sjulian        __cat_ = &__cat;
26514165Sjulian    }
26614165Sjulian
26711820Sjulian    template <class _Ep>
26811820Sjulian        _LIBCPP_INLINE_VISIBILITY
26911820Sjulian        typename enable_if
27011820Sjulian        <
27111820Sjulian            is_error_condition_enum<_Ep>::value,
27211820Sjulian            error_condition&
27311820Sjulian        >::type
27411820Sjulian        operator=(_Ep __e) _NOEXCEPT
27511820Sjulian            {*this = make_error_condition(__e); return *this;}
27611820Sjulian
27711820Sjulian    _LIBCPP_INLINE_VISIBILITY
27811820Sjulian    void clear() _NOEXCEPT
279    {
280        __val_ = 0;
281        __cat_ = &generic_category();
282    }
283
284    _LIBCPP_INLINE_VISIBILITY
285    int value() const _NOEXCEPT {return __val_;}
286
287    _LIBCPP_INLINE_VISIBILITY
288    const error_category& category() const _NOEXCEPT {return *__cat_;}
289    string message() const;
290
291    _LIBCPP_INLINE_VISIBILITY
292        _LIBCPP_EXPLICIT
293        operator bool() const _NOEXCEPT {return __val_ != 0;}
294};
295
296inline _LIBCPP_INLINE_VISIBILITY
297error_condition
298make_error_condition(errc __e) _NOEXCEPT
299{
300    return error_condition(static_cast<int>(__e), generic_category());
301}
302
303inline _LIBCPP_INLINE_VISIBILITY
304bool
305operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT
306{
307    return __x.category() < __y.category()
308        || (__x.category() == __y.category() && __x.value() < __y.value());
309}
310
311// error_code
312
313class _LIBCPP_TYPE_VIS error_code
314{
315    int __val_;
316    const error_category* __cat_;
317public:
318    _LIBCPP_INLINE_VISIBILITY
319    error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {}
320
321    _LIBCPP_INLINE_VISIBILITY
322    error_code(int __val, const error_category& __cat) _NOEXCEPT
323        : __val_(__val), __cat_(&__cat) {}
324
325    template <class _Ep>
326        _LIBCPP_INLINE_VISIBILITY
327        error_code(_Ep __e,
328                   typename enable_if<is_error_code_enum<_Ep>::value>::type* = 0
329                                                                     ) _NOEXCEPT
330            {*this = make_error_code(__e);}
331
332    _LIBCPP_INLINE_VISIBILITY
333    void assign(int __val, const error_category& __cat) _NOEXCEPT
334    {
335        __val_ = __val;
336        __cat_ = &__cat;
337    }
338
339    template <class _Ep>
340        _LIBCPP_INLINE_VISIBILITY
341        typename enable_if
342        <
343            is_error_code_enum<_Ep>::value,
344            error_code&
345        >::type
346        operator=(_Ep __e) _NOEXCEPT
347            {*this = make_error_code(__e); return *this;}
348
349    _LIBCPP_INLINE_VISIBILITY
350    void clear() _NOEXCEPT
351    {
352        __val_ = 0;
353        __cat_ = &system_category();
354    }
355
356    _LIBCPP_INLINE_VISIBILITY
357    int value() const _NOEXCEPT {return __val_;}
358
359    _LIBCPP_INLINE_VISIBILITY
360    const error_category& category() const _NOEXCEPT {return *__cat_;}
361
362    _LIBCPP_INLINE_VISIBILITY
363    error_condition default_error_condition() const _NOEXCEPT
364        {return __cat_->default_error_condition(__val_);}
365
366    string message() const;
367
368    _LIBCPP_INLINE_VISIBILITY
369        _LIBCPP_EXPLICIT
370        operator bool() const _NOEXCEPT {return __val_ != 0;}
371};
372
373inline _LIBCPP_INLINE_VISIBILITY
374error_code
375make_error_code(errc __e) _NOEXCEPT
376{
377    return error_code(static_cast<int>(__e), generic_category());
378}
379
380inline _LIBCPP_INLINE_VISIBILITY
381bool
382operator<(const error_code& __x, const error_code& __y) _NOEXCEPT
383{
384    return __x.category() < __y.category()
385        || (__x.category() == __y.category() && __x.value() < __y.value());
386}
387
388inline _LIBCPP_INLINE_VISIBILITY
389bool
390operator==(const error_code& __x, const error_code& __y) _NOEXCEPT
391{
392    return __x.category() == __y.category() && __x.value() == __y.value();
393}
394
395inline _LIBCPP_INLINE_VISIBILITY
396bool
397operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT
398{
399    return __x.category().equivalent(__x.value(), __y)
400        || __y.category().equivalent(__x, __y.value());
401}
402
403inline _LIBCPP_INLINE_VISIBILITY
404bool
405operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT
406{
407    return __y == __x;
408}
409
410inline _LIBCPP_INLINE_VISIBILITY
411bool
412operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT
413{
414    return __x.category() == __y.category() && __x.value() == __y.value();
415}
416
417inline _LIBCPP_INLINE_VISIBILITY
418bool
419operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT
420{return !(__x == __y);}
421
422inline _LIBCPP_INLINE_VISIBILITY
423bool
424operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT
425{return !(__x == __y);}
426
427inline _LIBCPP_INLINE_VISIBILITY
428bool
429operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT
430{return !(__x == __y);}
431
432inline _LIBCPP_INLINE_VISIBILITY
433bool
434operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT
435{return !(__x == __y);}
436
437template <>
438struct _LIBCPP_TEMPLATE_VIS hash<error_code>
439    : public unary_function<error_code, size_t>
440{
441    _LIBCPP_INLINE_VISIBILITY
442    size_t operator()(const error_code& __ec) const _NOEXCEPT
443    {
444        return static_cast<size_t>(__ec.value());
445    }
446};
447
448template <>
449struct _LIBCPP_TEMPLATE_VIS hash<error_condition>
450    : public unary_function<error_condition, size_t>
451{
452    _LIBCPP_INLINE_VISIBILITY
453    size_t operator()(const error_condition& __ec) const _NOEXCEPT
454    {
455        return static_cast<size_t>(__ec.value());
456    }
457};
458
459// system_error
460
461class _LIBCPP_TYPE_VIS system_error
462    : public runtime_error
463{
464    error_code __ec_;
465public:
466    system_error(error_code __ec, const string& __what_arg);
467    system_error(error_code __ec, const char* __what_arg);
468    system_error(error_code __ec);
469    system_error(int __ev, const error_category& __ecat, const string& __what_arg);
470    system_error(int __ev, const error_category& __ecat, const char* __what_arg);
471    system_error(int __ev, const error_category& __ecat);
472    ~system_error() _NOEXCEPT;
473
474    _LIBCPP_INLINE_VISIBILITY
475    const error_code& code() const _NOEXCEPT {return __ec_;}
476
477private:
478    static string __init(const error_code&, string);
479};
480
481_LIBCPP_NORETURN _LIBCPP_FUNC_VIS
482void __throw_system_error(int ev, const char* what_arg);
483
484_LIBCPP_END_NAMESPACE_STD
485
486#endif  // _LIBCPP_SYSTEM_ERROR
487