%!TEX root = std.tex
\rSec0[diagnostics]{Diagnostics library}

\rSec1[diagnostics.general]{General}

\pnum
This Clause describes components that \Cpp programs may use to detect and
report error conditions.

\pnum
The following subclauses describe components for
reporting several kinds of exceptional conditions,
documenting program assertions, and
a global variable for error number codes,
as summarized in Table~\ref{tab:diagnostics.lib.summary}.

\begin{libsumtab}{Diagnostics library summary}{tab:diagnostics.lib.summary}
\ref{std.exceptions}  & Exception classes     &   \tcode{<stdexcept>}     \\ \rowsep
\ref{assertions}      & Assertions            &   \tcode{<cassert>}       \\ \rowsep
\ref{errno}           & Error numbers         &   \tcode{<cerrno>}        \\ \rowsep
\ref{syserr}          & System error support  &   \tcode{<system_error>}  \\ \rowsep
\end{libsumtab}

\rSec1[std.exceptions]{Exception classes}

\pnum
The Standard \Cpp library provides classes to be used to report certain errors~(\ref{res.on.exception.handling}) in
\Cpp programs.
In the error model reflected in these classes, errors are divided into two
broad categories:
\term{logic}
errors and
\term{runtime}
errors.

\pnum
The distinguishing characteristic of logic errors is that they are due to errors
in the internal logic of the program.
In theory, they are preventable.

\pnum
By contrast, runtime errors are due to events beyond the scope of the program.
They cannot be easily predicted in advance.
The header
\tcode{<stdexcept>}
\indextext{\idxhdr{stdexcept}}%
\indexlibrary{\idxhdr{stdexcept}}%
defines several types of predefined exceptions for reporting errors in a \Cpp program.
These exceptions are related by inheritance.

\synopsis{Header \tcode{<stdexcept>} synopsis}

\indexlibrary{\idxhdr{stdexcept}}%
\indexlibrary{\idxcode{logic_error}}%
\indexlibrary{\idxcode{domain_error}}%
\indexlibrary{\idxcode{invalid_argument}}%
\indexlibrary{\idxcode{length_error}}%
\indexlibrary{\idxcode{out_of_range_error}}%
\indexlibrary{\idxcode{runtime_error}}%
\indexlibrary{\idxcode{range_error}}%
\indexlibrary{\idxcode{overflow_error}}%
\indexlibrary{\idxcode{underflow_error}}%
\begin{codeblock}
namespace std {
  class logic_error;
    class domain_error;
    class invalid_argument;
    class length_error;
    class out_of_range;
  class runtime_error;
    class range_error;
    class overflow_error;
    class underflow_error;
}
\end{codeblock}

\rSec2[logic.error]{Class \tcode{logic_error}}

\indexlibrary{\idxcode{logic_error}}%
\begin{codeblock}
namespace std {
  class logic_error : public exception {
  public:
    explicit logic_error(const string& what_arg);
    explicit logic_error(const char* what_arg);
  };
}
\end{codeblock}

\pnum
The class
\tcode{logic_error}
defines the type of objects thrown as
exceptions to report errors presumably detectable before
the program executes, such as violations of logical preconditions or class
invariants.

\indexlibrary{\idxcode{logic_error}!\tcode{logic_error}}%
\begin{itemdecl}
logic_error(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{logic_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg.c_str()) == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{logic_error}!\tcode{logic_error}}%
\begin{itemdecl}
logic_error(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{logic_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec2[domain.error]{Class \tcode{domain_error}}

\indexlibrary{\idxcode{domain_error}}%
\begin{codeblock}
namespace std {
  class domain_error : public logic_error {
  public:
    explicit domain_error(const string& what_arg);
    explicit domain_error(const char* what_arg);
  };
}
\end{codeblock}

\pnum
The class
\tcode{domain_error}
defines the type of objects thrown as
exceptions by the implementation to report domain errors.

\indexlibrary{\idxcode{domain_error}!\tcode{domain_error}}%
\begin{itemdecl}
domain_error(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{domain_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg.c_str()) == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{domain_error}!\tcode{domain_error}}%
\begin{itemdecl}
domain_error(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{domain_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec2[invalid.argument]{Class \tcode{invalid_argument}}

\indexlibrary{\idxcode{invalid_argument}}%
\begin{codeblock}
namespace std {
  class invalid_argument : public logic_error {
  public:
    explicit invalid_argument(const string& what_arg);
    explicit invalid_argument(const char* what_arg);
  };
}
\end{codeblock}

\pnum
The class
\tcode{invalid_argument}
defines the type of objects thrown as exceptions to report an invalid argument.

\indexlibrary{\idxcode{invalid_argument}!\tcode{invalid_argument}}%
\begin{itemdecl}
invalid_argument(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{invalid_argument}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg.c_str()) == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{invalid_argument}!\tcode{invalid_argument}}%
\begin{itemdecl}
invalid_argument(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{invalid_argument}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec2[length.error]{Class \tcode{length_error}}

\indexlibrary{\idxcode{length_error}}%
\begin{codeblock}
namespace std {
  class length_error : public logic_error {
  public:
    explicit length_error(const string& what_arg);
    explicit length_error(const char* what_arg);
  };
}
\end{codeblock}

\pnum
The class
\tcode{length_error}
defines the type of objects thrown as exceptions
to report an attempt to produce
an object whose length exceeds its maximum allowable size.

\indexlibrary{\idxcode{length_error}!\tcode{length_error}}%
\begin{itemdecl}
length_error(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{length_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg.c_str()) == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{length_error}!\tcode{length_error}}%
\begin{itemdecl}
length_error(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{length_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec2[out.of.range]{Class \tcode{out_of_range}}

\indexlibrary{\idxcode{out_of_range}}%
\begin{codeblock}
namespace std {
  class out_of_range : public logic_error {
  public:
    explicit out_of_range(const string& what_arg);
    explicit out_of_range(const char* what_arg);
  };
}
\end{codeblock}

\pnum
The class
\tcode{out_of_range}
defines the type of objects thrown as exceptions to report an
argument value not in its expected range.
\indextext{argument}

\indexlibrary{\idxcode{out_of_range}!\tcode{out_of_range}}%
\begin{itemdecl}
out_of_range(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{out_of_range}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg.c_str()) == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{out_of_range}!\tcode{out_of_range}}%
\begin{itemdecl}
out_of_range(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{out_of_range}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec2[runtime.error]{Class \tcode{runtime_error}}

\indexlibrary{\idxcode{runtime_error}}%
\begin{codeblock}
namespace std {
  class runtime_error : public exception {
  public:
    explicit runtime_error(const string& what_arg);
    explicit runtime_error(const char* what_arg);
  };
}
\end{codeblock}

\pnum
The class
\tcode{runtime_error}
defines the type of objects thrown as exceptions to report errors presumably detectable only
when the program executes.

\indexlibrary{\idxcode{runtime_error}!\tcode{runtime_error}}%
\begin{itemdecl}
runtime_error(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{runtime_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg.c_str()) == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{runtime_error}!\tcode{runtime_error}}%
\begin{itemdecl}
runtime_error(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{runtime_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec2[range.error]{Class \tcode{range_error}}

\indexlibrary{\idxcode{range_error}}%
\begin{codeblock}
namespace std {
  class range_error : public runtime_error {
  public:
    explicit range_error(const string& what_arg);
    explicit range_error(const char* what_arg);
  };
}
\end{codeblock}

\pnum
The class
\tcode{range_error}
defines the type of objects thrown as exceptions to report range errors
in internal computations.

\indexlibrary{\idxcode{range_error}!\tcode{range_error}}%
\begin{itemdecl}
range_error(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{range_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg.c_str()) == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{range_error}!\tcode{range_error}}%
\begin{itemdecl}
range_error(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{range_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec2[overflow.error]{Class \tcode{overflow_error}}

\indexlibrary{\idxcode{overflow_error}}%
\begin{codeblock}
namespace std {
  class overflow_error : public runtime_error {
  public:
    explicit overflow_error(const string& what_arg);
    explicit overflow_error(const char* what_arg);
  };
}
\end{codeblock}

\pnum
The class
\tcode{overflow_error}
defines the type of objects thrown as exceptions to report an arithmetic overflow error.

\indexlibrary{\idxcode{overflow_error}!\tcode{overflow_error}}%
\begin{itemdecl}
overflow_error(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{overflow_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg.c_str()) == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{overflow_error}!\tcode{overflow_error}}%
\begin{itemdecl}
overflow_error(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{overflow_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec2[underflow.error]{Class \tcode{underflow_error}}

\indexlibrary{\idxcode{overflow_error}}%
\begin{codeblock}
namespace std {
  class underflow_error : public runtime_error {
  public:
    explicit underflow_error(const string& what_arg);
    explicit underflow_error(const char* what_arg);
  };
}
\end{codeblock}

\pnum
The class
\tcode{underflow_error}
defines the type of objects thrown as exceptions to report an arithmetic underflow error.

\indexlibrary{\idxcode{underflow_error}!\tcode{underflow_error}}%
\begin{itemdecl}
underflow_error(const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{underflow_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg.c_str()) == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{underflow_error}!\tcode{underflow_error}}%
\begin{itemdecl}
underflow_error(const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of class
\tcode{underflow_error}.

\pnum
\postcondition
\tcode{strcmp(what(), what_arg) == 0}.
\end{itemdescr}

\rSec1[assertions]{Assertions}

\pnum
The header
\tcode{<cassert>}, described in
(Table~\ref{tab:diagnostics.hdr.cassert}),
provides a macro for documenting \Cpp program assertions and a mechanism
for disabling the assertion checks.

\begin{libsyntab2}{cassert}{tab:diagnostics.hdr.cassert}
\macro  &   \tcode{assert}  \\
\end{libsyntab2}

\pnum
The contents are the same as the Standard C library header
\tcode{<assert.h>}.

\xref
ISO C 7.2.

\rSec1[errno]{Error numbers}

\pnum
The header \tcode{<cerrno>} is described in Table~\ref{tab:diagnostics.hdr.cerrno}. Its contents are the same as the POSIX header \tcode{<errno.h>}, except that \tcode{errno} shall be defined as a macro. \enternote The intent is to remain in close alignment with the POSIX standard. \exitnote A separate \tcode{errno} value shall be provided for each thread.

\begin{libsyntab6}{cerrno}{tab:diagnostics.hdr.cerrno}

\macros &
\tcode{ECONNREFUSED} &
\tcode{EIO} &
\tcode{ENODEV} &
\tcode{ENOTEMPTY} &
\tcode{ERANGE} \\

\tcode{E2BIG} &
\tcode{ECONNRESET} &
\tcode{EISCONN} &
\tcode{ENOENT} &
\tcode{ENOTRECOVERABLE} &
\tcode{EROFS} \\

\tcode{EACCES} &
\tcode{EDEADLK} &
\tcode{EISDIR} &
\tcode{ENOEXEC} &
\tcode{ENOTSOCK} &
\tcode{ESPIPE} \\

\tcode{EADDRINUSE} &
\tcode{EDESTADDRREQ} &
\tcode{ELOOP} &
\tcode{ENOLCK} &
\tcode{ENOTSUP} &
\tcode{ESRCH} \\

\tcode{EADDRNOTAVAIL} &
\tcode{EDOM} &
\tcode{EMFILE} &
\tcode{ENOLINK} &
\tcode{ENOTTY} &
\tcode{ETIME} \\

\tcode{EAFNOSUPPORT} &
\tcode{EEXIST} &
\tcode{EMLINK} &
\tcode{ENOMEM} &
\tcode{ENXIO} &
\tcode{ETIMEDOUT} \\

\tcode{EAGAIN} &
\tcode{EFAULT} &
\tcode{EMSGSIZE} &
\tcode{ENOMSG} &
\tcode{EOPNOTSUPP} &
\tcode{ETXTBSY} \\

\tcode{EALREADY} &
\tcode{EFBIG} &
\tcode{ENAMETOOLONG} &
\tcode{ENOPROTOOPT} &
\tcode{EOVERFLOW} &
\tcode{EWOULDBLOCK} \\

\tcode{EBADF} &
\tcode{EHOSTUNREACH} &
\tcode{ENETDOWN} &
\tcode{ENOSPC} &
\tcode{EOWNERDEAD} &
\tcode{EXDEV} \\

\tcode{EBADMSG} &
\tcode{EIDRM} &
\tcode{ENETRESET} &
\tcode{ENOSR} &
\tcode{EPERM} &
\tcode{errno} \\

\tcode{EBUSY} &
\tcode{EILSEQ} &
\tcode{ENETUNREACH} &
\tcode{ENOSTR} &
\tcode{EPIPE}  & \\

\tcode{ECANCELED} &
\tcode{EINPROGRESS} &
\tcode{ENFILE} &
\tcode{ENOSYS} &
\tcode{EPROTO} & \\

\tcode{ECHILD} &
\tcode{EINTR} &
\tcode{ENOBUFS} &
\tcode{ENOTCONN} &
\tcode{EPROTONOSUPPORT} & \\

\tcode{ECONNABORTED} &
\tcode{EINVAL} &
\tcode{ENODATA} &
\tcode{ENOTDIR} &
\tcode{EPROTOTYPE} & \\

\end{libsyntab6}

\rSec1[syserr]{System error support}

\pnum
This subclause describes components that the standard library and
\Cpp programs may use to report error conditions originating from
the operating system or other low-level application program interfaces.

\pnum
Components described in this subclause shall not change the value of
\tcode{errno}~(\ref{errno}).
Implementations should leave the error states provided by other
libraries unchanged.

\synopsis{Header \tcode{<system_error>} synopsis}

\indexlibrary{\idxcode{error_category}}%
\indexlibrary{\idxcode{error_code}}%
\indexlibrary{\idxcode{error_condition}}%
\indexlibrary{\idxcode{system_error}}%
\indexlibrary{\idxcode{is_error_code_enum}}%
\indexlibrary{\idxcode{is_error_condition_enum}}%
\indexlibrary{\idxcode{errc}}%
\indexlibrary{\idxcode{make_error_code}}%
\indexlibrary{\idxcode{make_error_condition}}%
\begin{codeblock}
namespace std {
  class error_category;
  const error_category& generic_category() noexcept;
  const error_category& system_category() noexcept;

  class error_code;
  class error_condition;
  class system_error;

  template <class T>
  struct is_error_code_enum : public false_type {};

  template <class T>
  struct is_error_condition_enum : public false_type {};

  enum class errc {
    address_family_not_supported,       // \tcode{EAFNOSUPPORT}
    address_in_use,                     // \tcode{EADDRINUSE}
    address_not_available,              // \tcode{EADDRNOTAVAIL}
    already_connected,                  // \tcode{EISCONN}
    argument_list_too_long,             // \tcode{E2BIG}
    argument_out_of_domain,             // \tcode{EDOM}
    bad_address,                        // \tcode{EFAULT}
    bad_file_descriptor,                // \tcode{EBADF}
    bad_message,                        // \tcode{EBADMSG}
    broken_pipe,                        // \tcode{EPIPE}
    connection_aborted,                 // \tcode{ECONNABORTED}
    connection_already_in_progress,     // \tcode{EALREADY}
    connection_refused,                 // \tcode{ECONNREFUSED}
    connection_reset,                   // \tcode{ECONNRESET}
    cross_device_link,                  // \tcode{EXDEV}
    destination_address_required,       // \tcode{EDESTADDRREQ}
    device_or_resource_busy,            // \tcode{EBUSY}
    directory_not_empty,                // \tcode{ENOTEMPTY}
    executable_format_error,            // \tcode{ENOEXEC}
    file_exists,                        // \tcode{EEXIST}
    file_too_large,                     // \tcode{EFBIG}
    filename_too_long,                  // \tcode{ENAMETOOLONG}
    function_not_supported,             // \tcode{ENOSYS}
    host_unreachable,                   // \tcode{EHOSTUNREACH}
    identifier_removed,                 // \tcode{EIDRM}
    illegal_byte_sequence,              // \tcode{EILSEQ}
    inappropriate_io_control_operation, // \tcode{ENOTTY}
    interrupted,                        // \tcode{EINTR}
    invalid_argument,                   // \tcode{EINVAL}
    invalid_seek,                       // \tcode{ESPIPE}
    io_error,                           // \tcode{EIO}
    is_a_directory,                     // \tcode{EISDIR}
    message_size,                       // \tcode{EMSGSIZE}
    network_down,                       // \tcode{ENETDOWN}
    network_reset,                      // \tcode{ENETRESET}
    network_unreachable,                // \tcode{ENETUNREACH}
    no_buffer_space,                    // \tcode{ENOBUFS}
    no_child_process,                   // \tcode{ECHILD}
    no_link,                            // \tcode{ENOLINK}
    no_lock_available,                  // \tcode{ENOLCK}
    no_message_available,               // \tcode{ENODATA}
    no_message,                         // \tcode{ENOMSG}
    no_protocol_option,                 // \tcode{ENOPROTOOPT}
    no_space_on_device,                 // \tcode{ENOSPC}
    no_stream_resources,                // \tcode{ENOSR}
    no_such_device_or_address,          // \tcode{ENXIO}
    no_such_device,                     // \tcode{ENODEV}
    no_such_file_or_directory,          // \tcode{ENOENT}
    no_such_process,                    // \tcode{ESRCH}
    not_a_directory,                    // \tcode{ENOTDIR}
    not_a_socket,                       // \tcode{ENOTSOCK}
    not_a_stream,                       // \tcode{ENOSTR}
    not_connected,                      // \tcode{ENOTCONN}
    not_enough_memory,                  // \tcode{ENOMEM}
    not_supported,                      // \tcode{ENOTSUP}
    operation_canceled,                 // \tcode{ECANCELED}
    operation_in_progress,              // \tcode{EINPROGRESS}
    operation_not_permitted,            // \tcode{EPERM}
    operation_not_supported,            // \tcode{EOPNOTSUPP}
    operation_would_block,              // \tcode{EWOULDBLOCK}
    owner_dead,                         // \tcode{EOWNERDEAD}
    permission_denied,                  // \tcode{EACCES}
    protocol_error,                     // \tcode{EPROTO}
    protocol_not_supported,             // \tcode{EPROTONOSUPPORT}
    read_only_file_system,              // \tcode{EROFS}
    resource_deadlock_would_occur,      // \tcode{EDEADLK}
    resource_unavailable_try_again,     // \tcode{EAGAIN}
    result_out_of_range,                // \tcode{ERANGE}
    state_not_recoverable,              // \tcode{ENOTRECOVERABLE}
    stream_timeout,                     // \tcode{ETIME}
    text_file_busy,                     // \tcode{ETXTBSY}
    timed_out,                          // \tcode{ETIMEDOUT}
    too_many_files_open_in_system,      // \tcode{ENFILE}
    too_many_files_open,                // \tcode{EMFILE}
    too_many_links,                     // \tcode{EMLINK}
    too_many_symbolic_link_levels,      // \tcode{ELOOP}
    value_too_large,                    // \tcode{EOVERFLOW}
    wrong_protocol_type,                // \tcode{EPROTOTYPE}
  };
  
  template <> struct is_error_condition_enum<errc> : true_type { }

  error_code make_error_code(errc e) noexcept;
  error_condition make_error_condition(errc e) noexcept;

  // \ref{syserr.compare} Comparison operators:
  bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
  bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
  bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
  bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
  bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
  bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
  bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
  bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;

  // \ref{syserr.hash} Hash support
  template <class T> struct hash;
  template <> struct hash<error_code>;
}  // namespace std
\end{codeblock}

\pnum The value of each \tcode{enum errc} constant shall be the same as
the value of the \tcode{<cerrno>} macro shown in the above synopsis. Whether
or not the \tcode{<system_error>} implementation exposes the \tcode{<cerrno>}
macros is unspecified.

\pnum
The \tcode{is_error_code_enum} and \tcode{is_error_condition_enum} may be
specialized for user-defined types to indicate that such types are eligible
for \tcode{class error_code} and \tcode{class error_condition} automatic
conversions, respectively.

\rSec2[syserr.errcat]{Class \tcode{error_category}}

\rSec3[syserr.errcat.overview]{Class \tcode{error_category} overview}

\pnum
The class \tcode{error_category} serves as a base class for types used
to identify the source and encoding of a particular category of error code.
Classes may be derived from \tcode{error_category} to support
categories of errors in addition to those defined in this International
Standard.
Such classes shall behave as specified in this
subclause. \enternote \tcode{error_category} objects are
passed by reference, and two such objects
are equal if they have the same address. This means that applications using
custom \tcode{error_category} types should create a single object of each
such type. \exitnote

\indexlibrary{\idxcode{error_category}}%
\indexlibrary{\idxcode{generic_category}}%
\indexlibrary{\idxcode{system_category}}%
\begin{codeblock}
namespace std {
  class error_category {
  public:
    constexpr error_category() noexcept;
    virtual ~error_category();
    error_category(const error_category&) = delete;
    error_category& operator=(const error_category&) = delete;
    virtual const char* name() const noexcept = 0;
    virtual error_condition default_error_condition(int ev) const noexcept;
    virtual bool equivalent(int code, const error_condition& condition) const noexcept;
    virtual bool equivalent(const error_code& code, int condition) const noexcept;
    virtual string message(int ev) const = 0;
    
    bool operator==(const error_category& rhs) const noexcept;
    bool operator!=(const error_category& rhs) const noexcept;
    bool operator<(const error_category& rhs) const noexcept;
  };

  const error_category& generic_category() noexcept;
  const error_category& system_category() noexcept;

}   // namespace std
\end{codeblock}

\rSec3[syserr.errcat.virtuals]{Class \tcode{error_category} virtual members}

\indexlibrary{\idxcode{error_category}!destructor}%
\begin{itemdecl}
virtual ~error_category();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Destroys an object of class \tcode{error_category}.
\end{itemdescr}

\indexlibrary{\idxcode{name}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{name}}
\begin{itemdecl}
virtual const char* name() const noexcept = 0;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns A string naming the error category.
\end{itemdescr}

\indexlibrary{\idxcode{default_error_condition}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{default_error_condition}}
\begin{itemdecl}
virtual error_condition default_error_condition(int ev) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{error_condition(ev, *this)}.
\end{itemdescr}

\indexlibrary{\idxcode{equivalent}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{equivalent}}
\begin{itemdecl}
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{default_error_condition(code) == condition}.
\end{itemdescr}

\indexlibrary{\idxcode{equivalent}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{equivalent}}
\begin{itemdecl}
virtual bool equivalent(const error_code& code, int condition) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{*this == code.category() \&\& code.value() == condition}.
\end{itemdescr}

\indexlibrary{\idxcode{message}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{message}}
\begin{itemdecl}
virtual string message(int ev) const = 0;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns A string that describes the error condition denoted by \tcode{ev}.
\end{itemdescr}

\rSec3[syserr.errcat.nonvirtuals]{Class \tcode{error_category} non-virtual members}

\indexlibrary{\idxcode{error_category}!constructor}%
\begin{itemdecl}
constexpr error_category() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of class \tcode{error_category}.
\end{itemdescr}

\indexlibrary{\idxcode{operator==}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{operator==}}
\begin{itemdecl}
bool operator==(const error_category& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{this == \&rhs}.
\end{itemdescr}

\indexlibrary{\idxcode{operator"!=}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{operator"!=}}
\begin{itemdecl}
bool operator!=(const error_category& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{!(*this == rhs)}.
\end{itemdescr}

\indexlibrary{\idxcode{operator<}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{operator<}}
\begin{itemdecl}
bool operator<(const error_category& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{less<const error_category*>()(this, \&rhs)}.

\enternote \tcode{less}~(\ref{comparisons}) provides a total ordering for pointers. \exitnote
\end{itemdescr}

\rSec3[syserr.errcat.derived]{Program defined classes derived from \tcode{error_category}}

\indexlibrary{\idxcode{name}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{name}}
\begin{itemdecl}
virtual const char* name() const noexcept = 0;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns A string naming the error category.
\end{itemdescr}

\indexlibrary{\idxcode{default_error_condition}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{default_error_condition}}
\begin{itemdecl}
virtual error_condition default_error_condition(int ev) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns An object of type \tcode{error_condition} that corresponds to \tcode{ev}.
\end{itemdescr}

\indexlibrary{\idxcode{equivalent}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{equivalent}}
\begin{itemdecl}
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{true} if, for the category of error represented by \tcode{*this}, \tcode{code} is considered equivalent to \tcode{condition}; otherwise, \tcode{false}.
\end{itemdescr}

\indexlibrary{\idxcode{equivalent}!\idxcode{error_category}}
\indexlibrary{\idxcode{error_category}!\idxcode{equivalent}}
\begin{itemdecl}
virtual bool equivalent(const error_code& code, int condition) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{true} if, for the category of error represented by \tcode{*this}, \tcode{code} is considered equivalent to \tcode{condition}; otherwise, \tcode{false}.
\end{itemdescr}

\rSec3[syserr.errcat.objects]{Error category objects}

\indexlibrary{\idxcode{generic_category}}
\begin{itemdecl}
const error_category& generic_category() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns A reference to an object of a type derived from class \tcode{error_category}.
All calls to this function shall return references to the same object.

\pnum
\notes The object's \tcode{default_error_condition} and \tcode{equivalent} virtual functions shall behave as specified for the class \tcode{error_category}. The object's \tcode{name} virtual function shall return a pointer to the string \tcode{"generic"}.
\end{itemdescr}

\indexlibrary{\idxcode{system_category}}
\begin{itemdecl}
const error_category& system_category() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns A reference to an object of a type derived from class \tcode{error_category}.
All calls to this function shall return references to the same object.

\pnum
\notes The object's \tcode{equivalent} virtual functions shall behave as specified for
class \tcode{error_category}. The object's \tcode{name} virtual function shall return a
pointer to the string \tcode{"system"}. The object's \tcode{default_error_condition}
virtual function shall behave as follows:

If the argument \tcode{ev} corresponds to a POSIX \tcode{errno} value \tcode{posv}, the
function shall return \tcode{error_condition(posv, generic_category())}.
Otherwise, the function shall return \tcode{error_condition(ev,
system_category())}. What constitutes correspondence for any given operating
system is unspecified. \enternote The number of potential system error codes is large
and unbounded, and some may not correspond to any POSIX \tcode{errno} value. Thus
implementations are given latitude in determining correspondence. \exitnote
\end{itemdescr}

\rSec2[syserr.errcode]{Class \tcode{error_code}}

\rSec3[syserr.errcode.overview]{Class \tcode{error_code} overview}

\pnum
The class \tcode{error_code} describes an object used to hold error code
values, such as those originating from the operating system or other low-level
application program interfaces. \enternote Class \tcode{error_code} is an
adjunct to error reporting by exception. \exitnote

\indexlibrary{\idxcode{error_code}}%
\begin{codeblock}
namespace std {
  class error_code {
  public:
    // \ref{syserr.errcode.constructors} constructors:
    error_code() noexcept;
    error_code(int val, const error_category& cat) noexcept;
    template <class ErrorCodeEnum>
      error_code(ErrorCodeEnum e) noexcept;

    // \ref{syserr.errcode.modifiers} modifiers:
    void assign(int val, const error_category& cat) noexcept;
    template <class ErrorCodeEnum>
        error_code& operator=(ErrorCodeEnum e) noexcept;
    void clear() noexcept;

    // \ref{syserr.errcode.observers} observers:
    int value() const noexcept;
    const error_category& category() const noexcept;
    error_condition default_error_condition() const noexcept;
    string message() const;
    explicit operator bool() const noexcept;

  private:
    int val_;                   // \expos
    const error_category* cat_; // \expos
  };

  // \ref{syserr.errcode.nonmembers} non-member functions:
  error_code make_error_code(errc e) noexcept;
  bool operator<(const error_code& lhs, const error_code& rhs) noexcept;

  template <class charT, class traits>
    basic_ostream<charT,traits>&
      operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
}   // namespace std
\end{codeblock}

\rSec3[syserr.errcode.constructors]{Class \tcode{error_code} constructors}

\indexlibrary{\idxcode{error_code}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{error_code}}
\begin{itemdecl}
error_code() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of type \tcode{error_code}.

\pnum
\postconditions \tcode{val_ == 0} and \tcode{cat_ == \&system_category()}.
\end{itemdescr}

\indexlibrary{\idxcode{error_code}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{error_code}}
\begin{itemdecl}
error_code(int val, const error_category& cat) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of type \tcode{error_code}.

\pnum
\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}.
\end{itemdescr}

\indexlibrary{\idxcode{error_code}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{error_code}}
\begin{itemdecl}
template <class ErrorCodeEnum>
  error_code(ErrorCodeEnum e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of type \tcode{error_code}.

\pnum
\postconditions \tcode{*this == make_error_code(e)}.

\pnum
\remarks This constructor shall not participate in overload resolution unless\linebreak
\tcode{is_error_code_enum<ErrorCodeEnum>::value} is \tcode{true}.
\end{itemdescr}

\rSec3[syserr.errcode.modifiers]{Class \tcode{error_code} modifiers}

\indexlibrary{\idxcode{assign}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{assign}}
\begin{itemdecl}
void assign(int val, const error_category& cat) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}.
\end{itemdescr}

\indexlibrary{\idxcode{operator=}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{operator=}}
\begin{itemdecl}
template <class ErrorCodeEnum>
    error_code& operator=(ErrorCodeEnum e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\postconditions \tcode{*this == make_error_code(e)}.

\pnum
\returns \tcode{*this}.

\pnum
\remarks This operator shall not participate in overload resolution unless\linebreak
\tcode{is_error_code_enum<ErrorCodeEnum>::value} is \tcode{true}.
\end{itemdescr}

\indexlibrary{\idxcode{clear}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{clear}}
\begin{itemdecl}
void clear() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\postconditions \tcode{value() == 0} and \tcode{category() == system_category()}.
\end{itemdescr}


\rSec3[syserr.errcode.observers]{Class \tcode{error_code} observers}

\indexlibrary{\idxcode{value}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{value}}
\begin{itemdecl}
int value() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{val_}.
\end{itemdescr}

\indexlibrary{\idxcode{category}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{category}}
\begin{itemdecl}
const error_category& category() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{*cat_}.
\end{itemdescr}

\indexlibrary{\idxcode{default_error_condition}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{default_error_condition}}
\begin{itemdecl}
error_condition default_error_condition() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{category().default_error_condition(value())}.
\end{itemdescr}

\indexlibrary{\idxcode{message}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{message}}
\begin{itemdecl}
string message() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{category().message(value())}.
\end{itemdescr}

\indexlibrary{\idxcode{operator bool}!\idxcode{error_code}}
\indexlibrary{\idxcode{error_code}!\idxcode{operator bool}}
\begin{itemdecl}
explicit operator bool() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{value() != 0}.
\end{itemdescr}

\rSec3[syserr.errcode.nonmembers]{Class \tcode{error_code} non-member functions}

\indexlibrary{\idxcode{make_error_code}}
\begin{itemdecl}
error_code make_error_code(errc e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{error_code(static_cast<int>(e), generic_category())}.
\end{itemdescr}

\indexlibrary{\idxcode{operator<}!\idxcode{error_code}}%
\indexlibrary{\idxcode{error_code}!\idxcode{operator<}}%
\begin{itemdecl}
bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{lhs.category() < rhs.category() || lhs.category() == rhs.category() \&\& lhs.value() < rhs.value()}.
\end{itemdescr}

\indexlibrary{\idxcode{operator\shl}!\idxcode{error_code}}%
\indexlibrary{\idxcode{error_code}!\idxcode{operator\shl}}%
\begin{itemdecl}
template <class charT, class traits>
  basic_ostream<charT,traits>&
    operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects \tcode{os <{<} ec.category().name() <{<} ':' <{<} ec.value()}.
\end{itemdescr}


\rSec2[syserr.errcondition]{Class \tcode{error_condition}}

\rSec3[syserr.errcondition.overview]{Class \tcode{error_condition} overview}

\pnum
The class \tcode{error_condition} describes an object used to hold values identifying
error conditions. \enternote \tcode{error_condition} values are portable abstractions,
while \tcode{error_code} values~(\ref{syserr.errcode}) are implementation specific. \exitnote

\indexlibrary{\idxcode{error_code}}%
\begin{codeblock}
namespace std {
  class error_condition {
  public:
    // \ref{syserr.errcondition.constructors} constructors:
    error_condition() noexcept;
    error_condition(int val, const error_category& cat) noexcept;
    template <class ErrorConditionEnum>
      error_condition(ErrorConditionEnum e) noexcept;

    // \ref{syserr.errcondition.modifiers} modifiers:
    void assign(int val, const error_category& cat) noexcept;
    template<class ErrorConditionEnum>
        error_condition& operator=(ErrorConditionEnum e) noexcept;
    void clear() noexcept;

    // \ref{syserr.errcondition.observers} observers:
    int value() const noexcept;
    const error_category& category() const noexcept;
    string message() const;
    explicit operator bool() const noexcept;

  private:
    int val_;                   // \expos
    const error_category* cat_; // \expos
  };

  // \ref{syserr.errcondition.nonmembers} non-member functions:
  bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
} // namespace std
\end{codeblock}

\rSec3[syserr.errcondition.constructors]{Class \tcode{error_condition} constructors}

\indexlibrary{\idxcode{error_condition}!constructor}%
\begin{itemdecl}
error_condition() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of type \tcode{error_condition}.

\pnum
\postconditions \tcode{val_ == 0} and \tcode{cat_ == \&generic_category()}.
\end{itemdescr}

\indexlibrary{\idxcode{error_condition}!constructor}%
\begin{itemdecl}
error_condition(int val, const error_category& cat) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of type \tcode{error_condition}.

\pnum
\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}.
\end{itemdescr}

\indexlibrary{\idxcode{error_condition}!constructor}%
\begin{itemdecl}
template <class ErrorConditionEnum>
  error_condition(ErrorConditionEnum e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of type \tcode{error_condition}.

\pnum
\postcondition \tcode{*this == make_error_condition(e)}.

\pnum
\remarks This constructor shall not participate in overload resolution unless\linebreak
\tcode{is_error_condition_enum<ErrorConditionEnum>::value} is \tcode{true}.
\end{itemdescr}


\rSec3[syserr.errcondition.modifiers]{Class \tcode{error_condition} modifiers}

\indexlibrary{\idxcode{assign}!\idxcode{error_condition}}
\indexlibrary{\idxcode{error_condition}!\idxcode{assign}}
\begin{itemdecl}
void assign(int val, const error_category& cat) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}.
\end{itemdescr}

\indexlibrary{\idxcode{operator=}!\idxcode{error_condition}}
\indexlibrary{\idxcode{error_condition}!\idxcode{operator=}}
\begin{itemdecl}
template <class ErrorConditionEnum>
    error_condition& operator=(ErrorConditionEnum e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\postcondition \tcode{*this == make_error_condition(e)}.

\pnum
\returns \tcode{*this}.

\pnum
\remarks This operator shall not participate in overload resolution unless\linebreak
\tcode{is_error_condition_enum<ErrorConditionEnum>::value} is \tcode{true}.
\end{itemdescr}

\indexlibrary{\idxcode{clear}!\idxcode{error_condition}}
\indexlibrary{\idxcode{error_condition}!\idxcode{clear}}
\begin{itemdecl}
void clear() noexcept;
\end{itemdecl}

\begin{itemdescr}
\postconditions \tcode{value() == 0} and \tcode{category() == generic_category()}.
\end{itemdescr}

\rSec3[syserr.errcondition.observers]{Class \tcode{error_condition} observers}

\indexlibrary{\idxcode{value}!\idxcode{error_condition}}
\indexlibrary{\idxcode{error_condition}!\idxcode{value}}
\begin{itemdecl}
int value() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{val_}.
\end{itemdescr}

\indexlibrary{\idxcode{category}!\idxcode{error_condition}}
\indexlibrary{\idxcode{error_condition}!\idxcode{category}}
\begin{itemdecl}
const error_category& category() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{*cat_}.
\end{itemdescr}

\indexlibrary{\idxcode{message}!\idxcode{error_condition}}
\indexlibrary{\idxcode{error_condition}!\idxcode{message}}
\begin{itemdecl}
string message() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{category().message(value())}.
\end{itemdescr}

\indexlibrary{\idxcode{operator bool}!\idxcode{error_condition}}
\indexlibrary{\idxcode{error_condition}!\idxcode{operator bool}}
\begin{itemdecl}
explicit operator bool() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{value() != 0}.
\end{itemdescr}

\rSec3[syserr.errcondition.nonmembers]{Class \tcode{error_condition} non-member functions}

\indexlibrary{\idxcode{make_error_condition}}
\begin{itemdecl}
error_condition make_error_condition(errc e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\returns \tcode{error_condition(static_cast<int>(e), generic_category())}.
\end{itemdescr}

\indexlibrary{\idxcode{operator<}!\idxcode{error_condition}}%
\indexlibrary{\idxcode{error_condition}!\idxcode{operator<}}%
\begin{itemdecl}
bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{lhs.category() < rhs.category() || lhs.category() == rhs.category() \&\&\\
lhs.value() < rhs.value()}.
\end{itemdescr}

\rSec2[syserr.compare]{Comparison operators}

\indexlibrary{\idxcode{operator==}!\idxcode{error_code}}%
\indexlibrary{\idxcode{error_code}!\idxcode{operator==}}%
\begin{itemdecl}
bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{lhs.category() == rhs.category() \&\& lhs.value() == rhs.value()}.
\end{itemdescr}

\indexlibrary{\idxcode{operator==}!\idxcode{error_condition}}%
\indexlibrary{\idxcode{error_condition}!\idxcode{operator==}}%
\indexlibrary{\idxcode{operator==}!\idxcode{error_code}}%
\indexlibrary{\idxcode{error_code}!\idxcode{operator==}}%
\begin{itemdecl}
bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{lhs.category().equivalent(lhs.value(), rhs) || rhs.category().equivalent(lhs,
rhs.value())}.
\end{itemdescr}

\indexlibrary{\idxcode{operator==}!\idxcode{error_condition}}%
\indexlibrary{\idxcode{error_condition}!\idxcode{operator==}}%
\indexlibrary{\idxcode{operator==}!\idxcode{error_code}}%
\indexlibrary{\idxcode{error_code}!\idxcode{operator==}}%
\begin{itemdecl}
bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{rhs.category().equivalent(rhs.value(), lhs) || lhs.category().equivalent(rhs, lhs.value())}.
\end{itemdescr}

\indexlibrary{\idxcode{operator==}!\idxcode{error_condition}}%
\indexlibrary{\idxcode{error_condition}!\idxcode{operator==}}%
\begin{itemdecl}
bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{lhs.category() == rhs.category() \&\& lhs.value() == rhs.value()}.
\end{itemdescr}

\indexlibrary{\idxcode{operator"!=}!\idxcode{error_code}}%
\indexlibrary{\idxcode{error_code}!\idxcode{operator"!=}}%
\indexlibrary{\idxcode{operator"!=}!\idxcode{error_condition}}%
\indexlibrary{\idxcode{error_condition}!\idxcode{operator"!=}}%
\begin{itemdecl}
bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{!(lhs == rhs)}.
\end{itemdescr}

\rSec2[syserr.hash]{System error hash support}

\indexlibrary{\idxcode{hash}}%
\begin{itemdecl}
template <> struct hash<error_code>;
\end{itemdecl}

\begin{itemdescr}
\pnum The template specialization shall meet the requirements of class template
\tcode{hash}~(\ref{unord.hash}).
\end{itemdescr}

\rSec2[syserr.syserr]{Class \tcode{system_error}}

\rSec3[syserr.syserr.overview]{Class \tcode{system_error} overview}

\pnum
The class \tcode{system_error} describes an exception object used to
report error conditions that have an associated error code. Such error
conditions typically originate from the operating system or other low-level
application program interfaces.

\pnum
\enternote If an error represents an out-of-memory condition, implementations are
encouraged to throw an exception object of type \tcode{bad_alloc}~\ref{bad.alloc} rather
than \tcode{system_error}. \exitnote

\indexlibrary{\idxcode{system_error}}%
\begin{codeblock}
namespace std {
  class system_error : public runtime_error {
  public:
    system_error(error_code ec, const string& what_arg);
    system_error(error_code ec, const char* what_arg);
    system_error(error_code ec);
    system_error(int ev, const error_category& ecat,
        const string& what_arg);
    system_error(int ev, const error_category& ecat,
        const char* what_arg);
    system_error(int ev, const error_category& ecat);
    const error_code& code() const noexcept;
    const char* what() const noexcept;
  };
}   // namespace std
\end{codeblock}

\rSec3[syserr.syserr.members]{Class \tcode{system_error} members}

\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\begin{itemdecl}
system_error(error_code ec, const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of class \tcode{system_error}.

\pnum
\postconditions \tcode{code() == ec}.

\tcode{string(what()).find(what_arg) != string::npos}.
\end{itemdescr}

\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\begin{itemdecl}
system_error(error_code ec, const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of class \tcode{system_error}.

\pnum
\postconditions \tcode{code() == ec}.

\tcode{string(what()).find(what_arg) != string::npos}.
\end{itemdescr}

\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\begin{itemdecl}
system_error(error_code ec);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of class \tcode{system_error}.

\pnum
\postconditions \tcode{code() == ec}.
\end{itemdescr}

\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\begin{itemdecl}
system_error(int ev, const error_category& ecat,
  const string& what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of class \tcode{system_error}.

\pnum
\postconditions \tcode{code() == error_code(ev, ecat)}.

\tcode{string(what()).find(what_arg) != string::npos}.
\end{itemdescr}

\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\begin{itemdecl}
system_error(int ev, const error_category& ecat,
  const char* what_arg);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of class \tcode{system_error}.

\pnum
\postconditions \tcode{code() == error_code(ev, ecat)}.

\tcode{string(what()).find(what_arg) != string::npos}.
\end{itemdescr}

\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\indexlibrary{\idxcode{system_error}!\idxcode{system_error}}
\begin{itemdecl}
system_error(int ev, const error_category& ecat);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects Constructs an object of class \tcode{system_error}.

\pnum
\postconditions \tcode{code() == error_code(ev, ecat)}.
\end{itemdescr}

\indexlibrary{\idxcode{code}!\idxcode{system_error}}
\indexlibrary{\idxcode{system_error}!\idxcode{code}}
\begin{itemdecl}
const error_code& code() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns \tcode{ec} or \tcode{error_code(ev, ecat)}, from the constructor,
as appropriate.
\end{itemdescr}

\indexlibrary{\idxcode{what}!\idxcode{system_error}}
\indexlibrary{\idxcode{system_error}!\idxcode{what}}
\begin{itemdecl}
const char* what() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns An \ntbs incorporating the arguments supplied in the constructor.

\enternote The returned NTBS might be the contents of \tcode{what_arg + ": " +
code.message()}.\exitnote
\end{itemdescr}
