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 1 0.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 0 1 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             struct ErrorCode : AllocatedObject {
13 0           ErrorCode () noexcept {}
14              
15             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             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             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             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             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             struct StrictErrorCode {
111             StrictErrorCode(const ErrorCode& ec) : base(ec) {}
112             const ErrorCode& base;
113             };
114              
115             inline bool operator== (const StrictErrorCode& lhs, const StrictErrorCode& rhs) noexcept { return lhs.base.code() == rhs.base.code(); }
116             inline bool operator!= (const StrictErrorCode& lhs, const StrictErrorCode& rhs) noexcept { return !(lhs == rhs); }
117              
118             inline bool operator& (const ErrorCode& lhs, const std::error_code& rhs) noexcept { return lhs.contains(rhs); }
119             inline bool operator& (const std::error_code& lhs, const ErrorCode& rhs) noexcept { return rhs.contains(lhs); }
120              
121             template ::value || std::is_error_condition_enum::value, void>>
122             inline bool operator& (const ErrorCode& ec, E e) noexcept { return ec.contains(make_error_code(e)); }
123             template ::value || std::is_error_condition_enum::value, void>>
124             inline bool operator& (E e, const ErrorCode& ec) noexcept { return ec.contains(make_error_code(e)); }
125              
126             inline bool operator< (const ErrorCode& lhs, const ErrorCode& rhs) noexcept { return lhs.code() < rhs.code(); }
127             inline bool operator< (const ErrorCode& lhs, const std::error_code& rhs) noexcept { return lhs.code() < rhs; }
128             inline bool operator< (const std::error_code& lhs, const ErrorCode& rhs) noexcept { return lhs < rhs.code(); }
129             template ::value || std::is_error_condition_enum::value, void>>
130             inline bool operator< (const ErrorCode& ec, E e) noexcept { return ec.code() < make_error_code(e); }
131             template ::value || std::is_error_condition_enum::value, void>>
132             inline bool operator< (E e, const ErrorCode& ec) noexcept { return make_error_code(e) < ec.code(); }
133              
134             std::ostream& operator<< (std::ostream&, const ErrorCode&);
135              
136             namespace details {
137             inline string error_message(const ErrorCode& e) {
138             return e.what();
139             }
140              
141             inline string error_message(const std::error_code& e) {
142             auto r = e.message();
143             return string(r.data(), r.size());
144             }
145              
146             template
147             struct bad_expected_access_code : std::exception {
148             explicit bad_expected_access_code (E e) : _val(std::move(e)) {}
149              
150             virtual const char* what () const noexcept override {
151             if (_message.empty()) {
152             _message = "Bad expected access: " + error_message(_val);
153             }
154             return _message.c_str();
155             }
156              
157             const E& error () const & { return _val; }
158             const E&& error () const && { return std::move(_val); }
159              
160             E& error () & { return _val; }
161             E&& error () && { return std::move(_val); }
162              
163             private:
164             E _val;
165             mutable std::string _message;
166             };
167             }
168              
169             }}
170              
171             namespace panda {
172             using ErrorCode = error::ErrorCode;
173              
174             template <>
175             struct bad_expected_access : error::details::bad_expected_access_code {
176             using bad_expected_access_code::bad_expected_access_code;
177             };
178              
179             template <>
180             struct bad_expected_access : error::details::bad_expected_access_code {
181             using bad_expected_access_code::bad_expected_access_code;
182             };
183             }
184              
185             namespace std {
186             template<> struct hash {
187             typedef panda::ErrorCode argument_type;
188             typedef std::size_t result_type;
189              
190             result_type operator()(argument_type const& c) const noexcept { return std::hash{}(c.code()); }
191             };
192             }