pstore2
error.hpp
Go to the documentation of this file.
1 //===- include/pstore/support/error.hpp -------------------*- mode: C++ -*-===//
2 //* *
3 //* ___ _ __ _ __ ___ _ __ *
4 //* / _ \ '__| '__/ _ \| '__| *
5 //* | __/ | | | | (_) | | *
6 //* \___|_| |_| \___/|_| *
7 //* *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
18 
19 #ifndef PSTORE_SUPPORT_ERROR_HPP
20 #define PSTORE_SUPPORT_ERROR_HPP
21 
22 #include <cstdlib>
23 #include <system_error>
24 
25 #ifdef _WIN32
26 # define NOMINMAX
27 # define WIN32_LEAN_AND_MEAN
28 # include <Windows.h>
29 #endif
30 
31 #include "pstore/support/utf.hpp"
32 
33 #ifndef PSTORE_EXCEPTIONS
34 # include <iostream>
35 #endif
36 
37 namespace pstore {
38 
39 #define PSTORE_ERROR_CODES \
40  X (none) \
41  X (transaction_on_read_only_database) /* an attempt to create a transaction when the database \
42  is read-only */ \
43  X (unknown_revision) \
44  X (header_corrupt) \
45  X (header_version_mismatch) \
46  X (footer_corrupt) \
47  X (index_corrupt) \
48  X (bad_alignment) /* an address was not correctly aligned for its pointee type */ \
49  X (index_not_latest_revision) \
50  X (unknown_process_path) /* could not discover the path of the calling process image*/ \
51  X (store_closed) /*an attempt to read or write from a store which is not open*/ \
52  X (cannot_allocate_after_commit) /*cannot allocate data after a transaction has been \
53  committed*/ \
54  X (bad_address) /*an attempt to address an address outside of the allocated storage*/ \
55  X (read_only_address) /* an attempt to write to read-only storage*/ \
56  X (did_not_read_number_of_bytes_requested) \
57  X (uuid_parse_error) \
58  X (bad_message_part_number) \
59  X (unable_to_open_named_pipe) \
60  X (pipe_write_timeout) \
61  X (write_failed)
62 
63  // Add more error values here
64 
65  // **************
66  // * error code *
67  // **************
68 #define X(a) a,
69  enum class error_code : int { PSTORE_ERROR_CODES };
70 #undef X
71 
72 
73 
74  // ******************
75  // * error category *
76  // ******************
77  class error_category final : public std::error_category {
78  public:
79  // The need for this constructor was removed by CWG defect 253 but Clang (prior to 3.9.0)
80  // and GCC (before 4.6.4) require its presence.
81  error_category () noexcept {} // NOLINT
82  char const * name () const noexcept override;
83  std::string message (int error) const override;
84  };
85 
86  std::error_category const & get_error_category ();
87 
88  inline std::error_code make_error_code (error_code const erc) {
89  static_assert (std::is_same<std::underlying_type<decltype (erc)>::type, int>::value,
90  "base type of pstore::error_code must be int to permit safe static cast");
91  return {static_cast<int> (erc), get_error_category ()};
92  }
93 
94  // *************
95  // * errno_erc *
96  // *************
99  class errno_erc {
100  public:
101  constexpr explicit errno_erc (int const err) noexcept
102  : err_{err} {}
103  constexpr int get () const noexcept { return err_; }
104 
105  private:
106  int err_;
107  };
108 
109  inline std::error_code make_error_code (errno_erc const erc) noexcept {
110  return {erc.get (), std::generic_category ()};
111  }
112 
113 #ifdef _WIN32
114  class win32_erc {
115  public:
116  constexpr explicit win32_erc (DWORD err) noexcept
117  : err_{err} {}
118  constexpr int get () const noexcept { return err_; }
119 
120  private:
121  DWORD err_;
122  };
123 
124  inline std::error_code make_error_code (win32_erc const e) noexcept {
125  return {e.get (), std::system_category ()};
126  }
127 #endif //_WIN32
128 
129 } // end namespace pstore
130 
131 namespace std {
132 
133  template <>
134  struct is_error_code_enum<pstore::error_code> : std::true_type {};
135  template <>
136  struct is_error_code_enum<pstore::errno_erc> : std::true_type {};
137 
138 #ifdef _WIN32
139  template <>
140  struct is_error_code_enum<pstore::win32_erc> : std::true_type {};
141 #endif //_WIN32
142 
143 } // end namespace std
144 
145 namespace pstore {
146 
147  template <typename Exception, typename = typename std::enable_if<
148  std::is_base_of<std::exception, Exception>::value>::type>
149  PSTORE_NO_RETURN void raise_exception (Exception const & exc) {
150 #ifdef PSTORE_EXCEPTIONS
151  throw exc;
152 #else
153 # ifdef _WIN32
154  std::wcerr << L"Error: " << utf::win32::to16 (exc.what ()) << L'\n';
155 # else
156  std::cerr << "Error: " << exc.what () << '\n';
157 # endif // _WIN32
158  std::exit (EXIT_FAILURE);
159 #endif // PSTORE_EXCEPTIONS
160  }
161 
162  template <typename ErrorCode>
163  PSTORE_NO_RETURN void raise_error_code (ErrorCode erc) {
164  raise_exception (std::system_error{erc});
165  }
166  template <typename ErrorCode, typename StrType>
167  PSTORE_NO_RETURN void raise_error_code (ErrorCode erc, StrType const & what) {
168  raise_exception (std::system_error{erc, what});
169  }
170 
171  template <typename ErrorType>
172  PSTORE_NO_RETURN void raise (ErrorType erc) {
173  raise_error_code (make_error_code (erc));
174  }
175  template <typename ErrorType, typename StrType>
176  PSTORE_NO_RETURN void raise (ErrorType erc, StrType const & what) {
177  raise_error_code (make_error_code (erc), what);
178  }
179 
180 } // end namespace pstore
181 
182 #endif // PSTORE_SUPPORT_ERROR_HPP
Definition: chunked_sequence.hpp:607
This class is a tiny wrapper that allows an errno value to be passed to std::make_error_code().
Definition: error.hpp:99
Definition: nonpod2.cpp:40
Definition: error.hpp:77
Functionality for processing UTF-8 strings.