Silicium
error_code.hpp
Go to the documentation of this file.
1 #ifndef SILICIUM_ERROR_CODE_HPP
2 #define SILICIUM_ERROR_CODE_HPP
3 
4 #include <silicium/config.hpp>
5 #include <boost/system/error_code.hpp>
6 #include <boost/throw_exception.hpp>
7 #include <boost/static_assert.hpp>
8 
9 namespace Si
10 {
11  template <class UnderlyingErrorCode = boost::system::error_code, class UnderlyingCategory = boost::system::error_category>
12  struct error_code
13  {
14  error_code() BOOST_NOEXCEPT
15  : underlying(nullptr)
16  {
17  }
18 
19  template <int Value, UnderlyingCategory const &(*Category)()>
20  static error_code create()
21  {
22  static UnderlyingErrorCode const instance(Value, Category());
23  return error_code(instance);
24  }
25 
26  UnderlyingErrorCode to_underlying() const
27  {
28  if (underlying)
29  {
30  return *underlying;
31  }
32  return UnderlyingErrorCode();
33  }
34 
35  void clear() BOOST_NOEXCEPT
36  {
37  underlying = nullptr;
38  }
39 
40  int value() const BOOST_NOEXCEPT
41  {
42  return to_underlying().value();
43  }
44 
45  UnderlyingCategory const &category() const BOOST_NOEXCEPT
46  {
47  return to_underlying().category();
48  }
49 
50  private:
51 
52  UnderlyingErrorCode const *underlying;
53 
54  explicit error_code(UnderlyingErrorCode const &underlying) BOOST_NOEXCEPT
55  : underlying(&underlying)
56  {
57  }
58  };
59 
60  BOOST_STATIC_ASSERT(sizeof(error_code<>) == sizeof(void *));
61 
62  template <class UnderlyingErrorCode, class UnderlyingCategory>
64  {
65  return left.to_underlying() == right.to_underlying();
66  }
67 
68  template <class UnderlyingErrorCode, class UnderlyingCategory>
70  {
71 #ifndef __GNUC__
72  //GCC warns about a return in a "noreturn" function
73  return
74 #endif
75  throw_error(error.to_underlying());
76  }
77 
78  template <class UnderlyingErrorCode, class UnderlyingCategory>
80  {
81  return std::hash<error_code<UnderlyingErrorCode, UnderlyingCategory>>()(value);
82  }
83 
84  template <class UnderlyingErrorCode, class UnderlyingCategory>
85  std::ostream &operator << (std::ostream &out, error_code<UnderlyingErrorCode, UnderlyingCategory> const &value)
86  {
87  return out << value.to_underlying();
88  }
89 }
90 
91 namespace std
92 {
93  template <class UnderlyingErrorCode, class UnderlyingCategory>
94  struct hash<Si::error_code<UnderlyingErrorCode, UnderlyingCategory>>
95  {
97  {
99  }
100  };
101 }
102 
103 #endif
BOOST_STATIC_ASSERT(Si::is_handle< absolute_path >::value)
SILICIUM_NORETURN void throw_error(error_code< UnderlyingErrorCode, UnderlyingCategory > error)
Definition: error_code.hpp:69
int value() const BOOST_NOEXCEPT
Definition: error_code.hpp:40
error_code() BOOST_NOEXCEPT
Definition: error_code.hpp:14
Definition: absolute_path.hpp:352
Definition: absolute_path.hpp:19
SILICIUM_USE_RESULT bool operator==(absolute_path const &left, ComparableToPath const &right)
Definition: absolute_path.hpp:169
Definition: error_code.hpp:12
static error_code create()
Definition: error_code.hpp:20
std::size_t operator()(Si::error_code< UnderlyingErrorCode, UnderlyingCategory > const &value) const
Definition: error_code.hpp:96
std::size_t hash_value(error_code< UnderlyingErrorCode, UnderlyingCategory > const &value)
Definition: error_code.hpp:79
void clear() BOOST_NOEXCEPT
Definition: error_code.hpp:35
UnderlyingCategory const & category() const BOOST_NOEXCEPT
Definition: error_code.hpp:45
#define SILICIUM_NORETURN
Definition: config.hpp:63
UnderlyingErrorCode to_underlying() const
Definition: error_code.hpp:26
SILICIUM_USE_RESULT std::size_t hash_value(absolute_path const &value)
Definition: absolute_path.hpp:220