File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/XS/libpanda.x/i/panda/error.h
Criterion Covered Total %
statement 0 7 0.0
branch 0 2 0.0
condition n/a
subroutine n/a
pod n/a
total 0 9 0.0


line stmt bran cond sub pod time code
1             #pragma once
2             #include "memory.h"
3             #include "string.h"
4             #include "varint.h"
5             #include "refcnt.h"
6             #include "expected.h"
7             #include
8             #include
9              
10             namespace panda { namespace error {
11              
12 0           struct ErrorCode : AllocatedObject {
13 0           ErrorCode () noexcept {}
14              
15 0           ErrorCode (const ErrorCode& o) noexcept : data(o.data) {}
16             ErrorCode (ErrorCode&& o) noexcept : data(std::move(o.data)) {}
17              
18             ErrorCode (int ec, const std::error_category& cat) noexcept { if (ec) set(std::error_code(ec, cat)); }
19              
20 0 0         ErrorCode (const std::error_code& ec) noexcept { if (ec) set(ec); }
21              
22             template ::value, void>>
23             ErrorCode (N e) noexcept : ErrorCode(std::error_code(e)) {}
24              
25             ErrorCode (const std::error_code& ec, const std::error_code& next) noexcept { set(ec, next); }
26 0           ErrorCode (const std::error_code& ec, const ErrorCode& next) noexcept { set(ec, next); }
27              
28             ErrorCode& operator= (const ErrorCode& o) noexcept { data = o.data; return *this; }
29 0           ErrorCode& operator= (ErrorCode&& o) noexcept { data = std::move(o.data); return *this; }
30              
31             ErrorCode& operator= (const std::error_code& ec) {
32             if (ec) set(ec);
33             else clear();
34             return *this;
35             }
36              
37             template ::value, void>>
38             ErrorCode& operator= (N e) noexcept {
39             set(std::error_code(e));
40             return *this;
41             }
42              
43             void clear () noexcept {
44             data.reset();
45             }
46              
47 0           explicit operator bool () const noexcept { return data; }
48              
49             std::error_code code () const noexcept {
50             if (!data) return {};
51             return std::error_code(data->codes.top(), data->cat->self);
52             };
53              
54             int value () const noexcept {
55             if (!data) return 0;
56             return data->codes.top();
57             }
58              
59             const std::error_category& category () const noexcept {
60             if (!data) return std::system_category();
61             return data->cat->self;
62             }
63              
64             std::error_condition default_error_condition () const noexcept {
65             return code().default_error_condition();
66             }
67              
68             std::string message () const;
69              
70             ErrorCode next () const noexcept;
71              
72             string what () const;
73              
74             bool contains (const std::error_code& c) const {
75             if (!data) {
76             return !c;
77             }
78             return contains_impl(c);
79             }
80              
81             // any user can add specialization for his own result and get any data
82             template
83             T private_access(Args...);
84              
85             template
86             T private_access(Args...) const;
87              
88             struct NestedCategory {
89             const std::error_category& self;
90             const NestedCategory* next;
91             };
92              
93             private:
94             struct Data : Refcnt, AllocatedObject {
95             using CodeStack = VarIntStack;
96             CodeStack codes;
97             const NestedCategory* cat;
98             };
99              
100             iptr data;
101              
102             void init ();
103             void set (const std::error_code& ec);
104             void set (const std::error_code& ec, const std::error_code& next);
105             void set (const std::error_code& ec, const ErrorCode& next);
106             void push (const std::error_code&);
107             bool contains_impl (const std::error_code& c) const;
108             };
109              
110             inline bool operator== (const ErrorCode& lhs, const ErrorCode& rhs) noexcept { return lhs.code() == rhs.code(); }
111             inline bool operator== (const ErrorCode& lhs, const std::error_code& rhs) noexcept { return lhs.code() == rhs; }
112             inline bool operator== (const std::error_code& lhs, const ErrorCode& rhs) noexcept { return lhs == rhs.code(); }
113             inline bool operator== (const ErrorCode& lhs, const std::error_condition& rhs) noexcept { return lhs.code() == rhs; }
114             inline bool operator== (const std::error_condition& lhs, const ErrorCode& rhs) noexcept { return lhs == rhs.code(); }
115             template ::value || std::is_error_condition_enum::value, void>>
116             inline bool operator== (const ErrorCode& ec, E e) noexcept { return ec.code() == make_error_code(e); }
117             template ::value || std::is_error_condition_enum::value, void>>
118             inline bool operator== (E e, const ErrorCode& ec) noexcept { return ec.code() == make_error_code(e); }
119              
120             inline bool operator!= (const ErrorCode& lhs, const ErrorCode& rhs) noexcept { return lhs.code() != rhs.code(); }
121             inline bool operator!= (const ErrorCode& lhs, const std::error_code& rhs) noexcept { return lhs.code() != rhs; }
122             inline bool operator!= (const std::error_code& lhs, const ErrorCode& rhs) noexcept { return lhs != rhs.code(); }
123             inline bool operator!= (const ErrorCode& lhs, const std::error_condition& rhs) noexcept { return lhs.code() != rhs; }
124             inline bool operator!= (const std::error_condition& lhs, const ErrorCode& rhs) noexcept { return lhs != rhs.code(); }
125             template ::value || std::is_error_condition_enum::value, void>>
126             inline bool operator!= (const ErrorCode& ec, E e) noexcept { return ec.code() != make_error_code(e); }
127             template ::value || std::is_error_condition_enum::value, void>>
128             inline bool operator!= (E e, const ErrorCode& ec) noexcept { return ec.code() != make_error_code(e); }
129              
130             inline bool operator< (const ErrorCode& lhs, const ErrorCode& rhs) noexcept { return lhs.code() < rhs.code(); }
131             inline bool operator< (const ErrorCode& lhs, const std::error_code& rhs) noexcept { return lhs.code() < rhs; }
132             inline bool operator< (const std::error_code& lhs, const ErrorCode& rhs) noexcept { return lhs < rhs.code(); }
133             template ::value || std::is_error_condition_enum::value, void>>
134             inline bool operator< (const ErrorCode& ec, E e) noexcept { return ec.code() < make_error_code(e); }
135             template ::value || std::is_error_condition_enum::value, void>>
136             inline bool operator< (E e, const ErrorCode& ec) noexcept { return make_error_code(e) < ec.code(); }
137              
138             std::ostream& operator<< (std::ostream&, const ErrorCode&);
139              
140             namespace details {
141             inline string error_message(const ErrorCode& e) {
142             return e.what();
143             }
144              
145             inline string error_message(const std::error_code& e) {
146             auto r = e.message();
147             return string(r.data(), r.size());
148             }
149              
150             template
151             struct bad_expected_access_code : std::exception {
152             explicit bad_expected_access_code (E e) : _val(std::move(e)) {}
153              
154             virtual const char* what () const noexcept override {
155             if (_message.empty()) {
156             _message = "Bad expected access: " + error_message(_val);
157             }
158             return _message.c_str();
159             }
160              
161             const E& error () const & { return _val; }
162             const E&& error () const && { return std::move(_val); }
163              
164             E& error () & { return _val; }
165             E&& error () && { return std::move(_val); }
166              
167             private:
168             E _val;
169             mutable std::string _message;
170             };
171             }
172              
173             }}
174              
175             namespace panda {
176             using ErrorCode = error::ErrorCode;
177              
178             template <>
179             struct bad_expected_access : error::details::bad_expected_access_code {
180             using bad_expected_access_code::bad_expected_access_code;
181             };
182              
183             template <>
184             struct bad_expected_access : error::details::bad_expected_access_code {
185             using bad_expected_access_code::bad_expected_access_code;
186             };
187             }
188              
189             namespace std {
190             template<> struct hash {
191             typedef panda::ErrorCode argument_type;
192             typedef std::size_t result_type;
193              
194             result_type operator()(argument_type const& c) const noexcept { return std::hash{}(c.code()); }
195             };
196             }