Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // <system_error> -*- C++ -*-
  2.  
  3. // Copyright (C) 2007-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file include/system_error
  26.  *  This is a Standard C++ Library header.
  27.  */
  28.  
  29. #ifndef _GLIBCXX_SYSTEM_ERROR
  30. #define _GLIBCXX_SYSTEM_ERROR 1
  31.  
  32. #pragma GCC system_header
  33.  
  34. #if __cplusplus < 201103L
  35. # include <bits/c++0x_warning.h>
  36. #else
  37.  
  38. #include <bits/c++config.h>
  39. #include <bits/error_constants.h>
  40. #include <iosfwd>
  41. #include <stdexcept>
  42.  
  43. namespace std _GLIBCXX_VISIBILITY(default)
  44. {
  45. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  46.  
  47.   class error_code;
  48.   class error_condition;
  49.   class system_error;
  50.  
  51.   /// is_error_code_enum
  52.   template<typename _Tp>
  53.     struct is_error_code_enum : public false_type { };
  54.  
  55.   /// is_error_condition_enum
  56.   template<typename _Tp>
  57.     struct is_error_condition_enum : public false_type { };
  58.  
  59.   template<>
  60.     struct is_error_condition_enum<errc>
  61.     : public true_type { };
  62.  
  63.   inline namespace _V2 {
  64.  
  65.   /// error_category
  66.   class error_category
  67.   {
  68.   public:
  69.     constexpr error_category() noexcept = default;
  70.  
  71.     virtual ~error_category();
  72.  
  73.     error_category(const error_category&) = delete;
  74.     error_category& operator=(const error_category&) = delete;
  75.  
  76.     virtual const char*
  77.     name() const noexcept = 0;
  78.  
  79.     // We need two different virtual functions here, one returning a
  80.     // COW string and one returning an SSO string. Their positions in the
  81.     // vtable must be consistent for dynamic dispatch to work, but which one
  82.     // the name "message()" finds depends on which ABI the caller is using.
  83. #if _GLIBCXX_USE_CXX11_ABI
  84.   private:
  85.     _GLIBCXX_DEFAULT_ABI_TAG
  86.     virtual __cow_string
  87.     _M_message(int) const;
  88.  
  89.   public:
  90.     _GLIBCXX_DEFAULT_ABI_TAG
  91.     virtual string
  92.     message(int) const = 0;
  93. #else
  94.     virtual string
  95.     message(int) const = 0;
  96.  
  97.   private:
  98.     virtual __sso_string
  99.     _M_message(int) const;
  100. #endif
  101.  
  102.   public:
  103.     virtual error_condition
  104.     default_error_condition(int __i) const noexcept;
  105.  
  106.     virtual bool
  107.     equivalent(int __i, const error_condition& __cond) const noexcept;
  108.  
  109.     virtual bool
  110.     equivalent(const error_code& __code, int __i) const noexcept;
  111.  
  112.     bool
  113.     operator<(const error_category& __other) const noexcept
  114.     { return less<const error_category*>()(this, &__other); }
  115.  
  116.     bool
  117.     operator==(const error_category& __other) const noexcept
  118.     { return this == &__other; }
  119.  
  120.     bool
  121.     operator!=(const error_category& __other) const noexcept
  122.     { return this != &__other; }
  123.   };
  124.  
  125.   // DR 890.
  126.   _GLIBCXX_CONST const error_category& system_category() noexcept;
  127.   _GLIBCXX_CONST const error_category& generic_category() noexcept;
  128.  
  129.   } // end inline namespace
  130.  
  131.   error_code make_error_code(errc) noexcept;
  132.  
  133.   template<typename _Tp>
  134.     struct hash;
  135.  
  136.   /// error_code
  137.   // Implementation-specific error identification
  138.   struct error_code
  139.   {
  140.     error_code() noexcept
  141.     : _M_value(0), _M_cat(&system_category()) { }
  142.  
  143.     error_code(int __v, const error_category& __cat) noexcept
  144.     : _M_value(__v), _M_cat(&__cat) { }
  145.  
  146.     template<typename _ErrorCodeEnum, typename = typename
  147.              enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type>
  148.       error_code(_ErrorCodeEnum __e) noexcept
  149.       { *this = make_error_code(__e); }
  150.  
  151.     void
  152.     assign(int __v, const error_category& __cat) noexcept
  153.     {
  154.       _M_value = __v;
  155.       _M_cat = &__cat;
  156.     }
  157.  
  158.     void
  159.     clear() noexcept
  160.     { assign(0, system_category()); }
  161.  
  162.     // DR 804.
  163.     template<typename _ErrorCodeEnum>
  164.       typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
  165.                          error_code&>::type
  166.       operator=(_ErrorCodeEnum __e) noexcept
  167.       { return *this = make_error_code(__e); }
  168.  
  169.     int
  170.     value() const noexcept { return _M_value; }
  171.      
  172.     const error_category&  
  173.     category() const noexcept { return *_M_cat; }
  174.  
  175.     error_condition
  176.     default_error_condition() const noexcept;
  177.  
  178.     _GLIBCXX_DEFAULT_ABI_TAG
  179.     string
  180.     message() const
  181.     { return category().message(value()); }
  182.  
  183.     explicit operator bool() const noexcept
  184.     { return _M_value != 0 ? true : false; }
  185.  
  186.     // DR 804.
  187.   private:
  188.     friend class hash<error_code>;
  189.  
  190.     int                         _M_value;
  191.     const error_category*       _M_cat;
  192.   };
  193.  
  194.   // 19.4.2.6 non-member functions
  195.   inline error_code
  196.   make_error_code(errc __e) noexcept
  197.   { return error_code(static_cast<int>(__e), generic_category()); }
  198.  
  199.   inline bool
  200.   operator<(const error_code& __lhs, const error_code& __rhs) noexcept
  201.   {
  202.     return (__lhs.category() < __rhs.category()
  203.             || (__lhs.category() == __rhs.category()
  204.                 && __lhs.value() < __rhs.value()));
  205.   }
  206.  
  207.   template<typename _CharT, typename _Traits>
  208.     basic_ostream<_CharT, _Traits>&
  209.     operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
  210.     { return (__os << __e.category().name() << ':' << __e.value()); }
  211.  
  212.   error_condition make_error_condition(errc) noexcept;
  213.  
  214.   /// error_condition
  215.   // Portable error identification
  216.   struct error_condition
  217.   {
  218.     error_condition() noexcept
  219.     : _M_value(0), _M_cat(&generic_category()) { }
  220.  
  221.     error_condition(int __v, const error_category& __cat) noexcept
  222.     : _M_value(__v), _M_cat(&__cat) { }
  223.  
  224.     template<typename _ErrorConditionEnum, typename = typename
  225.          enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type>
  226.       error_condition(_ErrorConditionEnum __e) noexcept
  227.       { *this = make_error_condition(__e); }
  228.  
  229.     void
  230.     assign(int __v, const error_category& __cat) noexcept
  231.     {
  232.       _M_value = __v;
  233.       _M_cat = &__cat;
  234.     }
  235.  
  236.     // DR 804.
  237.     template<typename _ErrorConditionEnum>
  238.       typename enable_if<is_error_condition_enum
  239.                          <_ErrorConditionEnum>::value, error_condition&>::type
  240.       operator=(_ErrorConditionEnum __e) noexcept
  241.       { return *this = make_error_condition(__e); }
  242.  
  243.     void
  244.     clear() noexcept
  245.     { assign(0, generic_category()); }
  246.  
  247.     // 19.4.3.4 observers
  248.     int
  249.     value() const noexcept { return _M_value; }
  250.  
  251.     const error_category&
  252.     category() const noexcept { return *_M_cat; }
  253.  
  254.     _GLIBCXX_DEFAULT_ABI_TAG
  255.     string
  256.     message() const
  257.     { return category().message(value()); }
  258.  
  259.     explicit operator bool() const noexcept
  260.     { return _M_value != 0 ? true : false; }
  261.  
  262.     // DR 804.
  263.   private:
  264.     int                         _M_value;
  265.     const error_category*       _M_cat;
  266.   };
  267.  
  268.   // 19.4.3.6 non-member functions
  269.   inline error_condition
  270.   make_error_condition(errc __e) noexcept
  271.   { return error_condition(static_cast<int>(__e), generic_category()); }
  272.  
  273.   inline bool
  274.   operator<(const error_condition& __lhs,
  275.             const error_condition& __rhs) noexcept
  276.   {
  277.     return (__lhs.category() < __rhs.category()
  278.             || (__lhs.category() == __rhs.category()
  279.                 && __lhs.value() < __rhs.value()));
  280.   }
  281.  
  282.   // 19.4.4 Comparison operators
  283.   inline bool
  284.   operator==(const error_code& __lhs, const error_code& __rhs) noexcept
  285.   { return (__lhs.category() == __rhs.category()
  286.             && __lhs.value() == __rhs.value()); }
  287.  
  288.   inline bool
  289.   operator==(const error_code& __lhs, const error_condition& __rhs) noexcept
  290.   {
  291.     return (__lhs.category().equivalent(__lhs.value(), __rhs)
  292.             || __rhs.category().equivalent(__lhs, __rhs.value()));
  293.   }
  294.  
  295.   inline bool
  296.   operator==(const error_condition& __lhs, const error_code& __rhs) noexcept
  297.   {
  298.     return (__rhs.category().equivalent(__rhs.value(), __lhs)
  299.             || __lhs.category().equivalent(__rhs, __lhs.value()));
  300.   }
  301.  
  302.   inline bool
  303.   operator==(const error_condition& __lhs,
  304.              const error_condition& __rhs) noexcept
  305.   {
  306.     return (__lhs.category() == __rhs.category()
  307.             && __lhs.value() == __rhs.value());
  308.   }
  309.  
  310.   inline bool
  311.   operator!=(const error_code& __lhs, const error_code& __rhs) noexcept
  312.   { return !(__lhs == __rhs); }
  313.  
  314.   inline bool
  315.   operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept
  316.   { return !(__lhs == __rhs); }
  317.  
  318.   inline bool
  319.   operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept
  320.   { return !(__lhs == __rhs); }
  321.  
  322.   inline bool
  323.   operator!=(const error_condition& __lhs,
  324.              const error_condition& __rhs) noexcept
  325.   { return !(__lhs == __rhs); }
  326.  
  327.  
  328.   /**
  329.    *  @brief Thrown to indicate error code of underlying system.
  330.    *
  331.    *  @ingroup exceptions
  332.    */
  333.   class system_error : public std::runtime_error
  334.   {
  335.   private:
  336.     error_code  _M_code;
  337.  
  338.   public:
  339.     system_error(error_code __ec = error_code())
  340.     : runtime_error(__ec.message()), _M_code(__ec) { }
  341.  
  342.     system_error(error_code __ec, const string& __what)
  343.     : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { }
  344.  
  345.     system_error(error_code __ec, const char* __what)
  346.     : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { }
  347.  
  348.     system_error(int __v, const error_category& __ecat, const char* __what)
  349.     : system_error(error_code(__v, __ecat), __what) { }
  350.  
  351.     system_error(int __v, const error_category& __ecat)
  352.     : runtime_error(error_code(__v, __ecat).message()),
  353.       _M_code(__v, __ecat) { }
  354.  
  355.     system_error(int __v, const error_category& __ecat, const string& __what)
  356.     : runtime_error(__what + ": " + error_code(__v, __ecat).message()),
  357.       _M_code(__v, __ecat) { }
  358.  
  359.     virtual ~system_error() noexcept;
  360.  
  361.     const error_code&
  362.     code() const noexcept { return _M_code; }
  363.   };
  364.  
  365. _GLIBCXX_END_NAMESPACE_VERSION
  366. } // namespace
  367.  
  368. #ifndef _GLIBCXX_COMPATIBILITY_CXX0X
  369.  
  370. #include <bits/functional_hash.h>
  371.  
  372. namespace std _GLIBCXX_VISIBILITY(default)
  373. {
  374. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  375.  
  376.   // DR 1182.
  377.   /// std::hash specialization for error_code.
  378.   template<>
  379.     struct hash<error_code>
  380.     : public __hash_base<size_t, error_code>
  381.     {
  382.       size_t
  383.       operator()(const error_code& __e) const noexcept
  384.       {
  385.         const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
  386.         return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
  387.       }
  388.     };
  389.  
  390. _GLIBCXX_END_NAMESPACE_VERSION
  391. } // namespace
  392.  
  393. #endif // _GLIBCXX_COMPATIBILITY_CXX0X
  394.  
  395. #endif // C++11
  396.  
  397. #endif // _GLIBCXX_SYSTEM_ERROR
  398.