//  ndnboost/system/error_code.hpp  ---------------------------------------------//

//  Copyright Beman Dawes 2006, 2007
//  Copyright Christoper Kohlhoff 2007

//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See library home page at http://www.boost.org/libs/system

#ifndef NDNBOOST_ERROR_CODE_HPP
#define NDNBOOST_ERROR_CODE_HPP

#include <ndnboost/system/config.hpp>
#include <ndnboost/cstdint.hpp>
#include <ndnboost/assert.hpp>
#include <ndnboost/operators.hpp>
#include <ndnboost/noncopyable.hpp>
#include <ndnboost/utility/enable_if.hpp>
#include <ostream>
#include <string>
#include <stdexcept>
#include <functional>

// TODO: undef these macros if not already defined
#include <ndnboost/cerrno.hpp>

#if !defined(NDNBOOST_POSIX_API) && !defined(NDNBOOST_WINDOWS_API)
#  error NDNBOOST_POSIX_API or NDNBOOST_WINDOWS_API must be defined
#endif

#include <ndnboost/config/abi_prefix.hpp> // must be the last #include

#ifndef NDNBOOST_SYSTEM_NOEXCEPT
#define NDNBOOST_SYSTEM_NOEXCEPT NDNBOOST_NOEXCEPT
#endif

namespace ndnboost
{
  namespace system
  {

    class error_code;
    class error_condition;

    //  "Concept" helpers  ---------------------------------------------------//

    template< class T >
    struct is_error_code_enum { static const bool value = false; };

    template< class T >
    struct is_error_condition_enum { static const bool value = false; };

    //  generic error_conditions  --------------------------------------------//

    namespace errc
    {
      enum errc_t
      {
        success = 0,
        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
      };

    } // namespace errc

# ifndef NDNBOOST_SYSTEM_NO_DEPRECATED
    namespace posix = errc;
    namespace posix_error = errc;
# endif

    template<> struct is_error_condition_enum<errc::errc_t>
      { static const bool value = true; };


    //  ----------------------------------------------------------------------//

    //  Operating system specific interfaces  --------------------------------//


    //  The interface is divided into general and system-specific portions to
    //  meet these requirements:
    //
    //  * Code calling an operating system API can create an error_code with
    //    a single category (system_category), even for POSIX-like operating
    //    systems that return some POSIX errno values and some native errno
    //    values. This code should not have to pay the cost of distinguishing
    //    between categories, since it is not yet known if that is needed.
    //
    //  * Users wishing to write system-specific code should be given enums for
    //    at least the common error cases.
    //
    //  * System specific code should fail at compile time if moved to another
    //    operating system.

    //  The system specific portions of the interface are located in headers
    //  with names reflecting the operating system. For example,
    //
    //       <ndnboost/system/cygwin_error.hpp>
    //       <ndnboost/system/linux_error.hpp>
    //       <ndnboost/system/windows_error.hpp>
    //
    //  These headers are effectively empty for compiles on operating systems
    //  where they are not applicable.

    //  ----------------------------------------------------------------------//

    //  class error_category  ------------------------------------------------//

    class error_category : public noncopyable
    {
    public:
      virtual ~error_category(){}

      virtual const char *     name() const NDNBOOST_SYSTEM_NOEXCEPT = 0;
      virtual std::string      message( int ev ) const = 0;
      inline virtual error_condition  default_error_condition( int ev ) const  NDNBOOST_SYSTEM_NOEXCEPT;
      inline virtual bool             equivalent( int code,
                                           const error_condition & condition ) const  NDNBOOST_SYSTEM_NOEXCEPT;
      inline virtual bool             equivalent( const error_code & code,
                                           int condition ) const  NDNBOOST_SYSTEM_NOEXCEPT;

      bool operator==(const error_category & rhs) const NDNBOOST_SYSTEM_NOEXCEPT { return this == &rhs; }
      bool operator!=(const error_category & rhs) const NDNBOOST_SYSTEM_NOEXCEPT { return this != &rhs; }
      bool operator<( const error_category & rhs ) const NDNBOOST_SYSTEM_NOEXCEPT
      {
        return std::less<const error_category*>()( this, &rhs );
      }
    };

    //  predefined error categories  -----------------------------------------//

# ifdef NDNBOOST_ERROR_CODE_HEADER_ONLY
    inline const error_category &  system_category() NDNBOOST_SYSTEM_NOEXCEPT;
    inline const error_category &  generic_category() NDNBOOST_SYSTEM_NOEXCEPT;
#else
    NDNBOOST_SYSTEM_DECL const error_category &  system_category() NDNBOOST_SYSTEM_NOEXCEPT;
    NDNBOOST_SYSTEM_DECL const error_category &  generic_category() NDNBOOST_SYSTEM_NOEXCEPT;
#endif
    //  deprecated synonyms --------------------------------------------------//

# ifndef NDNBOOST_SYSTEM_NO_DEPRECATED
    inline const error_category &  get_system_category() { return system_category(); }
    inline const error_category &  get_generic_category() { return generic_category(); }
    inline const error_category &  get_posix_category() { return generic_category(); }
    static const error_category &  posix_category = generic_category();
    static const error_category &  errno_ecat     = generic_category();
    static const error_category &  native_ecat    = system_category();
# endif

    //  class error_condition  -----------------------------------------------//

    //  error_conditions are portable, error_codes are system or library specific

    class error_condition
    {
    public:

      // constructors:
      error_condition() NDNBOOST_SYSTEM_NOEXCEPT : m_val(0), m_cat(&generic_category()) {}
      error_condition( int val, const error_category & cat ) NDNBOOST_SYSTEM_NOEXCEPT : m_val(val), m_cat(&cat) {}

      template <class ErrorConditionEnum>
        error_condition(ErrorConditionEnum e,
          typename ndnboost::enable_if<is_error_condition_enum<ErrorConditionEnum> >::type* = 0) NDNBOOST_SYSTEM_NOEXCEPT
      {
        *this = make_error_condition(e);
      }

      // modifiers:

      void assign( int val, const error_category & cat ) NDNBOOST_SYSTEM_NOEXCEPT
      {
        m_val = val;
        m_cat = &cat;
      }

      template<typename ErrorConditionEnum>
        typename ndnboost::enable_if<is_error_condition_enum<ErrorConditionEnum>, error_condition>::type &
          operator=( ErrorConditionEnum val ) NDNBOOST_SYSTEM_NOEXCEPT
      {
        *this = make_error_condition(val);
        return *this;
      }

      void clear() NDNBOOST_SYSTEM_NOEXCEPT
      {
        m_val = 0;
        m_cat = &generic_category();
      }

      // observers:
      int                     value() const NDNBOOST_SYSTEM_NOEXCEPT    { return m_val; }
      const error_category &  category() const NDNBOOST_SYSTEM_NOEXCEPT { return *m_cat; }
      std::string             message() const  { return m_cat->message(value()); }

      typedef void (*unspecified_bool_type)();
      static void unspecified_bool_true() {}

      operator unspecified_bool_type() const NDNBOOST_SYSTEM_NOEXCEPT  // true if error
      {
        return m_val == 0 ? 0 : unspecified_bool_true;
      }

      bool operator!() const NDNBOOST_SYSTEM_NOEXCEPT  // true if no error
      {
        return m_val == 0;
      }

      // relationals:
      //  the more symmetrical non-member syntax allows enum
      //  conversions work for both rhs and lhs.
      inline friend bool operator==( const error_condition & lhs,
                                     const error_condition & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
      {
        return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;
      }

      inline friend bool operator<( const error_condition & lhs,
                                    const error_condition & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
        //  the more symmetrical non-member syntax allows enum
        //  conversions work for both rhs and lhs.
      {
        return lhs.m_cat < rhs.m_cat
          || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
      }

    private:
      int                     m_val;
      const error_category *  m_cat;

    };

    //  class error_code  ----------------------------------------------------//

    //  We want error_code to be a value type that can be copied without slicing
    //  and without requiring heap allocation, but we also want it to have
    //  polymorphic behavior based on the error category. This is achieved by
    //  abstract base class error_category supplying the polymorphic behavior,
    //  and error_code containing a pointer to an object of a type derived
    //  from error_category.
    class error_code
    {
    public:

      // constructors:
      error_code() NDNBOOST_SYSTEM_NOEXCEPT : m_val(0), m_cat(&system_category()) {}
      error_code( int val, const error_category & cat ) NDNBOOST_SYSTEM_NOEXCEPT : m_val(val), m_cat(&cat) {}

      template <class ErrorCodeEnum>
        error_code(ErrorCodeEnum e,
          typename ndnboost::enable_if<is_error_code_enum<ErrorCodeEnum> >::type* = 0) NDNBOOST_SYSTEM_NOEXCEPT
      {
        *this = make_error_code(e);
      }

      // modifiers:
      void assign( int val, const error_category & cat ) NDNBOOST_SYSTEM_NOEXCEPT
      {
        m_val = val;
        m_cat = &cat;
      }

      template<typename ErrorCodeEnum>
        typename ndnboost::enable_if<is_error_code_enum<ErrorCodeEnum>, error_code>::type &
          operator=( ErrorCodeEnum val ) NDNBOOST_SYSTEM_NOEXCEPT
      {
        *this = make_error_code(val);
        return *this;
      }

      void clear() NDNBOOST_SYSTEM_NOEXCEPT
      {
        m_val = 0;
        m_cat = &system_category();
      }

      // observers:
      int                     value() const  NDNBOOST_SYSTEM_NOEXCEPT   { return m_val; }
      const error_category &  category() const NDNBOOST_SYSTEM_NOEXCEPT { return *m_cat; }
      error_condition         default_error_condition() const NDNBOOST_SYSTEM_NOEXCEPT  { return m_cat->default_error_condition(value()); }
      std::string             message() const  { return m_cat->message(value()); }

      typedef void (*unspecified_bool_type)();
      static void unspecified_bool_true() {}

      operator unspecified_bool_type() const  NDNBOOST_SYSTEM_NOEXCEPT // true if error
      {
        return m_val == 0 ? 0 : unspecified_bool_true;
      }

      bool operator!() const  NDNBOOST_SYSTEM_NOEXCEPT // true if no error
      {
        return m_val == 0;
      }

      // relationals:
      inline friend bool operator==( const error_code & lhs,
                                     const error_code & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
        //  the more symmetrical non-member syntax allows enum
        //  conversions work for both rhs and lhs.
      {
        return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;
      }

      inline friend bool operator<( const error_code & lhs,
                                    const error_code & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
        //  the more symmetrical non-member syntax allows enum
        //  conversions work for both rhs and lhs.
      {
        return lhs.m_cat < rhs.m_cat
          || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
      }

    private:
      int                     m_val;
      const error_category *  m_cat;

    };

    //  predefined error_code object used as "throw on error" tag
# ifndef NDNBOOST_SYSTEM_NO_DEPRECATED
    NDNBOOST_SYSTEM_DECL extern error_code throws;
# endif

    //  Moving from a "throws" object to a "throws" function without breaking
    //  existing code is a bit of a problem. The workaround is to place the
    //  "throws" function in namespace ndnboost rather than namespace ndnboost::system.

  }  // namespace system

  namespace detail { inline system::error_code * throws() { return 0; } }
    //  Misuse of the error_code object is turned into a noisy failure by
    //  poisoning the reference. This particular implementation doesn't
    //  produce warnings or errors from popular compilers, is very efficient
    //  (as determined by inspecting generated code), and does not suffer
    //  from order of initialization problems. In practice, it also seems
    //  cause user function error handling implementation errors to be detected
    //  very early in the development cycle.

  inline system::error_code & throws()
    { return *detail::throws(); }

  namespace system
  {
    //  non-member functions  ------------------------------------------------//

    inline bool operator!=( const error_code & lhs,
                            const error_code & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
    {
      return !(lhs == rhs);
    }

    inline bool operator!=( const error_condition & lhs,
                            const error_condition & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
    {
      return !(lhs == rhs);
    }

    inline bool operator==( const error_code & code,
                            const error_condition & condition ) NDNBOOST_SYSTEM_NOEXCEPT
    {
      return code.category().equivalent( code.value(), condition )
        || condition.category().equivalent( code, condition.value() );
    }

    inline bool operator!=( const error_code & lhs,
                            const error_condition & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
    {
      return !(lhs == rhs);
    }

    inline bool operator==( const error_condition & condition,
                            const error_code & code ) NDNBOOST_SYSTEM_NOEXCEPT
    {
      return condition.category().equivalent( code, condition.value() )
        || code.category().equivalent( code.value(), condition );
    }

    inline bool operator!=( const error_condition & lhs,
                            const error_code & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
    {
      return !(lhs == rhs);
    }

    // TODO: both of these may move elsewhere, but the LWG hasn't spoken yet.

    template <class charT, class traits>
    inline std::basic_ostream<charT,traits>&
      operator<< (std::basic_ostream<charT,traits>& os, error_code ec)
    {
      os << ec.category().name() << ':' << ec.value();
      return os;
    }

    inline std::size_t hash_value( const error_code & ec )
    {
      return static_cast<std::size_t>(ec.value())
        + reinterpret_cast<std::size_t>(&ec.category());
    }

    //  make_* functions for errc::errc_t  -----------------------------//

    namespace errc
    {
      //  explicit conversion:
      inline error_code make_error_code( errc_t e ) NDNBOOST_SYSTEM_NOEXCEPT
        { return error_code( e, generic_category() ); }

      //  implicit conversion:
      inline error_condition make_error_condition( errc_t e ) NDNBOOST_SYSTEM_NOEXCEPT
        { return error_condition( e, generic_category() ); }
    }

    //  error_category default implementation  -------------------------------//

    error_condition error_category::default_error_condition( int ev ) const NDNBOOST_SYSTEM_NOEXCEPT
    {
      return error_condition( ev, *this );
    }

    bool error_category::equivalent( int code,
      const error_condition & condition ) const NDNBOOST_SYSTEM_NOEXCEPT
    {
      return default_error_condition( code ) == condition;
    }

    bool error_category::equivalent( const error_code & code,
      int condition ) const NDNBOOST_SYSTEM_NOEXCEPT
    {
      return *this == code.category() && code.value() == condition;
    }

  } // namespace system
} // namespace ndnboost

#include <ndnboost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas

# ifdef NDNBOOST_ERROR_CODE_HEADER_ONLY
#   include <ndnboost/../libs/system/src/error_code.cpp>
# endif

#endif // NDNBOOST_ERROR_CODE_HPP


