// bslstl_errc.h                                                      -*-C++-*-
#ifndef INCLUDED_BSLSTL_ERRC
#define INCLUDED_BSLSTL_ERRC

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

// BDE_VERIFY pragma: -TP25  // CLASSES are not defined in C++11

//@PURPOSE: Provide a standard compliant version of `errc`.
//
//@CLASSES:
//  bsl::errc: namespace for `errc` enumeration type
//  bsl::ErrcEnum: `typedef` for `bsl::errc::Enum` or `std::errc`
//
//@CANONICAL_HEADER: bsl_system_error.h
//
//@DESCRIPTION: This component defines an enumeration `bsl::errc::Enum`, and
// marks it eligible to participate as an error condition in the `system_error`
// facility.  In C++11 mode, the vendor-supplied `<system_error>`
// implementation is used instead, and the corresponding names from `std` are
// imported into `bsl`.
//
// This component also defines the type alias `bsl::ErrcEnum` that can be used
// as the type of the `errc` enumeration in both C++03 and C++11 mode.  Because
// `errc` is defined in C++11 as an `enum class`, we cannot emulate use of
// `std::errc` in C++03 mode - that tag can either be used to qualify the
// enumeration literals or name the type, but not both.  This component chooses
// to have `bsl::errc` be the literal qualifier and `bsl::ErrcEnum` be the type
// so to use this component portably, one would, for example, write
// ```
// bsl::ErrcEnum error_value = bsl::errc::io_error;
// ```
//
///Usage
///-----
// In this section we show intended use of this component.
//
///Example 1: Descriptive System Error Value Names
///- - - - - - - - - - - - - - - - - - - - - - - -
// Suppose we would like to have more descriptive and non-macro names for
// `errno` system error values.  We can use the `errc` from the `system_error`
// facility of the C++ standard for this.
//
// First, we do something that will set an error value.
// ```
// strtod("1e2000", 0);
// ```
// Finally, we check for that error using the descriptive name.
// ```
// bsl::ErrcEnum expected = bsl::errc::result_out_of_range;
// assert(static_cast<int>(expected) == errno);
// ```

#include <bslscm_version.h>

#include <bslstl_iserrorconditionenum.h>

#include <bslmf_integralconstant.h>

#include <bsls_libraryfeatures.h>

#include <errno.h>

#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
#include <bsls_nativestd.h>
#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY

#include <system_error>

namespace bsl {
using std::errc;

typedef std::errc ErrcEnum;  // Portable typedef for 'errc'
}  // close namespace bsl

#else

namespace bsl {

                               // =============
                               // struct 'errc'
                               // =============

/// This `struct` defines an enumeration type that provides named literals
/// for the `errno` values defined in the `<cerrno>` header.  Note that in
/// the C++11 standard, `std::errc` is defined as an `enum class`, so that
/// literals can be qualified with `std::errc::` and objects of the type can
/// be declared as `std::errc`.  In C++03 mode, we cannot have both, and we
/// have chosen in favor of allowing the literals to be qualified, so
/// objects of the type must be declared as `bsl::errc::Enum`.  For
/// portability between modes, declare objects of the enumeration type as
/// `bsl::ErrcEnum`.
struct errc {

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

typedef errc::Enum ErrcEnum;  // Portable typedef for 'errc'

                       // ------------------------------
                       // struct is_error_condition_enum
                       // ------------------------------

/// Mark the `errc` enumeration as an error condition.
template <>
struct is_error_condition_enum<errc::Enum> : public bsl::true_type {
};

}  // close namespace bsl

#endif
#endif

// ----------------------------------------------------------------------------
// Copyright 2019 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
