1515#pragma once
1616
1717#include < cstring>
18+ #include < format>
1819#include < iosfwd>
1920#include < memory>
2021#include < string>
2122#include < utility>
2223
2324#include " util/compare.h"
2425#include " util/macros.h"
25- #include " util/string_builder.h"
26- #include " util/visibility.h"
26+ #include " util/to_string_ostreamable.h"
2727
28- #ifdef ICEBERG_EXTRA_ERROR_CONTEXT
29-
30- // / \brief Return with given status if condition is met.
31- # define ICEBERG_RETURN_IF_ (condition, status, expr ) \
32- do { \
33- if (ICEBERG_PREDICT_FALSE (condition)) { \
34- ::iceberg::Status _st = (status); \
35- _st.AddContextLine (__FILE__, __LINE__, expr); \
36- return _st; \
37- } \
38- } while (false )
39-
40- #else
41-
42- # define ICEBERG_RETURN_IF_ (condition, status, _ ) \
43- do { \
44- if (ICEBERG_PREDICT_FALSE (condition)) { \
45- return (status); \
46- } \
47- } while (false )
48-
49- #endif // ICEBERG_EXTRA_ERROR_CONTEXT
28+ #define ICEBERG_RETURN_IF_ (condition, status, _ ) \
29+ do { \
30+ if (ICEBERG_PREDICT_FALSE (condition)) { \
31+ return (status); \
32+ } \
33+ } while (false )
5034
5135#define ICEBERG_RETURN_IF (condition, status ) \
5236 ICEBERG_RETURN_IF_ (condition, status, ICEBERG_STRINGIFY(status))
@@ -86,22 +70,16 @@ namespace iceberg {
8670enum class StatusCode : char {
8771 OK = 0 ,
8872 OutOfMemory = 1 ,
89- KeyError = 2 ,
90- TypeError = 3 ,
91- Invalid = 4 ,
92- IOError = 5 ,
93- CapacityError = 6 ,
94- IndexError = 7 ,
95- Cancelled = 8 ,
96- NotImplemented = 9 ,
97- SerializationError = 10 ,
98- AlreadyExists = 11 ,
73+ TypeError = 2 ,
74+ Invalid = 3 ,
75+ IOError = 4 ,
76+ NotImplemented = 5 ,
9977 UnknownError = 127
10078};
10179
10280// / \brief An opaque class that allows subsystems to retain
10381// / additional information inside the Status.
104- class ICEBERG_EXPORT StatusDetail {
82+ class StatusDetail {
10583 public:
10684 virtual ~StatusDetail () = default ;
10785 // / \brief Return a unique id for the type of the StatusDetail
@@ -123,16 +101,14 @@ class ICEBERG_EXPORT StatusDetail {
123101// /
124102// / Additionally, if an error occurred, a specific error message is generally
125103// / attached.
126- class ICEBERG_EXPORT [[nodiscard]] Status : public util::EqualityComparable<Status>,
127- public util::ToStringOstreamable<Status> {
104+ class [[nodiscard]] Status : public util::EqualityComparable<Status>,
105+ public util::ToStringOstreamable<Status> {
128106 public:
129107 // Create a success status.
130108 constexpr Status () noexcept : state_ (nullptr ) {}
131109 ~Status () noexcept {
132- if (ICEBERG_PREDICT_FALSE (state_ != NULL )) {
133- if (!state_->is_constant ) {
134- DeleteState ();
135- }
110+ if (ICEBERG_PREDICT_FALSE (state_ != nullptr )) {
111+ DeleteState ();
136112 }
137113 }
138114
@@ -160,14 +136,14 @@ class ICEBERG_EXPORT [[nodiscard]] Status : public util::EqualityComparable<Stat
160136 static Status OK () { return Status (); }
161137
162138 template <typename ... Args>
163- static Status FromArgs (StatusCode code, Args&&... args) {
164- return Status (code, util::StringBuilder ( std::forward<Args> (args) ...));
139+ static Status FromArgs (StatusCode code, std::string_view fmt, Args&&... args) {
140+ return Status (code, std::vformat (fmt, std::make_format_args (args...) ));
165141 }
166142
167143 template <typename ... Args>
168144 static Status FromDetailAndArgs (StatusCode code, std::shared_ptr<StatusDetail> detail,
169- Args&&... args) {
170- return Status (code, util::StringBuilder ( std::forward<Args> (args) ...),
145+ std::string_view fmt, Args&&... args) {
146+ return Status (code, std::vformat (fmt, std::make_format_args (args...) ),
171147 std::move (detail));
172148 }
173149
@@ -177,12 +153,6 @@ class ICEBERG_EXPORT [[nodiscard]] Status : public util::EqualityComparable<Stat
177153 return Status::FromArgs (StatusCode::OutOfMemory, std::forward<Args>(args)...);
178154 }
179155
180- // / Return an error status for failed key lookups (e.g. column name in a table)
181- template <typename ... Args>
182- static Status KeyError (Args&&... args) {
183- return Status::FromArgs (StatusCode::KeyError, std::forward<Args>(args)...);
184- }
185-
186156 // / Return an error status for type errors (such as mismatching data types)
187157 template <typename ... Args>
188158 static Status TypeError (Args&&... args) {
@@ -201,43 +171,13 @@ class ICEBERG_EXPORT [[nodiscard]] Status : public util::EqualityComparable<Stat
201171 return Status::FromArgs (StatusCode::IOError, std::forward<Args>(args)...);
202172 }
203173
204- // / Return an error status when a container's capacity would exceed its limits
205- template <typename ... Args>
206- static Status CapacityError (Args&&... args) {
207- return Status::FromArgs (StatusCode::CapacityError, std::forward<Args>(args)...);
208- }
209-
210- // / Return an error status when an index is out of bounds
211- template <typename ... Args>
212- static Status IndexError (Args&&... args) {
213- return Status::FromArgs (StatusCode::IndexError, std::forward<Args>(args)...);
214- }
215-
216- // / Return an error status for cancelled operation
217- template <typename ... Args>
218- static Status Cancelled (Args&&... args) {
219- return Status::FromArgs (StatusCode::Cancelled, std::forward<Args>(args)...);
220- }
221-
222174 // / Return an error status when an operation or a combination of operation and
223175 // / data types is unimplemented
224176 template <typename ... Args>
225177 static Status NotImplemented (Args&&... args) {
226178 return Status::FromArgs (StatusCode::NotImplemented, std::forward<Args>(args)...);
227179 }
228180
229- // / Return an error status when some (de)serialization operation failed
230- template <typename ... Args>
231- static Status SerializationError (Args&&... args) {
232- return Status::FromArgs (StatusCode::SerializationError, std::forward<Args>(args)...);
233- }
234-
235- // / Return an error status for already exists errors
236- template <typename ... Args>
237- static Status AlreadyExists (Args&&... args) {
238- return Status::FromArgs (StatusCode::AlreadyExists, std::forward<Args>(args)...);
239- }
240-
241181 // / Return an error status for unknown errors
242182 template <typename ... Args>
243183 static Status UnknownError (Args&&... args) {
@@ -249,27 +189,14 @@ class ICEBERG_EXPORT [[nodiscard]] Status : public util::EqualityComparable<Stat
249189
250190 // / Return true iff the status indicates an out-of-memory error.
251191 constexpr bool IsOutOfMemory () const { return code () == StatusCode::OutOfMemory; }
252- // / Return true iff the status indicates a key lookup error.
253- constexpr bool IsKeyError () const { return code () == StatusCode::KeyError; }
254192 // / Return true iff the status indicates a type error.
255193 constexpr bool IsTypeError () const { return code () == StatusCode::TypeError; }
256194 // / Return true iff the status indicates invalid data.
257195 constexpr bool IsInvalid () const { return code () == StatusCode::Invalid; }
258196 // / Return true iff the status indicates an IO-related failure.
259197 constexpr bool IsIOError () const { return code () == StatusCode::IOError; }
260- // / Return true iff the status indicates a container reaching capacity limits.
261- constexpr bool IsCapacityError () const { return code () == StatusCode::CapacityError; }
262- // / Return true iff the status indicates an out of bounds index.
263- constexpr bool IsIndexError () const { return code () == StatusCode::IndexError; }
264- // / Return true iff the status indicates a cancelled operation.
265- constexpr bool IsCancelled () const { return code () == StatusCode::Cancelled; }
266198 // / Return true iff the status indicates an unimplemented operation.
267199 constexpr bool IsNotImplemented () const { return code () == StatusCode::NotImplemented; }
268- // / Return true iff the status indicates a (de)serialization failure
269- constexpr bool IsSerializationError () const {
270- return code () == StatusCode::SerializationError;
271- }
272- constexpr bool IsAlreadyExists () const { return code () == StatusCode::AlreadyExists; }
273200 // / Return true iff the status indicates an unknown error.
274201 constexpr bool IsUnknownError () const { return code () == StatusCode::UnknownError; }
275202
@@ -278,12 +205,6 @@ class ICEBERG_EXPORT [[nodiscard]] Status : public util::EqualityComparable<Stat
278205 // / The string "OK" is returned for success.
279206 std::string ToString () const ;
280207
281- // / \brief Return a string representation of this status without
282- // / context lines suitable for printing.
283- // /
284- // / The string "OK" is returned for success.
285- std::string ToStringWithoutContextLines () const ;
286-
287208 // / \brief Return a string representation of the status code, without the message
288209 // / text or POSIX code information.
289210 std::string CodeAsString () const ;
@@ -320,17 +241,9 @@ class ICEBERG_EXPORT [[nodiscard]] Status : public util::EqualityComparable<Stat
320241 void Warn () const ;
321242 void Warn (const std::string& message) const ;
322243
323- [[noreturn]] void Abort () const ;
324- [[noreturn]] void Abort (const std::string& message) const ;
325-
326- #ifdef ICEBERG_EXTRA_ERROR_CONTEXT
327- void AddContextLine (const char * filename, int line, const char * expr);
328- #endif
329-
330244 private:
331245 struct State {
332246 StatusCode code;
333- bool is_constant;
334247 std::string msg;
335248 std::shared_ptr<StatusDetail> detail;
336249 };
@@ -342,17 +255,16 @@ class ICEBERG_EXPORT [[nodiscard]] Status : public util::EqualityComparable<Stat
342255 // On certain compilers, splitting off the slow path improves performance
343256 // significantly.
344257 delete state_;
258+ state_ = nullptr ;
345259 }
346260
347261 void CopyFrom (const Status& s);
348262 inline void MoveFrom (Status& s);
349263};
350264
351265void Status::MoveFrom (Status& s) {
352- if (ICEBERG_PREDICT_FALSE (state_ != NULL )) {
353- if (!state_->is_constant ) {
354- DeleteState ();
355- }
266+ if (ICEBERG_PREDICT_FALSE (state_ != nullptr )) {
267+ DeleteState ();
356268 }
357269 state_ = s.state_ ;
358270 s.state_ = nullptr ;
0 commit comments