Common System 0.2.0
Common interfaces and patterns for system integration
Loading...
Searching...
No Matches
core.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
25#pragma once
26
27#include <optional>
28#include <sstream>
29#include <stdexcept>
30#include <string>
31#include <type_traits>
32#include <utility>
33#include <variant>
34
35// Import C++17-compatible source_location
37
38// Import new error_code type for category-based error handling
40
41namespace kcenon::common {
42
43// Forward declaration to avoid circular dependency
44// error_code is defined in error_category.h
45
46// ============================================================================
47// Forward Declarations (from fwd.h)
48// ============================================================================
49
50// Forward declarations
51struct error_info;
52template<typename T> class Result;
53template<typename T> class Optional;
54
58enum class result_state {
59 uninitialized, // Result has not been initialized with a value or error
60 ok, // Result contains a valid value
61 error // Result contains an error
62};
63
71
72// ============================================================================
73// Error Info (from error_info.h)
74// ============================================================================
75
80struct error_info {
81 int code;
82 std::string message;
83 std::string module;
84 std::optional<std::string> details;
85
86 error_info() : code(0) {}
87
89 error_info(const std::string& msg)
90 : code(-1), message(msg), module("") {}
91
93 error_info(int c, const std::string& msg, const std::string& mod = "")
94 : code(c), message(msg), module(mod) {}
95
97 error_info(int c, const std::string& msg, const std::string& mod,
98 const std::string& det)
99 : code(c), message(msg), module(mod), details(det) {}
100
107 template<typename Enum,
108 typename std::enable_if_t<std::is_enum_v<Enum>, int> = 0>
109 error_info(Enum c, std::string msg, std::string mod = "",
110 std::optional<std::string> det = std::nullopt)
111 : code(static_cast<int>(c)),
112 message(std::move(msg)),
113 module(std::move(mod)),
114 details(std::move(det)) {}
115
116 bool operator==(const error_info& other) const {
117 return code == other.code && message == other.message &&
118 module == other.module && details == other.details;
119 }
120
121 bool operator!=(const error_info& other) const {
122 return !(*this == other);
123 }
124
135 : code(ec.value()),
136 message(ec.message()),
137 module(std::string(ec.category_name())) {}
138};
139
140
141// ============================================================================
142// Result<T> Class (from result_core.h)
143// ============================================================================
144
165template<typename T>
166class Result {
167public:
169 using value_type = T;
170
173
174private:
175 // Use std::optional<T> for value, which naturally supports uninitialized state
176 // Store error separately to avoid variant issues
177 std::optional<T> value_;
178 std::optional<error_info> error_;
179
180public:
181 // Constructors - public but encourage use of factory methods
182 Result(const T& value) : value_(value), error_(std::nullopt) {}
183 Result(T&& value) : value_(std::move(value)), error_(std::nullopt) {}
184 Result(const error_info& error) : value_(std::nullopt), error_(error) {}
185 Result(error_info&& error) : value_(std::nullopt), error_(std::move(error)) {}
186
195 Result(const typed_error_code& ec) : value_(std::nullopt), error_(error_info(ec)) {}
205 Result() = delete;
206
207 // Copy and move
208 Result(const Result&) = default;
209 Result(Result&&) = default;
210 Result& operator=(const Result&) = default;
211 Result& operator=(Result&&) = default;
212
213 // Static factory methods (Rust-style API)
222 template<typename U = T>
223 static Result<T> ok(U&& value) {
224 return Result<T>(std::forward<U>(value));
225 }
226
232 static Result<T> err(const error_info& error) {
233 return Result<T>(error);
234 }
235
242 return Result<T>(std::move(error));
243 }
244
252 static Result<T> err(int code, const std::string& message, const std::string& module = "") {
253 return Result<T>(error_info{code, message, module});
254 }
255
271 static Result<T> err(const typed_error_code& ec) {
272 return Result<T>(ec);
273 }
274
284 return Result<T>(error_info{-6, "Result not initialized", "common::Result"});
285 }
286
290 bool is_ok() const {
291 return value_.has_value();
292 }
293
297 bool is_err() const {
298 return error_.has_value();
299 }
300
306#if KCENON_HAS_SOURCE_LOCATION
307 const T& unwrap(
309 ) const {
310 if (is_err()) {
311 const auto& err = error_.value();
312 std::ostringstream oss;
313 oss << "Called unwrap on error: " << err.message << "\n"
314 << " Error code: " << err.code << "\n"
315 << " Module: " << (err.module.empty() ? "unknown" : err.module) << "\n"
316 << " Location: " << loc.file_name() << ":" << loc.line() << ":" << loc.column() << "\n"
317 << " Function: " << loc.function_name();
318 if (err.details.has_value()) {
319 oss << "\n Details: " << err.details.value();
320 }
321 throw std::runtime_error(oss.str());
322 }
323 return value_.value();
324 }
325#else
326 const T& unwrap() const {
327 if (is_err()) {
328 const auto& err = error_.value();
329 throw std::runtime_error("Called unwrap on error: " + err.message);
330 }
331 return value_.value();
332 }
333#endif
334
340#if KCENON_HAS_SOURCE_LOCATION
341 T& unwrap(
343 ) {
344 if (is_err()) {
345 const auto& err = error_.value();
346 std::ostringstream oss;
347 oss << "Called unwrap on error: " << err.message << "\n"
348 << " Error code: " << err.code << "\n"
349 << " Module: " << (err.module.empty() ? "unknown" : err.module) << "\n"
350 << " Location: " << loc.file_name() << ":" << loc.line() << ":" << loc.column() << "\n"
351 << " Function: " << loc.function_name();
352 if (err.details.has_value()) {
353 oss << "\n Details: " << err.details.value();
354 }
355 throw std::runtime_error(oss.str());
356 }
357 return value_.value();
358 }
359#else
360 T& unwrap() {
361 if (is_err()) {
362 const auto& err = error_.value();
363 throw std::runtime_error("Called unwrap on error: " + err.message);
364 }
365 return value_.value();
366 }
367#endif
368
372 T unwrap_or(T default_value) const {
373 if (is_ok()) {
374 return value_.value();
375 }
376 return default_value;
377 }
378
384 T value_or(T default_value) const {
385 return unwrap_or(std::move(default_value));
386 }
387
391 const T& value() const {
392 return value_.value();
393 }
394
398 T& value() {
399 return value_.value();
400 }
401
405 const error_info& error() const {
406 return error_.value();
407 }
408
412 template<typename F>
413 auto map(F&& func) const -> Result<decltype(func(std::declval<T>()))> {
414 using ReturnType = decltype(func(std::declval<T>()));
415
416 if (is_ok()) {
417 return Result<ReturnType>(func(value_.value()));
418 } else if (is_err()) {
419 return Result<ReturnType>(error_.value());
420 } else {
421 // Uninitialized state - use uninitialized factory
423 }
424 }
425
429 template<typename F>
430 auto and_then(F&& func) const -> decltype(func(std::declval<T>())) {
431 using ReturnType = decltype(func(std::declval<T>()));
432
433 if (is_ok()) {
434 return func(value_.value());
435 } else if (is_err()) {
436 return ReturnType(error_.value());
437 } else {
438 // Uninitialized state - use uninitialized factory
439 return ReturnType::uninitialized();
440 }
441 }
442
446 template<typename F>
447 Result<T> or_else(F&& func) const {
448 if (is_ok()) {
449 return *this;
450 } else if (is_err()) {
451 return func(error_.value());
452 } else {
453 // Uninitialized state
454 return *this;
455 }
456 }
457};
458
459// ============================================================================
460// Optional<T> Class (from optional.h)
461// ============================================================================
462
467template<typename T>
468class Optional {
469public:
471 using value_type = T;
472
473private:
474 std::optional<T> value_;
475
476public:
477 Optional() : value_(std::nullopt) {}
478 Optional(const T& value) : value_(value) {}
479 Optional(T&& value) : value_(std::move(value)) {}
480 Optional(std::nullopt_t) : value_(std::nullopt) {}
481
482 bool has_value() const { return value_.has_value(); }
483 bool is_some() const { return value_.has_value(); }
484 bool is_none() const { return !value_.has_value(); }
485
486 const T& value() const { return value_.value(); }
487 T& value() { return value_.value(); }
488
494#if KCENON_HAS_SOURCE_LOCATION
495 const T& unwrap(
497 ) const {
498 if (!has_value()) {
499 std::ostringstream oss;
500 oss << "Called unwrap on None\n"
501 << " Location: " << loc.file_name() << ":" << loc.line() << ":" << loc.column() << "\n"
502 << " Function: " << loc.function_name();
503 throw std::runtime_error(oss.str());
504 }
505 return value_.value();
506 }
507#else
508 const T& unwrap() const {
509 if (!has_value()) {
510 throw std::runtime_error("Called unwrap on None");
511 }
512 return value_.value();
513 }
514#endif
515
516 T unwrap_or(T default_value) const {
517 return value_.value_or(default_value);
518 }
519
520 template<typename F>
521 auto map(F&& func) const -> Optional<decltype(func(std::declval<T>()))> {
522 using ReturnType = decltype(func(std::declval<T>()));
523
524 if (has_value()) {
525 return Optional<ReturnType>(func(value_.value()));
526 } else {
527 return Optional<ReturnType>(std::nullopt);
528 }
529 }
530};
531
532// Optional factory functions
533
537template<typename T>
538inline Optional<T> Some(T value) {
539 return Optional<T>(std::move(value));
540}
541
545template<typename T>
547 return Optional<T>(std::nullopt);
548}
549
550} // namespace kcenon::common
Optional type similar to std::optional with Rust-like API.
Definition core.cppm:341
Optional(const T &value)
Definition core.h:478
T value_type
Type alias for the contained value type (for concept compatibility)
Definition core.h:471
Optional(std::nullopt_t)
Definition core.h:480
std::optional< T > value_
Definition core.h:474
bool is_some() const
Definition core.h:483
bool is_none() const
Definition core.h:484
const T & unwrap() const
Get value from optional (throws if None)
Definition core.h:508
T unwrap_or(T default_value) const
Definition core.h:516
auto map(F &&func) const -> Optional< decltype(func(std::declval< T >()))>
Definition core.h:521
bool has_value() const
Definition core.h:482
Optional(T &&value)
Definition core.h:479
const T & value() const
Definition core.h:486
Result type for error handling with member function support.
Definition core.cppm:165
Result(T &&value)
Definition core.h:183
const error_info & error() const
Get error reference.
Definition core.h:405
Result(const Result &)=default
static Result< T > err(int code, const std::string &message, const std::string &module="")
Create an error result with code and message (static factory)
Definition core.h:252
Result(const T &value)
Definition core.h:182
Result & operator=(Result &&)=default
bool is_err() const
Check if result contains an error.
Definition core.h:297
Result()=delete
Default constructor is deleted to enforce explicit initialization.
T & unwrap()
Get mutable value from result (throws if error)
Definition core.h:360
Result(const typed_error_code &ec)
Construct from category-based typed_error_code.
Definition core.h:195
static Result< T > err(const typed_error_code &ec)
Create an error result from category-based typed_error_code (static factory)
Definition core.h:271
static Result< T > uninitialized()
Create an explicitly uninitialized result (use with caution)
Definition core.h:283
T value_or(T default_value) const
Get value or return default (C++23 std::expected compatible)
Definition core.h:384
Result(Result &&)=default
auto map(F &&func) const -> Result< decltype(func(std::declval< T >()))>
Map a function over a successful result.
Definition core.h:413
T value_type
Type alias for the contained value type (for concept compatibility)
Definition core.h:169
static Result< T > err(const error_info &error)
Create an error result from error_info (static factory)
Definition core.h:232
static Result< T > err(error_info &&error)
Create an error result from error_info (static factory, move)
Definition core.h:241
Result(error_info &&error)
Definition core.h:185
static Result< T > ok(U &&value)
Create a successful result with value (static factory)
Definition core.h:223
Result< T > or_else(F &&func) const
Provide alternative value if error.
Definition core.h:447
auto and_then(F &&func) const -> decltype(func(std::declval< T >()))
Map a function that returns a Result (flatMap/bind)
Definition core.h:430
std::optional< error_info > error_
Definition core.h:178
const T & value() const
Get value reference (const)
Definition core.h:391
Result(const error_info &error)
Definition core.h:184
std::optional< T > value_
Definition core.h:177
bool is_ok() const
Check if result contains a successful value.
Definition core.h:290
Result & operator=(const Result &)=default
const T & unwrap() const
Get value from result (throws if error)
Definition core.h:326
T unwrap_or(T default_value) const
Get value or return default.
Definition core.h:372
T & value()
Get value reference (mutable)
Definition core.h:398
A type-safe error code that carries its category.
Decentralized error category system for improved system isolation.
Core interfaces.
Definition adapter.h:21
VoidResult ok()
Create a successful void result.
Definition utilities.h:71
result_state
Result state enum for tracking initialization.
Definition core.h:58
Optional< T > None()
Create an empty Optional.
Definition core.h:546
Optional< T > Some(T value)
Create an Optional with value.
Definition core.h:538
C++17-compatible source_location implementation.
Standard error information used by Result<T>.
Definition core.cppm:106
std::string message
Definition core.h:82
error_info(int c, const std::string &msg, const std::string &mod, const std::string &det)
Construct with code, message, module and details.
Definition core.h:97
std::optional< std::string > details
Definition core.h:84
error_info(Enum c, std::string msg, std::string mod="", std::optional< std::string > det=std::nullopt)
Construct from strongly-typed enum error codes.
Definition core.h:109
bool operator==(const error_info &other) const
Definition core.h:116
std::string module
Definition core.h:83
error_info(int c, const std::string &msg, const std::string &mod="")
Construct with code, message and optional module.
Definition core.h:93
error_info(const typed_error_code &ec)
Construct from the new category-based typed_error_code type.
Definition core.h:134
bool operator!=(const error_info &other) const
Definition core.h:121
error_info(const std::string &msg)
Construct with message only.
Definition core.h:89
C++17-compatible source_location implementation using compiler builtins.
Definition utils.cppm:54
static constexpr source_location current(const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE()) noexcept