aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/CMakeLists.txt2
-rw-r--r--kernel/kernel/filesystem/error.cpp103
-rw-r--r--kernel/kernel/filesystem/error.hpp94
-rw-r--r--kernel/kernel/filesystem/ext2/error.cpp92
-rw-r--r--kernel/kernel/filesystem/ext2/error.hpp81
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.cpp2
-rw-r--r--libs/kstd/CMakeLists.txt1
-rw-r--r--libs/kstd/kstd/system_error.cpp233
-rw-r--r--libs/kstd/kstd/system_error.hpp254
9 files changed, 463 insertions, 399 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index 1f7f66c4..7ada841d 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -47,6 +47,7 @@ target_sources("kernel_lib" PRIVATE
# Filesystem Subsystem
"kernel/filesystem/dentry.cpp"
"kernel/filesystem/device_inode.cpp"
+ "kernel/filesystem/error.cpp"
"kernel/filesystem/filesystem.cpp"
"kernel/filesystem/inode.cpp"
"kernel/filesystem/mount_table.cpp"
@@ -61,6 +62,7 @@ target_sources("kernel_lib" PRIVATE
"kernel/filesystem/devfs/inode.cpp"
# ext2 Filesystem
+ "kernel/filesystem/ext2/error.cpp"
"kernel/filesystem/ext2/filesystem.cpp"
"kernel/filesystem/ext2/inode.cpp"
diff --git a/kernel/kernel/filesystem/error.cpp b/kernel/kernel/filesystem/error.cpp
new file mode 100644
index 00000000..5512a5af
--- /dev/null
+++ b/kernel/kernel/filesystem/error.cpp
@@ -0,0 +1,103 @@
+#include <kernel/filesystem/error.hpp>
+
+#include <kstd/system_error.hpp>
+
+#include <string_view>
+
+namespace kernel::filesystem
+{
+
+ namespace
+ {
+ struct vfs_category_t final : kstd::error_category
+ {
+ [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
+ {
+ return "vfs";
+ }
+
+ [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
+ {
+ switch (static_cast<vfs_errc>(value))
+ {
+ case vfs_errc::invalid_path:
+ return "invalid path";
+ case vfs_errc::no_such_file_or_directory:
+ return "no such file or directory";
+ case vfs_errc::mount_point_not_found:
+ return "mount point not found";
+ case vfs_errc::mount_busy:
+ return "mount point is busy";
+ case vfs_errc::has_child_mounts:
+ return "mount point has child mounts";
+ case vfs_errc::invalid_filesystem:
+ return "invalid filesystem";
+ case vfs_errc::unmount_failed:
+ return "unmount failed";
+ case vfs_errc::too_many_symbolic_link_levels:
+ return "too many symbolic link levels";
+ case vfs_errc::unsupported_filesystem:
+ return "unsupported filesystem";
+ case vfs_errc::invalid_file_descriptor:
+ return "invalid file descriptor";
+ case vfs_errc::invalid_inode:
+ return "invalid inode";
+ case vfs_errc::not_a_directory:
+ return "not a directory";
+ case vfs_errc::is_a_directory:
+ return "is a directory";
+ case vfs_errc::read_only_file_system:
+ return "readonly filesystem";
+ case vfs_errc::file_exists:
+ return "file already exists";
+ case vfs_errc::no_such_device:
+ return "no such device";
+ default:
+ return "unknown VFS error";
+ }
+ }
+
+ [[nodiscard]] constexpr auto default_error_condition(int value) const noexcept -> kstd::error_condition override
+ {
+ switch (static_cast<vfs_errc>(value))
+ {
+ case vfs_errc::invalid_path:
+ case vfs_errc::invalid_filesystem:
+ case vfs_errc::invalid_inode:
+ return make_error_condition(kstd::errc::invalid_argument);
+ case vfs_errc::no_such_file_or_directory:
+ case vfs_errc::mount_point_not_found:
+ return make_error_condition(kstd::errc::no_such_file_or_directory);
+ case kernel::filesystem::vfs_errc::mount_busy:
+ case kernel::filesystem::vfs_errc::has_child_mounts:
+ case vfs_errc::unmount_failed:
+ return make_error_condition(kstd::errc::device_or_resource_busy);
+ case vfs_errc::too_many_symbolic_link_levels:
+ return make_error_condition(kstd::errc::too_many_symbolic_link_levels);
+ case vfs_errc::unsupported_filesystem:
+ return make_error_condition(kstd::errc::not_supported);
+ case vfs_errc::invalid_file_descriptor:
+ return make_error_condition(kstd::errc::bad_file_descriptor);
+ case vfs_errc::not_a_directory:
+ return make_error_condition(kstd::errc::not_a_directory);
+ case vfs_errc::is_a_directory:
+ return make_error_condition(kstd::errc::is_a_directory);
+ case vfs_errc::read_only_file_system:
+ return make_error_condition(kstd::errc::read_only_file_system);
+ case vfs_errc::file_exists:
+ return make_error_condition(kstd::errc::file_exists);
+ case vfs_errc::no_such_device:
+ return make_error_condition(kstd::errc::no_such_device);
+ default:
+ return kstd::error_condition{value, *this};
+ }
+ }
+ } constexpr vfs_category_instance{};
+ } // namespace
+
+ [[nodiscard]] auto vfs_category() noexcept -> kstd::error_category const &
+ {
+ return vfs_category_instance;
+ }
+
+} // namespace kernel::filesystem
diff --git a/kernel/kernel/filesystem/error.hpp b/kernel/kernel/filesystem/error.hpp
index 286d7a24..8c9d9e0b 100644
--- a/kernel/kernel/filesystem/error.hpp
+++ b/kernel/kernel/filesystem/error.hpp
@@ -3,7 +3,6 @@
#include <kstd/system_error.hpp>
-#include <string_view>
#include <type_traits>
namespace kernel::filesystem
@@ -29,98 +28,7 @@ namespace kernel::filesystem
no_such_device,
};
- namespace detail
- {
- struct vfs_category_t final : kstd::error_category
- {
- [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
- {
- return "vfs";
- }
-
- [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
- {
- switch (static_cast<vfs_errc>(value))
- {
- case vfs_errc::invalid_path:
- return "invalid path";
- case vfs_errc::no_such_file_or_directory:
- return "no such file or directory";
- case vfs_errc::mount_point_not_found:
- return "mount point not found";
- case vfs_errc::mount_busy:
- return "mount point is busy";
- case vfs_errc::has_child_mounts:
- return "mount point has child mounts";
- case vfs_errc::invalid_filesystem:
- return "invalid filesystem";
- case vfs_errc::unmount_failed:
- return "unmount failed";
- case vfs_errc::too_many_symbolic_link_levels:
- return "too many symbolic link levels";
- case vfs_errc::unsupported_filesystem:
- return "unsupported filesystem";
- case vfs_errc::invalid_file_descriptor:
- return "invalid file descriptor";
- case vfs_errc::invalid_inode:
- return "invalid inode";
- case vfs_errc::not_a_directory:
- return "not a directory";
- case vfs_errc::is_a_directory:
- return "is a directory";
- case vfs_errc::read_only_file_system:
- return "readonly filesystem";
- case vfs_errc::file_exists:
- return "file already exists";
- case vfs_errc::no_such_device:
- return "no such device";
- default:
- return "unknown VFS error";
- }
- }
-
- [[nodiscard]] constexpr auto default_error_condition(int value) const noexcept -> kstd::error_condition override
- {
- switch (static_cast<vfs_errc>(value))
- {
- case vfs_errc::invalid_path:
- case vfs_errc::invalid_filesystem:
- case vfs_errc::invalid_inode:
- return make_error_condition(kstd::errc::invalid_argument);
- case vfs_errc::no_such_file_or_directory:
- case vfs_errc::mount_point_not_found:
- return make_error_condition(kstd::errc::no_such_file_or_directory);
- case kernel::filesystem::vfs_errc::mount_busy:
- case kernel::filesystem::vfs_errc::has_child_mounts:
- case vfs_errc::unmount_failed:
- return make_error_condition(kstd::errc::device_or_resource_busy);
- case vfs_errc::too_many_symbolic_link_levels:
- return make_error_condition(kstd::errc::too_many_symbolic_link_levels);
- case vfs_errc::unsupported_filesystem:
- return make_error_condition(kstd::errc::not_supported);
- case vfs_errc::invalid_file_descriptor:
- return make_error_condition(kstd::errc::bad_file_descriptor);
- case vfs_errc::not_a_directory:
- return make_error_condition(kstd::errc::not_a_directory);
- case vfs_errc::is_a_directory:
- return make_error_condition(kstd::errc::is_a_directory);
- case vfs_errc::read_only_file_system:
- return make_error_condition(kstd::errc::read_only_file_system);
- case vfs_errc::file_exists:
- return make_error_condition(kstd::errc::file_exists);
- case vfs_errc::no_such_device:
- return make_error_condition(kstd::errc::no_such_device);
- default:
- return kstd::error_condition{value, *this};
- }
- }
- } constexpr inline vfs_category_instance{};
- } // namespace detail
-
- [[nodiscard]] constexpr auto inline vfs_category() noexcept -> kstd::error_category const &
- {
- return detail::vfs_category_instance;
- }
+ [[nodiscard]] auto vfs_category() noexcept -> kstd::error_category const &;
[[nodiscard]] constexpr auto inline make_error_code(vfs_errc error) noexcept -> kstd::error_code
{
diff --git a/kernel/kernel/filesystem/ext2/error.cpp b/kernel/kernel/filesystem/ext2/error.cpp
new file mode 100644
index 00000000..1da4ef36
--- /dev/null
+++ b/kernel/kernel/filesystem/ext2/error.cpp
@@ -0,0 +1,92 @@
+#include <kernel/filesystem/ext2/error.hpp>
+
+#include <kernel/filesystem/error.hpp>
+
+#include <kstd/system_error.hpp>
+
+#include <string_view>
+
+namespace kernel::filesystem::ext2
+{
+
+ namespace
+ {
+ struct ext2_category_t final : kstd::error_category
+ {
+ [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
+ {
+ return "ext2";
+ }
+
+ [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
+ {
+ switch (static_cast<ext2_errc>(value))
+ {
+ case ext2_errc::invalid_magic_number:
+ return "invalid filesystem magic";
+ case ext2_errc::invalid_root_inode:
+ return "invalid root inode";
+ case ext2_errc::invalid_block_group_index:
+ return "block group index out of bounds";
+ case ext2_errc::invalid_block_index:
+ return "block index out of bounds";
+ case ext2_errc::invalid_block_number:
+ return "block number out of bounds";
+ case ext2_errc::failed_to_read_superblock:
+ return "failed to read superblock";
+ case ext2_errc::failed_to_read_block_group_descriptors:
+ return "failed to read block group descriptors";
+ case ext2_errc::not_enough_free_blocks:
+ return "not enough free blocks";
+ case ext2_errc::not_enough_inodes:
+ return "not enough inodes";
+ default:
+ return "unknown ext2 error";
+ };
+ }
+
+ [[nodiscard]] constexpr auto equivalent(int code, kstd::error_condition const & condition) const noexcept
+ -> bool override
+ {
+ switch (static_cast<ext2_errc>(code))
+ {
+ case ext2_errc::invalid_magic_number:
+ case ext2_errc::invalid_root_inode:
+ if (condition.category() == kernel::filesystem::vfs_category())
+ {
+ return condition.value() == static_cast<int>(kernel::filesystem::vfs_errc::invalid_filesystem);
+ }
+ else if (condition.category() == kstd::generic_category())
+ {
+ return condition.value() == static_cast<int>(kstd::errc::invalid_argument);
+ }
+ break;
+ case ext2_errc::invalid_block_group_index:
+ case ext2_errc::invalid_block_index:
+ case ext2_errc::invalid_block_number:
+ case ext2_errc::failed_to_read_superblock:
+ case ext2_errc::failed_to_read_block_group_descriptors:
+ if (condition.category() == kstd::generic_category())
+ {
+ return condition.value() == static_cast<int>(kstd::errc::io_error);
+ }
+ break;
+ case ext2_errc::not_enough_free_blocks:
+ case ext2_errc::not_enough_inodes:
+ if (condition.category() == kstd::generic_category())
+ {
+ return condition.value() == static_cast<int>(kstd::errc::no_space_on_device);
+ }
+ break;
+ }
+ return kstd::error_category::equivalent(code, condition);
+ }
+ } constexpr inline ext2_category_instance{};
+ } // namespace
+
+ [[nodiscard]] auto ext2_category() noexcept -> kstd::error_category const &
+ {
+ return ext2_category_instance;
+ }
+
+} // namespace kernel::filesystem::ext2
diff --git a/kernel/kernel/filesystem/ext2/error.hpp b/kernel/kernel/filesystem/ext2/error.hpp
index 7de3b24b..dcdf7295 100644
--- a/kernel/kernel/filesystem/ext2/error.hpp
+++ b/kernel/kernel/filesystem/ext2/error.hpp
@@ -5,7 +5,6 @@
#include <kstd/system_error.hpp>
-#include <string_view>
#include <type_traits>
namespace kernel::filesystem::ext2
@@ -24,85 +23,7 @@ namespace kernel::filesystem::ext2
not_enough_inodes
};
- namespace detail
- {
- struct ext2_category_t final : kstd::error_category
- {
- [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
- {
- return "ext2";
- }
-
- [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
- {
- switch (static_cast<ext2_errc>(value))
- {
- case ext2_errc::invalid_magic_number:
- return "invalid filesystem magic";
- case ext2_errc::invalid_root_inode:
- return "invalid root inode";
- case ext2_errc::invalid_block_group_index:
- return "block group index out of bounds";
- case ext2_errc::invalid_block_index:
- return "block index out of bounds";
- case ext2_errc::invalid_block_number:
- return "block number out of bounds";
- case ext2_errc::failed_to_read_superblock:
- return "failed to read superblock";
- case ext2_errc::failed_to_read_block_group_descriptors:
- return "failed to read block group descriptors";
- case ext2_errc::not_enough_free_blocks:
- return "not enough free blocks";
- case ext2_errc::not_enough_inodes:
- return "not enough inodes";
- default:
- return "unknown ext2 error";
- };
- }
-
- [[nodiscard]] constexpr auto equivalent(int code, kstd::error_condition const & condition) const noexcept
- -> bool override
- {
- switch (static_cast<ext2_errc>(code))
- {
- case ext2_errc::invalid_magic_number:
- case ext2_errc::invalid_root_inode:
- if (condition.category() == kernel::filesystem::vfs_category())
- {
- return condition.value() == static_cast<int>(kernel::filesystem::vfs_errc::invalid_filesystem);
- }
- else if (condition.category() == kstd::generic_category())
- {
- return condition.value() == static_cast<int>(kstd::errc::invalid_argument);
- }
- break;
- case ext2_errc::invalid_block_group_index:
- case ext2_errc::invalid_block_index:
- case ext2_errc::invalid_block_number:
- case ext2_errc::failed_to_read_superblock:
- case ext2_errc::failed_to_read_block_group_descriptors:
- if (condition.category() == kstd::generic_category())
- {
- return condition.value() == static_cast<int>(kstd::errc::io_error);
- }
- break;
- case ext2_errc::not_enough_free_blocks:
- case ext2_errc::not_enough_inodes:
- if (condition.category() == kstd::generic_category())
- {
- return condition.value() == static_cast<int>(kstd::errc::no_space_on_device);
- }
- break;
- }
- return kstd::error_category::equivalent(code, condition);
- }
- } constexpr inline ext2_category_instance{};
- } // namespace detail
-
- [[nodiscard]] constexpr auto inline ext2_category() noexcept -> kstd::error_category const &
- {
- return detail::ext2_category_instance;
- }
+ [[nodiscard]] auto ext2_category() noexcept -> kstd::error_category const &;
[[nodiscard]] constexpr auto inline make_error_code(ext2_errc error) noexcept -> kstd::error_code
{
diff --git a/kernel/kernel/filesystem/open_file_descriptor.cpp b/kernel/kernel/filesystem/open_file_descriptor.cpp
index 6277d0b6..e233b5da 100644
--- a/kernel/kernel/filesystem/open_file_descriptor.cpp
+++ b/kernel/kernel/filesystem/open_file_descriptor.cpp
@@ -7,8 +7,6 @@
#include <kstd/result.hpp>
#include <kstd/units.hpp>
-#include <cstddef>
-
namespace kernel::filesystem
{
open_file_descriptor::open_file_descriptor(kstd::shared_ptr<dentry> const & dentry)
diff --git a/libs/kstd/CMakeLists.txt b/libs/kstd/CMakeLists.txt
index 9c68feed..e2b56d2f 100644
--- a/libs/kstd/CMakeLists.txt
+++ b/libs/kstd/CMakeLists.txt
@@ -18,6 +18,7 @@ add_library("kstd::lib" ALIAS "kstd")
target_sources("kstd" PRIVATE
"kstd/os/error.cpp"
"kstd/mutex.cpp"
+ "kstd/system_error.cpp"
"kstd/bits/format/vformat.cpp"
)
diff --git a/libs/kstd/kstd/system_error.cpp b/libs/kstd/kstd/system_error.cpp
new file mode 100644
index 00000000..8ecf40d7
--- /dev/null
+++ b/libs/kstd/kstd/system_error.cpp
@@ -0,0 +1,233 @@
+#include <kstd/system_error.hpp>
+
+#include <string_view>
+
+namespace kstd
+{
+
+ namespace
+ {
+ constexpr auto to_message(errc error) -> std::string_view
+ {
+ switch (error)
+ {
+ // clang-format off
+ case errc::address_family_not_supported: return "address family not supported";
+ case errc::address_in_use: return "address in use";
+ case errc::address_not_available: return "address not available";
+ case errc::already_connected: return "already connected";
+ case errc::argument_list_too_long: return "argument list too long";
+ case errc::argument_out_of_domain: return "argument out of domain";
+ case errc::bad_address: return "bad address";
+ case errc::bad_file_descriptor: return "bad file descriptor";
+ case errc::bad_message: return "bad message";
+ case errc::broken_pipe: return "broken pipe";
+ case errc::connection_aborted: return "connection aborted";
+ case errc::connection_already_in_progress: return "connection already in progress";
+ case errc::connection_refused: return "connection refused";
+ case errc::connection_reset: return "connection reset";
+ case errc::cross_device_link: return "cross device link";
+ case errc::destination_address_required: return "destination address required";
+ case errc::device_or_resource_busy: return "device or resource busy";
+ case errc::directory_not_empty: return "directory not empty";
+ case errc::executable_format_error: return "invalid executable format";
+ case errc::file_exists: return "file exists";
+ case errc::file_too_large: return "file too large";
+ case errc::filename_too_long: return "filename too long";
+ case errc::function_not_supported: return "function not supported";
+ case errc::host_unreachable: return "host unreachable";
+ case errc::identifier_removed: return "identifier removed";
+ case errc::illegal_byte_sequence: return "illegal byte sequence";
+ case errc::inappropriate_io_control_operation: return "inappropriate io control operation";
+ case errc::interrupted: return "system call interrupted";
+ case errc::invalid_argument: return "invalid argument";
+ case errc::invalid_seek: return "invalid seek";
+ case errc::io_error: return "input/output error";
+ case errc::is_a_directory: return "is a directory";
+ case errc::message_size: return "message size";
+ case errc::network_down: return "network down";
+ case errc::network_reset: return "network reset";
+ case errc::network_unreachable: return "network unreachable";
+ case errc::no_buffer_space: return "no buffer space";
+ case errc::no_child_process: return "no child process";
+ case errc::no_link: return "no link";
+ case errc::no_lock_available: return "no lock available";
+ case errc::no_message: return "no message";
+ case errc::no_protocol_option: return "no protocol option";
+ case errc::no_space_on_device: return "no space on device";
+ case errc::no_such_device: return "no such device";
+ case errc::no_such_device_or_address: return "no such device or address";
+ case errc::no_such_file_or_directory: return "no such file or directory";
+ case errc::no_such_process: return "no such process";
+ case errc::not_a_directory: return "not a directory";
+ case errc::not_a_socket: return "not a socket";
+ case errc::not_connected: return "not connected";
+ case errc::not_enough_memory: return "not enough memory";
+ case errc::not_supported: return "not supported";
+ case errc::operation_canceled: return "operation canceled";
+ case errc::operation_in_progress: return "operation in progress";
+ case errc::operation_not_permitted: return "operation not permitted";
+ case errc::operation_not_supported: return "operation not supported";
+ case errc::operation_would_block: return "operation would block";
+ case errc::owner_dead: return "owner dead";
+ case errc::permission_denied: return "permission denied";
+ case errc::protocol_error: return "protocol error";
+ case errc::protocol_not_supported: return "protocol not supported";
+ case errc::read_only_file_system: return "read only file system";
+ case errc::resource_deadlock_would_occur: return "resource deadlock would occur";
+ case errc::resource_unavailable_try_again: return "resource unavailable, try again";
+ case errc::result_out_of_range: return "result out of range";
+ case errc::state_not_recoverable: return "state not recoverable";
+ case errc::text_file_busy: return "text file busy";
+ case errc::timed_out: return "timed out";
+ case errc::too_many_files_open: return "too many files open";
+ case errc::too_many_files_open_in_system: return "too many files open in system";
+ case errc::too_many_links: return "too many links";
+ case errc::too_many_symbolic_link_levels: return "too many symbolic link levels";
+ case errc::value_too_large: return "value too large";
+ case errc::wrong_protocol_type: return "wrong protocol type";
+ default: return "unknown error";
+ // clang-format on
+ }
+ }
+
+ struct generic_category_t final : error_category
+ {
+ [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
+ {
+ return "generic";
+ }
+
+ [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
+ {
+ return to_message(static_cast<errc>(value));
+ }
+ } constexpr generic_category_instance{};
+
+ struct system_category_t final : error_category
+ {
+ [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
+ {
+ return "system";
+ }
+
+ [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
+ {
+ return to_message(static_cast<errc>(value));
+ }
+ } constexpr system_category_instance{};
+ } // namespace
+
+ auto generic_category() noexcept -> error_category const &
+ {
+ return generic_category_instance;
+ }
+
+ auto system_category() noexcept -> error_category const &
+ {
+ return system_category_instance;
+ }
+
+ error_condition::error_condition() noexcept
+ : m_value{0}
+ , m_category{&generic_category()}
+ {}
+
+ error_condition::error_condition(int value, error_category const & category) noexcept
+ : m_value{value}
+ , m_category{&category}
+ {}
+
+ auto error_category::default_error_condition(int value) const noexcept -> error_condition
+ {
+ return error_condition{value, *this};
+ }
+
+ auto error_category::equivalent(int value, error_condition const & other) const noexcept -> bool
+ {
+ return default_error_condition(value) == other;
+ }
+
+ auto error_category::equivalent(error_code const & code, int condition) const noexcept -> bool
+ {
+ return *this == code.category() && code.value() == condition;
+ }
+
+ auto error_condition::assign(int value, error_category const & category) noexcept -> void
+ {
+ m_value = value;
+ m_category = &category;
+ }
+
+ auto error_condition::clear() noexcept -> void
+ {
+ m_value = 0;
+ m_category = &generic_category();
+ }
+
+ [[nodiscard]] auto error_condition::value() const noexcept -> int
+ {
+ return m_value;
+ }
+
+ [[nodiscard]] auto error_condition::category() const noexcept -> error_category const &
+ {
+ return *m_category;
+ }
+
+ [[nodiscard]] auto error_condition::message() const noexcept -> std::string_view
+ {
+ return m_category->message(m_value);
+ }
+
+ error_code::error_code() noexcept
+ : error_code{0, system_category()} {};
+
+ error_code::error_code(int value, error_category const & category) noexcept
+ : m_value{value}
+ , m_category{&category}
+ {}
+
+ auto error_code::assign(int value, error_category const & category) noexcept -> void
+ {
+ m_value = value;
+ m_category = &category;
+ }
+
+ auto error_code::clear() noexcept -> void
+ {
+ m_value = 0;
+ m_category = &system_category();
+ }
+
+ auto error_code::value() const noexcept -> int
+ {
+ return m_value;
+ }
+
+ auto error_code::category() const noexcept -> error_category const &
+ {
+ return *m_category;
+ }
+
+ auto error_code::default_error_condition() const noexcept -> error_condition
+ {
+ return m_category->default_error_condition(m_value);
+ }
+
+ auto error_code::message() const noexcept -> std::string_view
+ {
+ return m_category->message(m_value);
+ }
+
+ auto make_error_code(errc const value) noexcept -> error_code
+ {
+ return {static_cast<int>(value), generic_category()};
+ }
+
+ auto make_error_condition(errc const value) noexcept -> error_condition
+ {
+ return {static_cast<int>(value), generic_category()};
+ }
+
+} // namespace kstd
diff --git a/libs/kstd/kstd/system_error.hpp b/libs/kstd/kstd/system_error.hpp
index 09efb097..d6e78ffe 100644
--- a/libs/kstd/kstd/system_error.hpp
+++ b/libs/kstd/kstd/system_error.hpp
@@ -95,33 +95,33 @@ namespace kstd
auto operator=(error_category const &) -> error_category & = delete;
//! Get the name of this error category.
- [[nodiscard]] constexpr auto virtual name() const noexcept -> std::string_view = 0;
+ [[nodiscard]] auto virtual name() const noexcept -> std::string_view = 0;
//! Get the default error condition for a given error code value in this category.
//!
//! @param value The error code value to get the default error condition for.
//! @return The default error condition for the given error code value in this category.
- [[nodiscard]] constexpr auto virtual default_error_condition(int value) const noexcept -> error_condition;
+ [[nodiscard]] auto virtual default_error_condition(int value) const noexcept -> error_condition;
//! Check if a given error code value is equivalent to a given error condition in this category.
//!
//! @param value The error code value to check.
//! @param other The error condition to compare against.
//! @return True if the error code value is equivalent to the error condition in this category, false otherwise.
- [[nodiscard]] constexpr auto virtual equivalent(int value, error_condition const & other) const noexcept -> bool;
+ [[nodiscard]] auto virtual equivalent(int value, error_condition const & other) const noexcept -> bool;
//! Check if a given error code is equivalent to a given error condition in this category.
//!
//! @param code The error code to check.
//! @param condition The error condition to compare against.
//! @return True if the error code is equivalent to the error condition in this category, false otherwise.
- [[nodiscard]] constexpr auto virtual equivalent(error_code const & code, int condition) const noexcept -> bool;
+ [[nodiscard]] auto virtual equivalent(error_code const & code, int condition) const noexcept -> bool;
//! Get the message for a given error code value in this category.
//!
//! @param value The error code value to get the message for.
//! @return The message for the given error code value in this category.
- [[nodiscard]] constexpr auto virtual message(int value) const noexcept -> std::string_view = 0;
+ [[nodiscard]] auto virtual message(int value) const noexcept -> std::string_view = 0;
//! Check if this error category is equal to another one.
[[nodiscard]] constexpr auto operator==(error_category const & other) const noexcept -> bool
@@ -142,16 +142,13 @@ namespace kstd
struct error_condition
{
//! Construct an error condition with a default value and category.
- constexpr error_condition() noexcept;
+ error_condition() noexcept;
//! Construct an error condition with a specific value and category.
//!
//! @param value The error code value.
//! @param category The error category.
- constexpr error_condition(int value, error_category const & category) noexcept
- : m_value{value}
- , m_category{&category}
- {}
+ error_condition(int value, error_category const & category) noexcept;
//! Construct an error condition from an error condition enumeration value.
//!
@@ -176,34 +173,21 @@ namespace kstd
//!
//! @param value The new error code value.
//! @param category The new error category.
- constexpr auto assign(int value, error_category const & category) noexcept -> void
- {
- m_value = value;
- m_category = &category;
- }
+ auto assign(int value, error_category const & category) noexcept -> void;
//! Clear this error condition.
//!
//! This sets the value to 0 and the category to the generic error category.
- constexpr auto clear() noexcept -> void;
+ auto clear() noexcept -> void;
//! Get the raw error code value of this error condition.
- [[nodiscard]] constexpr auto value() const noexcept -> int
- {
- return m_value;
- }
+ [[nodiscard]] auto value() const noexcept -> int;
//! Get the error category of this error condition.
- [[nodiscard]] constexpr auto category() const noexcept -> error_category const &
- {
- return *m_category;
- }
+ [[nodiscard]] auto category() const noexcept -> error_category const &;
//! Get the message associated with this error condition based on its value and category.
- [[nodiscard]] constexpr auto message() const noexcept -> std::string_view
- {
- return m_category->message(m_value);
- }
+ [[nodiscard]] auto message() const noexcept -> std::string_view;
//! Check if this error condition holds an error.
//!
@@ -246,13 +230,10 @@ namespace kstd
struct error_code
{
//! Construct an error code with a default value and category.
- constexpr error_code() noexcept;
+ error_code() noexcept;
//! Construct an error code with a specific value and category.
- constexpr error_code(int value, error_category const & category) noexcept
- : m_value{value}
- , m_category{&category}
- {}
+ error_code(int value, error_category const & category) noexcept;
//! Construct an error code from an error code enumeration value.
//!
@@ -278,38 +259,22 @@ namespace kstd
//!
//! @param value The new error code value.
//! @param category The new error code category.
- constexpr auto assign(int value, error_category const & category) noexcept -> void
- {
- m_value = value;
- m_category = &category;
- }
+ auto assign(int value, error_category const & category) noexcept -> void;
//! Clear this error code.
- constexpr auto clear() noexcept -> void;
+ auto clear() noexcept -> void;
//! Get the raw error code value of this error code.
- [[nodiscard]] constexpr auto value() const noexcept -> int
- {
- return m_value;
- }
+ [[nodiscard]] auto value() const noexcept -> int;
//! Get the error category of this error code.
- [[nodiscard]] constexpr auto category() const noexcept -> error_category const &
- {
- return *m_category;
- }
+ [[nodiscard]] auto category() const noexcept -> error_category const &;
//! Get and error condition that is equivalent to this error code.
- [[nodiscard]] constexpr auto default_error_condition() const noexcept -> error_condition
- {
- return m_category->default_error_condition(m_value);
- }
+ [[nodiscard]] auto default_error_condition() const noexcept -> error_condition;
//! Get the message associated with this error code based on its value and category.
- [[nodiscard]] constexpr auto message() const noexcept -> std::string_view
- {
- return m_category->message(m_value);
- }
+ [[nodiscard]] auto message() const noexcept -> std::string_view;
//! Check if this error code holds an error.
//!
@@ -327,6 +292,12 @@ namespace kstd
return lhs.category() == rhs.category() && lhs.value() == rhs.value();
}
+ constexpr auto friend operator==(error_code const & code, error_condition const & condition) noexcept -> bool
+ {
+ return code.category().equivalent(code.value(), condition) ||
+ condition.category().equivalent(code, condition.value());
+ }
+
//! Lexicographically compare two error codes.
[[nodiscard]] constexpr auto friend operator<=>(error_code const & lhs, error_code const & rhs) noexcept
-> std::strong_ordering
@@ -428,182 +399,17 @@ namespace kstd
{
};
- namespace bits
- {
- constexpr auto to_message(errc error) -> std::string_view
- {
- switch (error)
- {
- // clang-format off
- case errc::address_family_not_supported: return "address family not supported";
- case errc::address_in_use: return "address in use";
- case errc::address_not_available: return "address not available";
- case errc::already_connected: return "already connected";
- case errc::argument_list_too_long: return "argument list too long";
- case errc::argument_out_of_domain: return "argument out of domain";
- case errc::bad_address: return "bad address";
- case errc::bad_file_descriptor: return "bad file descriptor";
- case errc::bad_message: return "bad message";
- case errc::broken_pipe: return "broken pipe";
- case errc::connection_aborted: return "connection aborted";
- case errc::connection_already_in_progress: return "connection already in progress";
- case errc::connection_refused: return "connection refused";
- case errc::connection_reset: return "connection reset";
- case errc::cross_device_link: return "cross device link";
- case errc::destination_address_required: return "destination address required";
- case errc::device_or_resource_busy: return "device or resource busy";
- case errc::directory_not_empty: return "directory not empty";
- case errc::executable_format_error: return "invalid executable format";
- case errc::file_exists: return "file exists";
- case errc::file_too_large: return "file too large";
- case errc::filename_too_long: return "filename too long";
- case errc::function_not_supported: return "function not supported";
- case errc::host_unreachable: return "host unreachable";
- case errc::identifier_removed: return "identifier removed";
- case errc::illegal_byte_sequence: return "illegal byte sequence";
- case errc::inappropriate_io_control_operation: return "inappropriate io control operation";
- case errc::interrupted: return "system call interrupted";
- case errc::invalid_argument: return "invalid argument";
- case errc::invalid_seek: return "invalid seek";
- case errc::io_error: return "input/output error";
- case errc::is_a_directory: return "is a directory";
- case errc::message_size: return "message size";
- case errc::network_down: return "network down";
- case errc::network_reset: return "network reset";
- case errc::network_unreachable: return "network unreachable";
- case errc::no_buffer_space: return "no buffer space";
- case errc::no_child_process: return "no child process";
- case errc::no_link: return "no link";
- case errc::no_lock_available: return "no lock available";
- case errc::no_message: return "no message";
- case errc::no_protocol_option: return "no protocol option";
- case errc::no_space_on_device: return "no space on device";
- case errc::no_such_device: return "no such device";
- case errc::no_such_device_or_address: return "no such device or address";
- case errc::no_such_file_or_directory: return "no such file or directory";
- case errc::no_such_process: return "no such process";
- case errc::not_a_directory: return "not a directory";
- case errc::not_a_socket: return "not a socket";
- case errc::not_connected: return "not connected";
- case errc::not_enough_memory: return "not enough memory";
- case errc::not_supported: return "not supported";
- case errc::operation_canceled: return "operation canceled";
- case errc::operation_in_progress: return "operation in progress";
- case errc::operation_not_permitted: return "operation not permitted";
- case errc::operation_not_supported: return "operation not supported";
- case errc::operation_would_block: return "operation would block";
- case errc::owner_dead: return "owner dead";
- case errc::permission_denied: return "permission denied";
- case errc::protocol_error: return "protocol error";
- case errc::protocol_not_supported: return "protocol not supported";
- case errc::read_only_file_system: return "read only file system";
- case errc::resource_deadlock_would_occur: return "resource deadlock would occur";
- case errc::resource_unavailable_try_again: return "resource unavailable, try again";
- case errc::result_out_of_range: return "result out of range";
- case errc::state_not_recoverable: return "state not recoverable";
- case errc::text_file_busy: return "text file busy";
- case errc::timed_out: return "timed out";
- case errc::too_many_files_open: return "too many files open";
- case errc::too_many_files_open_in_system: return "too many files open in system";
- case errc::too_many_links: return "too many links";
- case errc::too_many_symbolic_link_levels: return "too many symbolic link levels";
- case errc::value_too_large: return "value too large";
- case errc::wrong_protocol_type: return "wrong protocol type";
- default: return "unknown error";
- // clang-format on
- }
- }
-
- struct generic_category_t final : error_category
- {
- [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
- {
- return "generic";
- }
-
- [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
- {
- return to_message(static_cast<errc>(value));
- }
- } constexpr inline generic_category_instance{};
-
- struct system_category_t final : error_category
- {
- [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
- {
- return "system";
- }
-
- [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
- {
- return to_message(static_cast<errc>(value));
- }
- } constexpr inline system_category_instance{};
- } // namespace bits
-
//! Get a reference to the generic error category.
- constexpr auto inline generic_category() noexcept -> error_category const &
- {
- return bits::generic_category_instance;
- }
+ auto generic_category() noexcept -> error_category const &;
//! Get a reference to the system error category.
- constexpr auto inline system_category() noexcept -> error_category const &
- {
- return bits::system_category_instance;
- }
-
- constexpr auto inline error_category::default_error_condition(int value) const noexcept -> error_condition
- {
- return error_condition{value, *this};
- }
-
- constexpr auto inline error_category::equivalent(int value, error_condition const & other) const noexcept -> bool
- {
- return default_error_condition(value) == other;
- }
-
- constexpr auto error_category::equivalent(error_code const & code, int condition) const noexcept -> bool
- {
- return *this == code.category() && code.value() == condition;
- }
-
- constexpr error_condition::error_condition() noexcept
- : error_condition{0, generic_category()}
- {}
-
- constexpr auto error_condition::clear() noexcept -> void
- {
- m_value = 0;
- m_category = &generic_category();
- }
-
- constexpr auto operator==(error_code const & code, error_condition const & condition) noexcept -> bool
- {
- return code.category().equivalent(code.value(), condition) ||
- condition.category().equivalent(code, condition.value());
- }
-
- constexpr error_code::error_code() noexcept
- : error_code{0, system_category()} {};
-
- constexpr auto error_code::clear() noexcept -> void
- {
- m_value = 0;
- m_category = &system_category();
- }
+ auto system_category() noexcept -> error_category const &;
//! Create an error code from an kstd::errc enumeration value.
- [[nodiscard]] constexpr auto inline make_error_code(errc const value) noexcept -> error_code
- {
- return {static_cast<int>(value), generic_category()};
- }
+ [[nodiscard]] auto make_error_code(errc const value) noexcept -> error_code;
//! Create an error condition from an kstd::errc enumeration value.
- [[nodiscard]] constexpr auto inline make_error_condition(errc const value) noexcept -> error_condition
- {
- return {static_cast<int>(value), generic_category()};
- }
+ [[nodiscard]] auto make_error_condition(errc const value) noexcept -> error_condition;
//! Enable formatting of kstd::error_code
//!