Error Handling Overview

The cslt library provides a robust, STL-independent error handling system designed for safety-critical and embedded applications. The error handling framework consists of two main components: a hierarchical exception class system and an Expected<T> type for exception-free error handling.

All error handling components are defined in Error.hpp and reside in the cslt namespace.

Error Class Overview

The cslt::Error class hierarchy provides a comprehensive, three-level taxonomy of error conditions designed for type-safe exception handling in C++ applications. At the base is the Error class, which serves as the foundation for all errors in the library. This base class is specialized into nine category-level error classes (ArgumentError, MemoryError, StateError, MathError, IOError, FormatError, ConcurrencyError, ConfigError, and GenericError), each representing a broad class of related failures. These categories are further refined into 40+ specific error types that precisely describe individual error conditions.

This hierarchical design enables flexible error handling strategies. Applications can catch specific error types for fine-grained control (e.g., NullPointerError), catch category-level errors to handle related failures uniformly (e.g., all ArgumentError types), or catch the base Error class to handle any library error. The hierarchy ensures that error handling can be as specific or general as the application requires.

Each error class provides two constructors: a default constructor that uses a predefined, descriptive error message, and a parameterized constructor that accepts a custom message for context-specific details. All error messages are stored in fixed 256-byte buffers, eliminating dynamic allocation and ensuring predictable memory usage—critical for embedded systems and safety-critical applications.

Error Class Hierarchy

The following diagram illustrates the complete error hierarchy:

Error (base)
├── ArgumentError
│   ├── InvalidArgError
│   ├── NullPointerError
│   ├── OutOfBoundsError
│   ├── SizeMismatchError
│   ├── UninitializedError
│   ├── IteratorInvalidError
│   ├── PreconditionFailError
│   ├── PostconditionFailError
│   └── IllegalStateError
├── MemoryError
│   ├── BadAllocError
│   ├── ReallocFailError
│   ├── OutOfMemoryError
│   ├── LengthOverflowError
│   ├── CapacityOverflowError
│   └── AlignmentError
├── StateError
│   ├── StateCorruptError
│   ├── AlreadyInitializedError
│   ├── NotFoundError
│   ├── EmptyError
│   └── ConcurrentModificationError
├── MathError
│   ├── DivByZeroError
│   ├── SingularMatrixError
│   ├── NumericOverflowError
│   ├── DomainError
│   └── LossOfPrecisionError
├── IOError
│   ├── FileOpenError
│   ├── FileReadError
│   ├── FileWriteError
│   ├── PermissionDeniedError
│   ├── IOInterruptedError
│   ├── IOTimeoutError
│   ├── IOClosedError
│   └── IOWouldBlockError
├── FormatError
│   ├── TypeMismatchError
│   ├── FormatInvalidError
│   ├── EncodingInvalidError
│   ├── ParsingFailedError
│   └── ValidationFailedError
├── ConcurrencyError
│   ├── LockFailedError
│   ├── DeadlockDetectedError
│   ├── ThreadFailError
│   ├── CancelledError
│   └── RaceDetectedError
├── ConfigError
│   ├── ConfigInvalidError
│   ├── UnsupportedError
│   ├── FeatureDisabledError
│   ├── VersionMismatchError
│   └── ResourceExhaustedError
└── GenericError
    ├── NotImplementedError
    ├── OperationUnavailableError
    └── UnknownError

Base Error Class

class Error

Base class for all cslt library exceptions with fixed-size error messages.

The Error class provides a lightweight, STL-independent exception mechanism with predictable memory usage. Error messages are stored in a fixed-size buffer to avoid heap allocations, making it suitable for embedded systems and real-time applications.

All error messages are capped at MAX_MESSAGE_LEN (256 characters). Messages exceeding this length are silently truncated.

Example Usage:
// Using default error message
try {
    throw cslt::Error();
} catch (const cslt::Error& e) {
    printf("Error: %s\n", e.what());  // "An error occurred"
}

// Using custom error message
try {
    throw cslt::Error("Failed to process data");
} catch (const cslt::Error& e) {
    printf("Error: %s\n", e.what());  // "Failed to process data"
}

Subclassed by cslt::ArgumentError, cslt::ConcurrencyError, cslt::ConfigError, cslt::FormatError, cslt::GenericError, cslt::IOError, cslt::MathError, cslt::MemoryError, cslt::NoError, cslt::StateError

Public Functions

Error()

Constructs an Error with the default message.

Creates an error object with the predefined message “An error occurred”. Use this constructor when a generic error indication is sufficient.

Error(const char *msg)

Constructs an Error with a custom message.

Creates an error object with the specified error message. If msg exceeds MAX_MESSAGE_LEN-1 characters, it will be truncated to fit.

Parameters:

msg – Null-terminated custom error message string (max 255 characters)

virtual const char *what() const

Returns the error message.

Returns:

Pointer to null-terminated error message string

virtual ~Error()

Virtual destructor for proper cleanup of derived classes.

Protected Static Functions

static void safeCopy(char *dest, const char *src, size_t maxLen)

Safely copies a null-terminated string to a destination buffer.

Copies characters from src to dest up to maxLen-1 characters, ensuring the destination is always null-terminated. If src is longer than maxLen-1, the string is truncated.

Parameters:
  • dest – Destination buffer to copy into

  • src – Source null-terminated string to copy from

  • maxLen – Maximum length of destination buffer including null terminator

static void append(char *dest, const char *suffix, size_t maxLen)

Appends a string to the end of an existing null-terminated string.

Appends suffix to the end of dest, respecting the maxLen buffer size. If the combined length would exceed maxLen-1, the result is truncated. The destination buffer is always null-terminated.

Parameters:
  • dest – Destination buffer containing existing string to append to

  • suffix – Null-terminated string to append

  • maxLen – Maximum length of destination buffer including null terminator

static void prepend(char *dest, const char *prefix, size_t maxLen)

Prepends a string to the beginning of an existing null-terminated string.

Inserts prefix before the existing content in dest, respecting the maxLen buffer size. If the combined length would exceed maxLen-1, the result is truncated. The destination buffer is always null-terminated.

Parameters:
  • dest – Destination buffer containing existing string to prepend to

  • prefix – Null-terminated string to insert at the beginning

  • maxLen – Maximum length of destination buffer including null terminator

static void compose(char *dest, const char *prefix, const char *suffix, size_t maxLen)

Composes a new string by concatenating prefix and suffix.

Copies prefix into dest, then appends suffix. If the combined length would exceed maxLen-1, the result is truncated. The destination buffer is always null-terminated. Any existing content in dest is overwritten.

Parameters:
  • dest – Destination buffer to write composed string into

  • prefix – Null-terminated string to write first

  • suffix – Null-terminated string to append after prefix

  • maxLen – Maximum length of destination buffer including null terminator

Category-Level Error Classes

No Error

class NoError : public cslt::Error

Argument and input for no error.

NoError represents state where no error is present

Example Usage:
// Using default message
throw NoError();  // "No Error"

// Using custom message
throw NoError("Function X executed with no error");

Public Functions

NoError()

Constructs an NoError with the default message.

Creates an NoError with the predefined message “No Error”.

NoError(const char *msg)

Constructs an NoError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Argument and Input Validation Errors

class ArgumentError : public cslt::Error

Argument and input validation errors.

ArgumentError represents errors related to invalid function arguments, null pointers, out-of-bounds access, and other input validation failures.

Example Usage:
// Using default message
throw ArgumentError();  // "Invalid argument"

// Using custom message
throw ArgumentError("Index 5 is out of bounds for array of size 3");

Subclassed by cslt::IllegalStateError, cslt::InvalidArgError, cslt::IteratorInvalidError, cslt::NullPointerError, cslt::OutOfBoundsError, cslt::PostconditionFailError, cslt::PreconditionFailError, cslt::SizeMismatchError, cslt::UninitializedError

Public Functions

ArgumentError()

Constructs an ArgumentError with the default message.

Creates an ArgumentError with the predefined message “Invalid argument”.

ArgumentError(const char *msg)

Constructs an ArgumentError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Specific ArgumentError Types:

class InvalidArgError : public cslt::ArgumentError

Invalid function argument error.

InvalidArgError represents an error when an invalid argument is passed to a function.

Example Usage:
throw InvalidArgError();  // "Invalid function argument"
throw InvalidArgError("Expected positive value, got -5");

Public Functions

InvalidArgError()

Constructs an InvalidArgError with the default message.

InvalidArgError(const char *msg)

Constructs an InvalidArgError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class NullPointerError : public cslt::ArgumentError

Null pointer error.

NullPointerError represents an error when a null pointer is passed where a valid pointer is required.

Example Usage:
throw NullPointerError();  // "Null pointer passed"
throw NullPointerError("Buffer pointer is null");

Public Functions

NullPointerError()

Constructs a NullPointerError with the default message.

NullPointerError(const char *msg)

Constructs a NullPointerError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class OutOfBoundsError : public cslt::ArgumentError

Out of bounds access error.

OutOfBoundsError represents an error when an index or position is outside the valid range.

Example Usage:
throw OutOfBoundsError();  // "Index out of range"
throw OutOfBoundsError("Index 10 exceeds array size 5");

Public Functions

OutOfBoundsError()

Constructs an OutOfBoundsError with the default message.

OutOfBoundsError(const char *msg)

Constructs an OutOfBoundsError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class SizeMismatchError : public cslt::ArgumentError

Size or dimension mismatch error.

SizeMismatchError represents an error when dimensions or sizes of objects don’t match as required for an operation.

Example Usage:
throw SizeMismatchError();  // "Dimension/size mismatch"
throw SizeMismatchError("Matrix dimensions incompatible: 3x4 and 2x3");

Public Functions

SizeMismatchError()

Constructs a SizeMismatchError with the default message.

SizeMismatchError(const char *msg)

Constructs a SizeMismatchError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class UninitializedError : public cslt::ArgumentError

Uninitialized element access error.

UninitializedError represents an error when attempting to access an element or object that has not been properly initialized.

Example Usage:
throw UninitializedError();  // "Uninitialized element access"
throw UninitializedError("Attempting to read uninitialized variable");

Public Functions

UninitializedError()

Constructs an UninitializedError with the default message.

UninitializedError(const char *msg)

Constructs an UninitializedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class IteratorInvalidError : public cslt::ArgumentError

Invalid iterator or cursor error.

IteratorInvalidError represents an error when an iterator or cursor is dangling, invalidated, or otherwise unusable.

Example Usage:
throw IteratorInvalidError();  // "Invalid iterator/cursor"
throw IteratorInvalidError("Iterator invalidated by container modification");

Public Functions

IteratorInvalidError()

Constructs an IteratorInvalidError with the default message.

IteratorInvalidError(const char *msg)

Constructs an IteratorInvalidError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class PreconditionFailError : public cslt::ArgumentError

Precondition failure error.

PreconditionFailError represents an error when a required precondition for an operation is not satisfied.

Example Usage:
throw PreconditionFailError();  // "Precondition failed"
throw PreconditionFailError("Array must be sorted before binary search");

Public Functions

PreconditionFailError()

Constructs a PreconditionFailError with the default message.

PreconditionFailError(const char *msg)

Constructs a PreconditionFailError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class PostconditionFailError : public cslt::ArgumentError

Postcondition failure error.

PostconditionFailError represents an error when a postcondition or invariant is violated after an operation.

Example Usage:
throw PostconditionFailError();  // "Postcondition failed"
throw PostconditionFailError("Invariant violated: size must equal capacity");

Public Functions

PostconditionFailError()

Constructs a PostconditionFailError with the default message.

PostconditionFailError(const char *msg)

Constructs a PostconditionFailError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class IllegalStateError : public cslt::ArgumentError

Illegal state for operation error.

IllegalStateError represents an error when an API call is not valid for the current state of the object.

Example Usage:
throw IllegalStateError();  // "Illegal state for operation"
throw IllegalStateError("Cannot read from closed stream");

Public Functions

IllegalStateError()

Constructs an IllegalStateError with the default message.

IllegalStateError(const char *msg)

Constructs an IllegalStateError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Memory Management Errors

class MemoryError : public cslt::Error

Memory allocation and management errors.

MemoryError represents errors related to memory allocation failures, reallocation issues, out-of-memory conditions, and alignment problems.

Example Usage:
// Using default message
throw MemoryError();  // "Memory allocation failed"

// Using custom message
throw MemoryError("Failed to allocate 1024 bytes");

Subclassed by cslt::AlignmentError, cslt::BadAllocError, cslt::CapacityOverflowError, cslt::LengthOverflowError, cslt::OutOfMemoryError, cslt::ReallocFailError

Public Functions

MemoryError()

Constructs a MemoryError with the default message.

Creates a MemoryError with the predefined message “Memory allocation failed”.

MemoryError(const char *msg)

Constructs a MemoryError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Specific MemoryError Types:

class BadAllocError : public cslt::MemoryError

Memory allocation failure error.

BadAllocError represents an error when malloc, calloc, or new fails to allocate memory.

Example Usage:
throw BadAllocError();  // "Memory allocation failed"
throw BadAllocError("Failed to allocate 1024 bytes for buffer");

Public Functions

BadAllocError()

Constructs a BadAllocError with the default message.

BadAllocError(const char *msg)

Constructs a BadAllocError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class ReallocFailError : public cslt::MemoryError

Memory reallocation failure error.

ReallocFailError represents an error when realloc fails to resize a memory block (the original buffer remains unchanged).

Example Usage:
throw ReallocFailError();  // "Memory reallocation failed"
throw ReallocFailError("Failed to expand buffer from 512 to 1024 bytes");

Public Functions

ReallocFailError()

Constructs a ReallocFailError with the default message.

ReallocFailError(const char *msg)

Constructs a ReallocFailError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class OutOfMemoryError : public cslt::MemoryError

System out of memory error.

OutOfMemoryError represents an error when the system is completely out of memory or an allocator has reached its limit.

Example Usage:
throw OutOfMemoryError();  // "Out of memory"
throw OutOfMemoryError("System memory exhausted");

Public Functions

OutOfMemoryError()

Constructs an OutOfMemoryError with the default message.

OutOfMemoryError(const char *msg)

Constructs an OutOfMemoryError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class LengthOverflowError : public cslt::MemoryError

Length or size arithmetic overflow error.

LengthOverflowError represents an error when size or length calculations result in arithmetic overflow.

Example Usage:
throw LengthOverflowError();  // "Length/size arithmetic overflow"
throw LengthOverflowError("Size calculation overflowed: SIZE_MAX exceeded");

Public Functions

LengthOverflowError()

Constructs a LengthOverflowError with the default message.

LengthOverflowError(const char *msg)

Constructs a LengthOverflowError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class CapacityOverflowError : public cslt::MemoryError

Capacity limit exceeded error.

CapacityOverflowError represents an error when a capacity policy or representable limit is exceeded.

Example Usage:
throw CapacityOverflowError();  // "Capacity limit exceeded"
throw CapacityOverflowError("Container capacity cannot exceed 65535 elements");

Public Functions

CapacityOverflowError()

Constructs a CapacityOverflowError with the default message.

CapacityOverflowError(const char *msg)

Constructs a CapacityOverflowError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class AlignmentError : public cslt::MemoryError

Memory alignment requirement error.

AlignmentError represents an error when required memory alignment is not satisfied.

Example Usage:
throw AlignmentError();  // "Required alignment not satisfied"
throw AlignmentError("Pointer must be 16-byte aligned for SIMD operations");

Public Functions

AlignmentError()

Constructs an AlignmentError with the default message.

AlignmentError(const char *msg)

Constructs an AlignmentError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

State and Container Errors

class StateError : public cslt::Error

State and container management errors.

StateError represents errors related to invalid object states, corruption, initialization issues, and container operations.

Example Usage:
// Using default message
throw StateError();  // "Invalid state"

// Using custom message
throw StateError("Container already initialized");

Subclassed by cslt::AlreadyInitializedError, cslt::ConcurrentModificationError, cslt::EmptyError, cslt::NotFoundError, cslt::StateCorruptError

Public Functions

StateError()

Constructs a StateError with the default message.

Creates a StateError with the predefined message “Invalid state”.

StateError(const char *msg)

Constructs a StateError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Specific StateError Types:

class StateCorruptError : public cslt::StateError

Internal state corruption error.

StateCorruptError represents an error when internal invariants are violated or data corruption is detected.

Example Usage:
throw StateCorruptError();  // "Internal state corrupt"
throw StateCorruptError("Checksum mismatch: data corruption detected");

Public Functions

StateCorruptError()

Constructs a StateCorruptError with the default message.

StateCorruptError(const char *msg)

Constructs a StateCorruptError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class AlreadyInitializedError : public cslt::StateError

Already initialized error.

AlreadyInitializedError represents an error when attempting to initialize an object that has already been initialized (double-initialization).

Example Usage:
throw AlreadyInitializedError();  // "Already initialized"
throw AlreadyInitializedError("Cannot reinitialize active connection");

Public Functions

AlreadyInitializedError()

Constructs an AlreadyInitializedError with the default message.

AlreadyInitializedError(const char *msg)

Constructs an AlreadyInitializedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class NotFoundError : public cslt::StateError

Item or key not found error.

NotFoundError represents an error when a requested item or key does not exist in a collection.

Example Usage:
throw NotFoundError();  // "Item not found"
throw NotFoundError("Key 'username' not found in dictionary");

Public Functions

NotFoundError()

Constructs a NotFoundError with the default message.

NotFoundError(const char *msg)

Constructs a NotFoundError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class EmptyError : public cslt::StateError

Container empty error.

EmptyError represents an error when attempting to access or remove elements from an empty container.

Example Usage:
throw EmptyError();  // "Container is empty"
throw EmptyError("Cannot pop from empty stack");

Public Functions

EmptyError()

Constructs an EmptyError with the default message.

EmptyError(const char *msg)

Constructs an EmptyError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class ConcurrentModificationError : public cslt::StateError

Concurrent modification detected error.

ConcurrentModificationError represents an error when a container is modified during iteration (fail-fast behavior).

Example Usage:
throw ConcurrentModificationError();  // "Concurrent modification detected"
throw ConcurrentModificationError("Container modified during iteration");

Public Functions

ConcurrentModificationError()

Constructs a ConcurrentModificationError with the default message.

ConcurrentModificationError(const char *msg)

Constructs a ConcurrentModificationError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Mathematical Computation Errors

class MathError : public cslt::Error

Mathematical and numerical computation errors.

MathError represents errors related to mathematical operations such as division by zero, matrix singularities, numeric overflow, and domain errors.

Example Usage:
// Using default message
throw MathError();  // "Mathematical error"

// Using custom message
throw MathError("Division by zero in computation");

Subclassed by cslt::DivByZeroError, cslt::DomainError, cslt::LossOfPrecisionError, cslt::NumericOverflowError, cslt::SingularMatrixError

Public Functions

MathError()

Constructs a MathError with the default message.

Creates a MathError with the predefined message “Mathematical error”.

MathError(const char *msg)

Constructs a MathError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Specific MathError Types:

class DivByZeroError : public cslt::MathError

Division by zero error.

DivByZeroError represents an error when attempting to divide by zero.

Example Usage:
throw DivByZeroError();  // "Division by zero"
throw DivByZeroError("Cannot divide 10 by 0");

Public Functions

DivByZeroError()

Constructs a DivByZeroError with the default message.

DivByZeroError(const char *msg)

Constructs a DivByZeroError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class SingularMatrixError : public cslt::MathError

Singular or non-invertible matrix error.

SingularMatrixError represents an error when attempting operations that require a non-singular matrix (e.g., matrix inversion, solving linear systems) but the matrix is singular.

Example Usage:
throw SingularMatrixError();  // "Singular/non-invertible matrix"
throw SingularMatrixError("Matrix determinant is zero, cannot invert");

Public Functions

SingularMatrixError()

Constructs a SingularMatrixError with the default message.

SingularMatrixError(const char *msg)

Constructs a SingularMatrixError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class NumericOverflowError : public cslt::MathError

Numeric overflow or underflow error.

NumericOverflowError represents an error when a numeric computation results in overflow (exceeds maximum) or underflow (below minimum representable value).

Example Usage:
throw NumericOverflowError();  // "Numeric overflow/underflow"
throw NumericOverflowError("Result exceeds maximum double value");

Public Functions

NumericOverflowError()

Constructs a NumericOverflowError with the default message.

NumericOverflowError(const char *msg)

Constructs a NumericOverflowError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class DomainError : public cslt::MathError

Mathematical domain error.

DomainError represents an error when an input value is outside the valid domain for a mathematical function (e.g., negative input to square root, log of negative number).

Example Usage:
throw DomainError();  // "Math domain error"
throw DomainError("Cannot compute sqrt of negative number: -4");

Public Functions

DomainError()

Constructs a DomainError with the default message.

DomainError(const char *msg)

Constructs a DomainError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class LossOfPrecisionError : public cslt::MathError

Loss of numeric precision error.

LossOfPrecisionError represents an error when a computation results in excessive loss of precision or numerical instability.

Example Usage:
throw LossOfPrecisionError();  // "Loss of numeric precision"
throw LossOfPrecisionError("Ill-conditioned matrix: condition number > 1e15");

Public Functions

LossOfPrecisionError()

Constructs a LossOfPrecisionError with the default message.

LossOfPrecisionError(const char *msg)

Constructs a LossOfPrecisionError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Input/Output Errors

class IOError : public cslt::Error

File and I/O operation errors.

IOError represents errors related to file operations, reading, writing, permissions, timeouts, and other I/O operations.

Example Usage:
// Using default message
throw IOError();  // "I/O operation failed"

// Using custom message
throw IOError("Failed to open file: config.txt");

Subclassed by cslt::FileOpenError, cslt::FileReadError, cslt::FileWriteError, cslt::IOClosedError, cslt::IOInterruptedError, cslt::IOTimeoutError, cslt::IOWouldBlockError, cslt::PermissionDeniedError

Public Functions

IOError()

Constructs an IOError with the default message.

Creates an IOError with the predefined message “I/O operation failed”.

IOError(const char *msg)

Constructs an IOError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Specific IOError Types:

class FileOpenError : public cslt::IOError

File or handle open failure error.

FileOpenError represents an error when attempting to open a file or handle fails.

Example Usage:
throw FileOpenError();  // "Failed to open file/handle"
throw FileOpenError("Cannot open config.txt: file does not exist");

Public Functions

FileOpenError()

Constructs a FileOpenError with the default message.

FileOpenError(const char *msg)

Constructs a FileOpenError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class FileReadError : public cslt::IOError

File or handle read error.

FileReadError represents an error when reading from a file or handle fails.

Example Usage:
throw FileReadError();  // "Error reading from file/handle"
throw FileReadError("Read operation failed after 512 bytes");

Public Functions

FileReadError()

Constructs a FileReadError with the default message.

FileReadError(const char *msg)

Constructs a FileReadError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class FileWriteError : public cslt::IOError

File or handle write error.

FileWriteError represents an error when writing to a file or handle fails.

Example Usage:
throw FileWriteError();  // "Error writing to file/handle"
throw FileWriteError("Disk full: cannot write data");

Public Functions

FileWriteError()

Constructs a FileWriteError with the default message.

FileWriteError(const char *msg)

Constructs a FileWriteError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class PermissionDeniedError : public cslt::IOError

Permission denied error.

PermissionDeniedError represents an error when access control or permission restrictions prevent an operation.

Example Usage:
throw PermissionDeniedError();  // "Permission denied"
throw PermissionDeniedError("No write access to /etc/config");

Public Functions

PermissionDeniedError()

Constructs a PermissionDeniedError with the default message.

PermissionDeniedError(const char *msg)

Constructs a PermissionDeniedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class IOInterruptedError : public cslt::IOError

I/O operation interrupted error.

IOInterruptedError represents an error when an I/O operation is interrupted (e.g., by a signal like EINTR).

Example Usage:
throw IOInterruptedError();  // "I/O interrupted"
throw IOInterruptedError("Read interrupted by signal");

Public Functions

IOInterruptedError()

Constructs an IOInterruptedError with the default message.

IOInterruptedError(const char *msg)

Constructs an IOInterruptedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class IOTimeoutError : public cslt::IOError

I/O operation timeout error.

IOTimeoutError represents an error when an I/O operation exceeds its timeout period.

Example Usage:
throw IOTimeoutError();  // "I/O timed out"
throw IOTimeoutError("Network read timed out after 30 seconds");

Public Functions

IOTimeoutError()

Constructs an IOTimeoutError with the default message.

IOTimeoutError(const char *msg)

Constructs an IOTimeoutError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class IOClosedError : public cslt::IOError

Operation on closed stream or descriptor error.

IOClosedError represents an error when attempting an operation on a closed file descriptor or stream.

Example Usage:
throw IOClosedError();  // "Operation on closed stream/descriptor"
throw IOClosedError("Cannot read from closed socket");

Public Functions

IOClosedError()

Constructs an IOClosedError with the default message.

IOClosedError(const char *msg)

Constructs an IOClosedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class IOWouldBlockError : public cslt::IOError

Non-blocking operation would block error.

IOWouldBlockError represents an error when a non-blocking I/O operation would block (EWOULDBLOCK/EAGAIN).

Example Usage:
throw IOWouldBlockError();  // "Operation would block"
throw IOWouldBlockError("Socket read would block in non-blocking mode");

Public Functions

IOWouldBlockError()

Constructs an IOWouldBlockError with the default message.

IOWouldBlockError(const char *msg)

Constructs an IOWouldBlockError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Format and Encoding Errors

class FormatError : public cslt::Error

Type, format, and encoding errors.

FormatError represents errors related to type mismatches, invalid data formats, encoding issues, parsing failures, and validation errors.

Example Usage:
// Using default message
throw FormatError();  // "Format error"

// Using custom message
throw FormatError("Invalid JSON format at line 42");

Subclassed by cslt::EncodingInvalidError, cslt::FormatInvalidError, cslt::ParsingFailedError, cslt::TypeMismatchError, cslt::ValidationFailedError

Public Functions

FormatError()

Constructs a FormatError with the default message.

Creates a FormatError with the predefined message “Format error”.

FormatError(const char *msg)

Constructs a FormatError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Specific FormatError Types:

class TypeMismatchError : public cslt::FormatError

Type mismatch error.

TypeMismatchError represents an error where a value or object does not match the expected type.

Example Usage:
throw TypeMismatchError();  
throw TypeMismatchError("Expected integer but received string");

Public Functions

TypeMismatchError()

Constructs a TypeMismatchError with the default message.

TypeMismatchError(const char *msg)

Constructs a TypeMismatchError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class FormatInvalidError : public cslt::FormatError

Invalid format error.

FormatInvalidError represents an error where data does not conform to the expected format or structure.

Example Usage:
throw FormatInvalidError();
throw FormatInvalidError("Malformed header detected");

Public Functions

FormatInvalidError()

Constructs a FormatInvalidError with the default message.

FormatInvalidError(const char *msg)

Constructs a FormatInvalidError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class EncodingInvalidError : public cslt::FormatError

Invalid encoding error.

EncodingInvalidError represents an error where text or binary data is not encoded using a supported or expected encoding.

Example Usage:
throw EncodingInvalidError();
throw EncodingInvalidError("UTF-8 decoding failed");

Public Functions

EncodingInvalidError()

Constructs an EncodingInvalidError with the default message.

EncodingInvalidError(const char *msg)

Constructs an EncodingInvalidError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class ParsingFailedError : public cslt::FormatError

Parsing failure error.

ParsingFailedError represents an error that occurs when structured input cannot be successfully parsed.

Example Usage:
throw ParsingFailedError();
throw ParsingFailedError("JSON parsing failed at line 12");

Public Functions

ParsingFailedError()

Constructs a ParsingFailedError with the default message.

ParsingFailedError(const char *msg)

Constructs a ParsingFailedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class ValidationFailedError : public cslt::FormatError

Validation failure error.

ValidationFailedError represents an error where data is syntactically correct but fails semantic or rule-based validation.

Example Usage:
throw ValidationFailedError();
throw ValidationFailedError("Checksum validation failed");

Public Functions

ValidationFailedError()

Constructs a ValidationFailedError with the default message.

ValidationFailedError(const char *msg)

Constructs a ValidationFailedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Concurrency and Synchronization Errors

class ConcurrencyError : public cslt::Error

Concurrency and synchronization errors.

ConcurrencyError represents errors related to locking, deadlocks, thread operations, cancellations, and race conditions.

Example Usage:
// Using default message
throw ConcurrencyError();  // "Concurrency error"

// Using custom message
throw ConcurrencyError("Deadlock detected in mutex acquisition");

Subclassed by cslt::CancelledError, cslt::DeadlockDetectedError, cslt::LockFailedError, cslt::RaceDetectedError, cslt::ThreadFailError

Public Functions

ConcurrencyError()

Constructs a ConcurrencyError with the default message.

Creates a ConcurrencyError with the predefined message “Concurrency error”.

ConcurrencyError(const char *msg)

Constructs a ConcurrencyError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Specific ConcurrencyError Types:

class LockFailedError : public cslt::ConcurrencyError

Lock operation failure error.

LockFailedError represents an error where a mutex, spinlock, or other synchronization primitive fails to acquire or release.

Example Usage:
throw LockFailedError();
throw LockFailedError("Failed to acquire mutex");

Public Functions

LockFailedError()

Constructs a LockFailedError with the default message.

LockFailedError(const char *msg)

Constructs a LockFailedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class DeadlockDetectedError : public cslt::ConcurrencyError

Deadlock detection error.

DeadlockDetectedError represents an error where a deadlock condition has been detected between concurrent execution contexts.

Example Usage:
throw DeadlockDetectedError();
throw DeadlockDetectedError("Deadlock detected between worker threads");

Public Functions

DeadlockDetectedError()

Constructs a DeadlockDetectedError with the default message.

DeadlockDetectedError(const char *msg)

Constructs a DeadlockDetectedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class ThreadFailError : public cslt::ConcurrencyError

Thread operation failure error.

ThreadFailError represents an error where a thread could not be created, joined, or otherwise managed correctly.

Example Usage:
throw ThreadFailError();
throw ThreadFailError("Thread creation failed");

Public Functions

ThreadFailError()

Constructs a ThreadFailError with the default message.

ThreadFailError(const char *msg)

Constructs a ThreadFailError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class CancelledError : public cslt::ConcurrencyError

Operation cancelled error.

CancelledError represents an error where an operation was intentionally cancelled before completion.

Example Usage:
throw CancelledError();
throw CancelledError("Operation cancelled by user request");

Public Functions

CancelledError()

Constructs a CancelledError with the default message.

CancelledError(const char *msg)

Constructs a CancelledError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class RaceDetectedError : public cslt::ConcurrencyError

Data race detection error.

RaceDetectedError represents an error where a data race has been detected during concurrent execution.

Example Usage:
throw RaceDetectedError();
throw RaceDetectedError("Concurrent write detected on shared buffer");

Public Functions

RaceDetectedError()

Constructs a RaceDetectedError with the default message.

RaceDetectedError(const char *msg)

Constructs a RaceDetectedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Configuration and Environment Errors

class ConfigError : public cslt::Error

Configuration, policy, and environment errors.

ConfigError represents errors related to invalid configurations, unsupported features, version mismatches, and resource exhaustion.

Example Usage:
// Using default message
throw ConfigError();  // "Configuration error"

// Using custom message
throw ConfigError("Unsupported platform: ARM64");

Subclassed by cslt::ConfigInvalidError, cslt::FeatureDisabledError, cslt::ResourceExhaustedError, cslt::UnsupportedError, cslt::VersionMismatchError

Public Functions

ConfigError()

Constructs a ConfigError with the default message.

Creates a ConfigError with the predefined message “Configuration error”.

ConfigError(const char *msg)

Constructs a ConfigError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Specific ConfigError Types:

class ConfigInvalidError : public cslt::ConfigError

Invalid configuration error.

ConfigInvalidError represents an error where a configuration is malformed, incomplete, or otherwise invalid.

Example Usage:
throw ConfigInvalidError();
throw ConfigInvalidError("Missing required configuration key");

Public Functions

ConfigInvalidError()

Constructs a ConfigInvalidError with the default message.

ConfigInvalidError(const char *msg)

Constructs a ConfigInvalidError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class UnsupportedError : public cslt::ConfigError

Unsupported feature or platform error.

UnsupportedError represents an error where a requested feature or platform is not supported by the current build or environment.

Example Usage:
throw UnsupportedError();
throw UnsupportedError("ARM platform not supported");

Public Functions

UnsupportedError()

Constructs an UnsupportedError with the default message.

UnsupportedError(const char *msg)

Constructs an UnsupportedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class FeatureDisabledError : public cslt::ConfigError

Feature disabled error.

FeatureDisabledError represents an error where a feature is explicitly disabled by build configuration or policy.

Example Usage:
throw FeatureDisabledError();
throw FeatureDisabledError("Feature disabled by security policy");

Public Functions

FeatureDisabledError()

Constructs a FeatureDisabledError with the default message.

FeatureDisabledError(const char *msg)

Constructs a FeatureDisabledError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class VersionMismatchError : public cslt::ConfigError

Version or ABI mismatch error.

VersionMismatchError represents an error where incompatible versions or ABIs are detected between components.

Example Usage:
throw VersionMismatchError();
throw VersionMismatchError("Library ABI version mismatch");

Public Functions

VersionMismatchError()

Constructs a VersionMismatchError with the default message.

VersionMismatchError(const char *msg)

Constructs a VersionMismatchError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class ResourceExhaustedError : public cslt::ConfigError

Resource exhaustion error.

ResourceExhaustedError represents an error where required system or application resources have been exhausted.

Example Usage:
throw ResourceExhaustedError();
throw ResourceExhaustedError("Out of file descriptors");

Public Functions

ResourceExhaustedError()

Constructs a ResourceExhaustedError with the default message.

ResourceExhaustedError(const char *msg)

Constructs a ResourceExhaustedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Generic and Fallback Errors

class GenericError : public cslt::Error

Generic and unspecified errors.

GenericError represents generic fallback errors including not-implemented functionality, unavailable operations, and unknown errors.

Example Usage:
// Using default message
throw GenericError();  // "An error occurred"

// Using custom message
throw GenericError("Feature not yet implemented");

Subclassed by cslt::NotImplementedError, cslt::OperationUnavailableError, cslt::UnknownError

Public Functions

GenericError()

Constructs a GenericError with the default message.

Creates a GenericError with the predefined message “An error occurred”.

GenericError(const char *msg)

Constructs a GenericError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Specific GenericError Types:

class NotImplementedError : public cslt::GenericError

Not implemented error.

NotImplementedError represents an error where a requested operation or feature has not yet been implemented.

Example Usage:
throw NotImplementedError();
throw NotImplementedError("Serialization not yet implemented");

Public Functions

NotImplementedError()

Constructs a NotImplementedError with the default message.

NotImplementedError(const char *msg)

Constructs a NotImplementedError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class OperationUnavailableError : public cslt::GenericError

Operation unavailable error.

OperationUnavailableError represents an error where an operation cannot be performed due to current system or application state.

Example Usage:
throw OperationUnavailableError();
throw OperationUnavailableError("Service unavailable during shutdown");

Public Functions

OperationUnavailableError()

Constructs an OperationUnavailableError with the default message.

OperationUnavailableError(const char *msg)

Constructs an OperationUnavailableError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

class UnknownError : public cslt::GenericError

Unknown error.

UnknownError represents an error where the underlying cause is unknown or could not be classified.

Example Usage:
throw UnknownError();
throw UnknownError("Unexpected failure occurred");

Public Functions

UnknownError()

Constructs an UnknownError with the default message.

UnknownError(const char *msg)

Constructs an UnknownError with a custom message.

Parameters:

msg – Custom null-terminated error message (max 255 characters)

Expected Class Overview

The cslt::Expected<T> template class provides a type-safe mechanism for representing computations that may either succeed with a value of type T or fail with a cslt::Error. Unlike traditional exception-based error handling, Expected<T> returns errors as values, making error handling explicit and predictable. This approach is particularly valuable in performance-critical code, embedded systems, real-time applications, and scenarios where exceptions are disabled or discouraged by coding standards like MISRA C++.

The Expected<T> class forces callers to explicitly acknowledge the possibility of failure before accessing a result. This “errors as values” paradigm eliminates hidden control flow, makes error propagation visible in the code, and enables the compiler to optimize more aggressively since there is no exception unwinding overhead. All storage is stack-based with no dynamic allocation, making behavior completely predictable and suitable for safety-critical applications.

Design Philosophy

Unlike std::expected from C++23, cslt::Expected<T> makes several opinionated design choices optimized for embedded and safety-critical environments:

Fixed Error Type

The error type is always cslt::Error (or any of its derived types), eliminating the need for a second template parameter. This ensures consistency across the library and simplifies error handling patterns.

Static Storage

Both the value and error are stored simultaneously in the structure, avoiding the complexity of union-based storage with placement new. While this uses more memory (sizeof(Expected<T>) == sizeof(bool) + sizeof(T) + sizeof(Error)), it provides:

  • Trivial copyability (compiler-generated copy/move operations work correctly)

  • No manual memory management or placement new

  • Simple, predictable behavior

  • Full MISRA C++ compliance

Explicit State Management

State transitions are performed through explicit setValue() and setError() methods rather than constructor overloads, making the code’s intent clearer and more auditable.

No Monadic Operations

The class intentionally omits monadic operations like and_then(), or_else(), and transform() to keep the interface minimal and predictable for embedded use cases.

Memory Layout and Performance

The Expected<T> class uses a straightforward memory layout:

template<typename T>
class Expected {
private:
    bool has_value_;    // 1 byte (+ padding)
    T value_;           // sizeof(T) bytes
    Error error_;       // 256 bytes (fixed buffer)
};

This results in:

sizeof(Expected<int>)     = 260 bytes
sizeof(Expected<double>)  = 264 bytes
sizeof(Expected<void*>)   = 264 bytes

While larger than a union-based approach, this design provides:

  • Zero dynamic allocation - All memory is on the stack

  • Predictable performance - No heap operations or cache misses

  • Simple debugging - Both value and error visible in debugger

  • Compiler optimization - Trivially copyable enables more optimizations

For most use cases, the memory overhead is negligible compared to the benefits of simplicity and safety.

Basic Usage

Creating an Expected result:

#include <cslt/Expected.hpp>

cslt::Expected<int> divide(int numerator, int denominator) {
    cslt::Expected<int> result;

    if (denominator == 0) {
        result.setError(cslt::DivByZeroError("Cannot divide by zero"));
        return result;
    }

    result.setValue(numerator / denominator);
    return result;
}

Checking and using the result:

cslt::Expected<int> result = divide(10, 2);

// Method 1: Check with hasValue() / hasError()
if (result.hasValue()) {
    printf("Result: %d\n", result.value());
} else {
    printf("Error: %s\n", result.error().what());
}

// Method 2: Use explicit bool conversion
if (result) {
    printf("Success: %d\n", result.value());
} else {
    fprintf(stderr, "Failed: %s\n", result.error().what());
}

// Method 3: Use valueOr() for a safe default
int safeValue = divide(10, 0).valueOr(-1);

Error Propagation Patterns

Manual Propagation

cslt::Expected<double> complexCalculation(int a, int b, int c) {
    cslt::Expected<int> step1 = divide(a, b);
    if (step1.hasError()) {
        cslt::Expected<double> result;
        result.setError(step1.error());
        return result;
    }

    cslt::Expected<int> step2 = divide(step1.value(), c);
    if (step2.hasError()) {
        cslt::Expected<double> result;
        result.setError(step2.error());
        return result;
    }

    cslt::Expected<double> result;
    result.setValue(static_cast<double>(step2.value()));
    return result;
}

Early Return Pattern

cslt::Expected<int> processData(int* data, size_t size, size_t index) {
    cslt::Expected<int> result;

    if (data == nullptr) {
        result.setError(cslt::NullPointerError("Data pointer is null"));
        return result;
    }

    if (index >= size) {
        result.setError(cslt::OutOfBoundsError("Index out of range"));
        return result;
    }

    if (size == 0) {
        result.setError(cslt::EmptyError("Data array is empty"));
        return result;
    }

    // All checks passed, return the value
    result.setValue(data[index]);
    return result;
}

When to Use Expected vs Exceptions

Use Expected<T> when:

  • Performance is critical - No exception unwinding overhead

  • Errors are expected - Function commonly returns errors as part of normal operation

  • Deep call stacks - Returning errors is faster than unwinding many stack frames

  • MISRA compliance required - Exceptions may be forbidden

  • Embedded systems - Predictable memory usage and no heap allocation needed

  • Real-time systems - Deterministic execution time is required

  • Error recovery - Caller needs detailed error information to recover

Use throw Error when:

  • Errors are exceptional - Failure indicates a bug or very rare condition

  • Simplicity matters - Exception handling keeps error paths out of normal code flow

  • Deep stack unwinding needed - Need automatic cleanup via destructors (RAII)

  • Multiple error points - Many potential failure points that would clutter return checking

  • Standard C++ environment - Exceptions enabled and expected by ecosystem

  • Library integration - Interoperating with code that expects exceptions

Comparison Table

Aspect

Expected<T>

throw Error

Performance

Faster (no unwinding)

Slower (stack unwinding)

Memory

Stack only, predictable

May use heap for exception objects

Visibility

Explicit in signatures

Hidden (not in signature)

Error handling

Mandatory checking

Can be forgotten

Control flow

Explicit returns

Non-local jumps

MISRA compliance

✓ Compliant

✗ Often forbidden

Real-time systems

✓ Deterministic

✗ Non-deterministic

Code complexity

More verbose

Cleaner normal path

API Reference

template<typename T>
class Expected

A type that represents either a value of type T or an Error.

Expected<T> stores both the value and error in a fixed-size structure. No dynamic allocation is used - all storage is static.

Example Usage:
Expected<int> divide(int a, int b) {
    Expected<int> result;
    if (b == 0) {
        result.setError(DivByZeroError());
        return result;
    }
    result.setValue(a / b);
    return result;
}

Expected<int> result = divide(10, 2);
if (result.hasValue()) {
    printf("Result: %d\n", result.value());
} else {
    printf("Error: %s\n", result.error().what());
}

Template Parameters:

T – The type of the expected value

Public Functions

inline Expected()

Default constructor - initializes with no value and generic error.

inline void setValue(const T &val)

Sets the value by copy and marks this as containing a value.

Parameters:

val – The value to store

inline void setValue(T &&val)

Sets the value by move and marks this as containing a value.

Parameters:

val – The value to move

inline void setError(const Error &err)

Sets the error and marks this as containing an error.

Parameters:

err – The error to store

inline bool hasValue() const

Checks if the Expected contains a value.

Returns:

true if contains a value, false if contains an error

inline bool hasError() const

Checks if the Expected contains an error.

Returns:

true if contains an error, false if contains a value

inline T &value()

Gets the contained value.

Behavior is undefined if the Expected contains an error. Use hasValue() to check before calling this method.

Returns:

Reference to the contained value

inline const T &value() const

Gets the contained value (const version).

Behavior is undefined if the Expected contains an error. Use hasValue() to check before calling this method.

Returns:

Const reference to the contained value

inline Error &error()

Gets the contained error.

Behavior is undefined if the Expected contains a value. Use hasError() to check before calling this method.

Returns:

Reference to the contained error

inline const Error &error() const

Gets the contained error (const version).

Behavior is undefined if the Expected contains a value. Use hasError() to check before calling this method.

Returns:

Const reference to the contained error

inline T valueOr(T &&default_val) const

Gets the value or a default if error.

Parameters:

default_val – The default value to return if this contains an error

Returns:

The contained value if present, otherwise default_val

inline explicit operator bool() const

Conversion to bool (checks if has value).

Returns:

true if contains a value, false if contains an error

Complete Example

Here’s a complete example demonstrating Expected<T> in a realistic scenario:

#include <cslt/Expected.hpp>
#include <cslt/Error.hpp>
#include <cstdio>

// Safe array access with detailed error reporting
cslt::Expected<int> getArrayElement(int* array, size_t size, size_t index) {
    cslt::Expected<int> result;

    // Validate input
    if (array == nullptr) {
        result.setError(cslt::NullPointerError("Array pointer is null"));
        return result;
    }

    if (size == 0) {
        result.setError(cslt::EmptyError("Array is empty"));
        return result;
    }

    if (index >= size) {
        result.setError(cslt::OutOfBoundsError("Index exceeds array bounds"));
        return result;
    }

    // Success path
    result.setValue(array[index]);
    return result;
}

// Chain multiple operations
cslt::Expected<double> calculateAverage(int* array, size_t size) {
    cslt::Expected<double> result;

    if (size == 0) {
        result.setError(cslt::EmptyError("Cannot average empty array"));
        return result;
    }

    int sum = 0;
    for (size_t i = 0; i < size; ++i) {
        cslt::Expected<int> elem = getArrayElement(array, size, i);
        if (elem.hasError()) {
            result.setError(elem.error());
            return result;
        }
        sum += elem.value();
    }

    result.setValue(static_cast<double>(sum) / size);
    return result;
}

int main() {
    int data[] = {10, 20, 30, 40, 50};

    // Example 1: Successful access
    cslt::Expected<int> elem = getArrayElement(data, 5, 2);
    if (elem.hasValue()) {
        printf("Element at index 2: %d\n", elem.value());
    } else {
        fprintf(stderr, "Error: %s\n", elem.error().what());
    }

    // Example 2: Out of bounds
    cslt::Expected<int> invalid = getArrayElement(data, 5, 10);
    if (invalid.hasError()) {
        fprintf(stderr, "Expected error: %s\n", invalid.error().what());
    }

    // Example 3: Chained operations
    cslt::Expected<double> avg = calculateAverage(data, 5);
    if (avg.hasValue()) {
        printf("Average: %.2f\n", avg.value());
    } else {
        fprintf(stderr, "Failed to calculate average: %s\n", avg.error().what());
    }

    // Example 4: Using valueOr for defaults
    int safeValue = getArrayElement(nullptr, 0, 0).valueOr(-1);
    printf("Safe value with default: %d\n", safeValue);

    return 0;
}

Integration with Error Hierarchy

Expected<T> works seamlessly with the entire cslt::Error hierarchy. You can set any error type, and the polymorphic behavior is preserved:

cslt::Expected<double> safeSqrt(double x) {
    cslt::Expected<double> result;

    if (x < 0.0) {
        // Use specific error type
        result.setError(cslt::DomainError("Cannot compute sqrt of negative number"));
        return result;
    }

    result.setValue(sqrt(x));
    return result;
}

// Caller can catch specific or general errors
cslt::Expected<double> res = safeSqrt(-4.0);
if (res.hasError()) {
    // Can check error type
    printf("Error: %s\n", res.error().what());

    // The error object is polymorphic - it's actually a DomainError
    // but accessible through the Error interface
}

isInstance Overview

template<typename ErrorType>
bool cslt::isinstance(const Error &err)

Checks if an error object is an instance of a specific error type.

This function performs runtime type checking to determine if an error is of a specific type or derived from that type. It uses dynamic_cast internally, so it works with the polymorphic error hierarchy.

Example Usage:
Expected<int> result = someFunction();
if (result.hasError()) {
    if (isinstance<ArgumentError>(result.error())) {
        // Handle argument errors
    } else if (isinstance<MemoryError>(result.error())) {
        // Handle memory errors
    }
}

Template Parameters:

ErrorType – The error type to check against (e.g., ArgumentError)

Parameters:

err – Reference to the error object to check

Returns:

true if err is an instance of ErrorType or derived from it