Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / outcome / experimental / status-code / generic_code.hpp
index e97b358..fe35511 100644 (file)
@@ -1,31 +1,25 @@
 /* Proposed SG14 status_code
-(C) 2018-2019 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
+(C) 2018 - 2019 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
 File Created: Feb 2018
 
 
-Boost Software License - Version 1.0 - August 17th, 2003
+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 in the accompanying file
+Licence.txt or at
 
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
+http://www.apache.org/licenses/LICENSE-2.0
 
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
+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.
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
+
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file Licence.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
 */
 
 #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_GENERIC_CODE_HPP
@@ -124,102 +118,178 @@ enum class errc : int
 
 namespace detail
 {
-  struct generic_code_messages
+  BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline const char *generic_code_message(errc code) noexcept
   {
-    // libc++ defines missing errc macros to integers in the 9xxx range
-    // As much as 10,000 seems wasteful, bear in mind this is all constexpr
-    // and on C++ 14 or later this entire construct disappears.
-    const char *msgs[(ETIME >= 256) ? 10000 : 256];
-    BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 size_t size() const { return sizeof(msgs) / sizeof(*msgs); }  // NOLINT
-    BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 const char *operator[](int i) const { return (i < 0 || i >= static_cast<int>(size()) || nullptr == msgs[i]) ? "unknown" : msgs[i]; }  // NOLINT
-    BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 generic_code_messages()
-        : msgs{}
+    switch(code)
     {
-      msgs[0] = "Success";
-
-      msgs[EAFNOSUPPORT] = "Address family not supported by protocol";
-      msgs[EADDRINUSE] = "Address already in use";
-      msgs[EADDRNOTAVAIL] = "Cannot assign requested address";
-      msgs[EISCONN] = "Transport endpoint is already connected";
-      msgs[E2BIG] = "Argument list too long";
-      msgs[EDOM] = "Numerical argument out of domain";
-      msgs[EFAULT] = "Bad address";
-      msgs[EBADF] = "Bad file descriptor";
-      msgs[EBADMSG] = "Bad message";
-      msgs[EPIPE] = "Broken pipe";
-      msgs[ECONNABORTED] = "Software caused connection abort";
-      msgs[EALREADY] = "Operation already in progress";
-      msgs[ECONNREFUSED] = "Connection refused";
-      msgs[ECONNRESET] = "Connection reset by peer";
-      msgs[EXDEV] = "Invalid cross-device link";
-      msgs[EDESTADDRREQ] = "Destination address required";
-      msgs[EBUSY] = "Device or resource busy";
-      msgs[ENOTEMPTY] = "Directory not empty";
-      msgs[ENOEXEC] = "Exec format error";
-      msgs[EEXIST] = "File exists";
-      msgs[EFBIG] = "File too large";
-      msgs[ENAMETOOLONG] = "File name too long";
-      msgs[ENOSYS] = "Function not implemented";
-      msgs[EHOSTUNREACH] = "No route to host";
-      msgs[EIDRM] = "Identifier removed";
-      msgs[EILSEQ] = "Invalid or incomplete multibyte or wide character";
-      msgs[ENOTTY] = "Inappropriate ioctl for device";
-      msgs[EINTR] = "Interrupted system call";
-      msgs[EINVAL] = "Invalid argument";
-      msgs[ESPIPE] = "Illegal seek";
-      msgs[EIO] = "Input/output error";
-      msgs[EISDIR] = "Is a directory";
-      msgs[EMSGSIZE] = "Message too long";
-      msgs[ENETDOWN] = "Network is down";
-      msgs[ENETRESET] = "Network dropped connection on reset";
-      msgs[ENETUNREACH] = "Network is unreachable";
-      msgs[ENOBUFS] = "No buffer space available";
-      msgs[ECHILD] = "No child processes";
-      msgs[ENOLINK] = "Link has been severed";
-      msgs[ENOLCK] = "No locks available";
-      msgs[ENOMSG] = "No message of desired type";
-      msgs[ENOPROTOOPT] = "Protocol not available";
-      msgs[ENOSPC] = "No space left on device";
-      msgs[ENOSR] = "Out of streams resources";
-      msgs[ENXIO] = "No such device or address";
-      msgs[ENODEV] = "No such device";
-      msgs[ENOENT] = "No such file or directory";
-      msgs[ESRCH] = "No such process";
-      msgs[ENOTDIR] = "Not a directory";
-      msgs[ENOTSOCK] = "Socket operation on non-socket";
-      msgs[ENOSTR] = "Device not a stream";
-      msgs[ENOTCONN] = "Transport endpoint is not connected";
-      msgs[ENOMEM] = "Cannot allocate memory";
-      msgs[ENOTSUP] = "Operation not supported";
-      msgs[ECANCELED] = "Operation canceled";
-      msgs[EINPROGRESS] = "Operation now in progress";
-      msgs[EPERM] = "Operation not permitted";
-      msgs[EOPNOTSUPP] = "Operation not supported";
-      msgs[EWOULDBLOCK] = "Resource temporarily unavailable";
-      msgs[EOWNERDEAD] = "Owner died";
-      msgs[EACCES] = "Permission denied";
-      msgs[EPROTO] = "Protocol error";
-      msgs[EPROTONOSUPPORT] = "Protocol not supported";
-      msgs[EROFS] = "Read-only file system";
-      msgs[EDEADLK] = "Resource deadlock avoided";
-      msgs[EAGAIN] = "Resource temporarily unavailable";
-      msgs[ERANGE] = "Numerical result out of range";
-      msgs[ENOTRECOVERABLE] = "State not recoverable";
-      msgs[ETIME] = "Timer expired";
-      msgs[ETXTBSY] = "Text file busy";
-      msgs[ETIMEDOUT] = "Connection timed out";
-      msgs[ENFILE] = "Too many open files in system";
-      msgs[EMFILE] = "Too many open files";
-      msgs[EMLINK] = "Too many links";
-      msgs[ELOOP] = "Too many levels of symbolic links";
-      msgs[EOVERFLOW] = "Value too large for defined data type";
-      msgs[EPROTOTYPE] = "Protocol wrong type for socket";
+    case errc::success:
+      return "Success";
+    case errc::address_family_not_supported:
+      return "Address family not supported by protocol";
+    case errc::address_in_use:
+      return "Address already in use";
+    case errc::address_not_available:
+      return "Cannot assign requested address";
+    case errc::already_connected:
+      return "Transport endpoint is already connected";
+    case errc::argument_list_too_long:
+      return "Argument list too long";
+    case errc::argument_out_of_domain:
+      return "Numerical argument out of domain";
+    case errc::bad_address:
+      return "Bad address";
+    case errc::bad_file_descriptor:
+      return "Bad file descriptor";
+    case errc::bad_message:
+      return "Bad message";
+    case errc::broken_pipe:
+      return "Broken pipe";
+    case errc::connection_aborted:
+      return "Software caused connection abort";
+    case errc::connection_already_in_progress:
+      return "Operation already in progress";
+    case errc::connection_refused:
+      return "Connection refused";
+    case errc::connection_reset:
+      return "Connection reset by peer";
+    case errc::cross_device_link:
+      return "Invalid cross-device link";
+    case errc::destination_address_required:
+      return "Destination address required";
+    case errc::device_or_resource_busy:
+      return "Device or resource busy";
+    case errc::directory_not_empty:
+      return "Directory not empty";
+    case errc::executable_format_error:
+      return "Exec format error";
+    case errc::file_exists:
+      return "File exists";
+    case errc::file_too_large:
+      return "File too large";
+    case errc::filename_too_long:
+      return "File name too long";
+    case errc::function_not_supported:
+      return "Function not implemented";
+    case errc::host_unreachable:
+      return "No route to host";
+    case errc::identifier_removed:
+      return "Identifier removed";
+    case errc::illegal_byte_sequence:
+      return "Invalid or incomplete multibyte or wide character";
+    case errc::inappropriate_io_control_operation:
+      return "Inappropriate ioctl for device";
+    case errc::interrupted:
+      return "Interrupted system call";
+    case errc::invalid_argument:
+      return "Invalid argument";
+    case errc::invalid_seek:
+      return "Illegal seek";
+    case errc::io_error:
+      return "Input/output error";
+    case errc::is_a_directory:
+      return "Is a directory";
+    case errc::message_size:
+      return "Message too long";
+    case errc::network_down:
+      return "Network is down";
+    case errc::network_reset:
+      return "Network dropped connection on reset";
+    case errc::network_unreachable:
+      return "Network is unreachable";
+    case errc::no_buffer_space:
+      return "No buffer space available";
+    case errc::no_child_process:
+      return "No child processes";
+    case errc::no_link:
+      return "Link has been severed";
+    case errc::no_lock_available:
+      return "No locks available";
+    case errc::no_message:
+      return "No message of desired type";
+    case errc::no_protocol_option:
+      return "Protocol not available";
+    case errc::no_space_on_device:
+      return "No space left on device";
+    case errc::no_stream_resources:
+      return "Out of streams resources";
+    case errc::no_such_device_or_address:
+      return "No such device or address";
+    case errc::no_such_device:
+      return "No such device";
+    case errc::no_such_file_or_directory:
+      return "No such file or directory";
+    case errc::no_such_process:
+      return "No such process";
+    case errc::not_a_directory:
+      return "Not a directory";
+    case errc::not_a_socket:
+      return "Socket operation on non-socket";
+    case errc::not_a_stream:
+      return "Device not a stream";
+    case errc::not_connected:
+      return "Transport endpoint is not connected";
+    case errc::not_enough_memory:
+      return "Cannot allocate memory";
+#if ENOTSUP != EOPNOTSUPP
+    case errc::not_supported:
+      return "Operation not supported";
+#endif
+    case errc::operation_canceled:
+      return "Operation canceled";
+    case errc::operation_in_progress:
+      return "Operation now in progress";
+    case errc::operation_not_permitted:
+      return "Operation not permitted";
+    case errc::operation_not_supported:
+      return "Operation not supported";
+#if EAGAIN != EWOULDBLOCK
+    case errc::operation_would_block:
+      return "Resource temporarily unavailable";
+#endif
+    case errc::owner_dead:
+      return "Owner died";
+    case errc::permission_denied:
+      return "Permission denied";
+    case errc::protcol_error:
+      return "Protocol error";
+    case errc::protocol_not_supported:
+      return "Protocol not supported";
+    case errc::read_only_file_system:
+      return "Read-only file system";
+    case errc::resource_deadlock_would_occur:
+      return "Resource deadlock avoided";
+    case errc::resource_unavailable_try_again:
+      return "Resource temporarily unavailable";
+    case errc::result_out_of_range:
+      return "Numerical result out of range";
+    case errc::state_not_recoverable:
+      return "State not recoverable";
+    case errc::stream_timeout:
+      return "Timer expired";
+    case errc::text_file_busy:
+      return "Text file busy";
+    case errc::timed_out:
+      return "Connection timed out";
+    case errc::too_many_files_open_in_system:
+      return "Too many open files in system";
+    case errc::too_many_files_open:
+      return "Too many open files";
+    case errc::too_many_links:
+      return "Too many links";
+    case errc::too_many_symbolic_link_levels:
+      return "Too many levels of symbolic links";
+    case errc::value_too_large:
+      return "Value too large for defined data type";
+    case errc::wrong_protocol_type:
+      return "Protocol wrong type for socket";
+    default:
+      return "unknown";
     }
-  };
+  }
 }  // namespace detail
 
 /*! The implementation of the domain for generic status codes, those mapped by `errc` (POSIX).
-*/
+ */
 class _generic_code_domain : public status_code_domain
 {
   template <class> friend class status_code;
@@ -247,12 +317,12 @@ public:
 protected:
   virtual bool _do_failure(const status_code<void> &code) const noexcept override  // NOLINT
   {
-    assert(code.domain() == *this);  // NOLINT
+    assert(code.domain() == *this);                                           // NOLINT
     return static_cast<const generic_code &>(code).value() != errc::success;  // NOLINT
   }
   virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override  // NOLINT
   {
-    assert(code1.domain() == *this);  // NOLINT
+    assert(code1.domain() == *this);                            // NOLINT
     const auto &c1 = static_cast<const generic_code &>(code1);  // NOLINT
     if(code2.domain() == *this)
     {
@@ -263,20 +333,19 @@ protected:
   }
   virtual generic_code _generic_code(const status_code<void> &code) const noexcept override  // NOLINT
   {
-    assert(code.domain() == *this);  // NOLINT
+    assert(code.domain() == *this);                  // NOLINT
     return static_cast<const generic_code &>(code);  // NOLINT
   }
   virtual _base::string_ref _do_message(const status_code<void> &code) const noexcept override  // NOLINT
   {
-    assert(code.domain() == *this);  // NOLINT
+    assert(code.domain() == *this);                           // NOLINT
     const auto &c = static_cast<const generic_code &>(code);  // NOLINT
-    static BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 detail::generic_code_messages msgs;
-    return string_ref(msgs[static_cast<int>(c.value())]);
+    return string_ref(detail::generic_code_message(c.value()));
   }
 #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE)
   BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override  // NOLINT
   {
-    assert(code.domain() == *this);  // NOLINT
+    assert(code.domain() == *this);                           // NOLINT
     const auto &c = static_cast<const generic_code &>(code);  // NOLINT
     throw status_error<_generic_code_domain>(c);
   }
@@ -340,8 +409,7 @@ template <class DomainType1, class DomainType2> inline bool operator!=(const sta
 template <class DomainType1, class T,                                                                       //
           class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type,  // Safe ADL lookup of make_status_code(), returns void if not found
           typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true>          // ADL makes a status code
-inline bool
-operator==(const status_code<DomainType1> &a, const T &b)
+inline bool operator==(const status_code<DomainType1> &a, const T &b)
 {
   return a.equivalent(make_status_code(b));
 }
@@ -349,8 +417,7 @@ operator==(const status_code<DomainType1> &a, const T &b)
 template <class T, class DomainType1,                                                                       //
           class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type,  // Safe ADL lookup of make_status_code(), returns void if not found
           typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true>          // ADL makes a status code
-inline bool
-operator==(const T &a, const status_code<DomainType1> &b)
+inline bool operator==(const T &a, const status_code<DomainType1> &b)
 {
   return b.equivalent(make_status_code(a));
 }
@@ -358,8 +425,7 @@ operator==(const T &a, const status_code<DomainType1> &b)
 template <class DomainType1, class T,                                                                       //
           class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type,  // Safe ADL lookup of make_status_code(), returns void if not found
           typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true>          // ADL makes a status code
-inline bool
-operator!=(const status_code<DomainType1> &a, const T &b)
+inline bool operator!=(const status_code<DomainType1> &a, const T &b)
 {
   return !a.equivalent(make_status_code(b));
 }
@@ -367,8 +433,7 @@ operator!=(const status_code<DomainType1> &a, const T &b)
 template <class T, class DomainType1,                                                                       //
           class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type,  // Safe ADL lookup of make_status_code(), returns void if not found
           typename std::enable_if<is_status_code<MakeStatusCodeResult>::value, bool>::type = true>          // ADL makes a status code
-inline bool
-operator!=(const T &a, const status_code<DomainType1> &b)
+inline bool operator!=(const T &a, const status_code<DomainType1> &b)
 {
   return !b.equivalent(make_status_code(a));
 }