diff --git a/include/argparse.hpp b/include/argparse.hpp index 5c7affa..b5403d3 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -41,7 +41,6 @@ #include #include #include - #include #include #include #include @@ -63,7 +62,7 @@ #endif #include "src/util/defs.hpp" -#include "src/util/error.hpp" // Added for Result type +#include "src/util/error.hpp" #include "src/util/types.hpp" #ifndef ARGPARSE_CUSTOM_STRTOF @@ -79,11 +78,12 @@ #endif // ReSharper disable CppTemplateParameterNeverUsed, CppDFATimeOver -// NOLINTBEGIN(readability-identifier-naming, readability-identifier-length) +// NOLINTBEGIN(readability-identifier-naming, readability-identifier-length, modernize-use-nullptr) namespace argparse { using namespace util::types; + using util::error::DracError, util::error::DracErrorCode; - namespace details { // namespace for helper methods + namespace details { template struct HasContainerTraits : std::false_type {}; @@ -241,17 +241,16 @@ namespace argparse { if (ptr == last) return x; - return Err(util::error::DracError(util::error::DracErrorCode::ParseError, std::format("pattern '{}' does not match to the end", String(s)))); + return Err(DracError(DracErrorCode::ParseError, std::format("pattern '{}' does not match to the end", String(s)))); } if (ec == std::errc::invalid_argument) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, std::format("pattern '{}' not found", String(s)))); + return Err(DracError(DracErrorCode::InvalidArgument, std::format("pattern '{}' not found", String(s)))); if (ec == std::errc::result_out_of_range) - return Err(util::error::DracError(util::error::DracErrorCode::ParseError, std::format("'{}' not representable", String(s)))); + return Err(DracError(DracErrorCode::ParseError, std::format("'{}' not representable", String(s)))); - // Should be unreachable, but handle potential unknown error codes - return Err(util::error::DracError(util::error::DracErrorCode::InternalError, std::format("Unknown parsing error for '{}'", String(s)))); + return Err(DracError(DracErrorCode::InternalError, std::format("Unknown parsing error for '{}'", String(s)))); } template @@ -267,7 +266,7 @@ namespace argparse { if (auto [ok, rest] = consume_binary_prefix(s); ok) return do_from_chars(rest); - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "pattern not found")); + return Err(DracError(DracErrorCode::InvalidArgument, "pattern not found")); } }; @@ -280,12 +279,12 @@ namespace argparse { if (auto [ok, rest] = consume_hex_prefix(s); ok) result = do_from_chars(rest); else - return Err(util::error::DracError(util::error::DracErrorCode::InternalError, std::format("Inconsistent hex prefix detection for '{}'", String(s)))); + return Err(DracError(DracErrorCode::InternalError, std::format("Inconsistent hex prefix detection for '{}'", String(s)))); } else result = do_from_chars(s); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as hexadecimal: {}", String(s), result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as hexadecimal: {}", String(s), result.error().message))); return result; } @@ -298,7 +297,7 @@ namespace argparse { Result result = do_from_chars(rest); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as hexadecimal: {}", String(s), result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as hexadecimal: {}", String(s), result.error().message))); return result; } @@ -307,25 +306,24 @@ namespace argparse { Result result = do_from_chars(rest_binary); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as binary: {}", String(s), result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as binary: {}", String(s), result.error().message))); return result; } - // Note: consume_hex_prefix already removed the prefix if present, so 'rest' is correct here for octal/decimal check. - if (starts_with("0"sv, s)) { // Check original string for octal prefix - Result result = do_from_chars(s); // Pass original string for octal + if (starts_with("0"sv, s)) { + Result result = do_from_chars(s); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as octal: {}", String(s), result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as octal: {}", String(s), result.error().message))); return result; } - Result result = do_from_chars(s); // Pass original string for decimal + Result result = do_from_chars(s); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as decimal integer: {}", String(s), result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as decimal integer: {}", String(s), result.error().message))); return result; } @@ -343,7 +341,7 @@ namespace argparse { template fn do_strtod(const String& s) -> Result { if (isspace(static_cast(s[0])) || s[0] == '+') - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, std::format("pattern '{}' not found", s))); + return Err(DracError(DracErrorCode::InvalidArgument, std::format("pattern '{}' not found", s))); auto [first, last] = pointer_range(s); @@ -357,28 +355,27 @@ namespace argparse { if (ptr == last) return x; - return Err(util::error::DracError(util::error::DracErrorCode::ParseError, std::format("pattern '{}' does not match to the end", s))); + return Err(DracError(DracErrorCode::ParseError, std::format("pattern '{}' does not match to the end", s))); } if (errno == ERANGE) - return Err(util::error::DracError(util::error::DracErrorCode::ParseError, std::format("'{}' not representable", s))); + return Err(DracError(DracErrorCode::ParseError, std::format("'{}' not representable", s))); - // Handle other potential errno values - return Err(util::error::DracError(std::error_code(errno, std::system_category()))); + return Err(DracError(std::error_code(errno, std::system_category()))); } template struct parse_number { fn operator()(const String& s)->Result { if (auto [is_hex, rest] = consume_hex_prefix(s); is_hex) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::general does not parse hexfloat")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::general does not parse hexfloat")); if (auto [is_bin, rest] = consume_binary_prefix(s); is_bin) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::general does not parse binfloat")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::general does not parse binfloat")); Result result = do_strtod(s); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as number: {}", s, result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as number: {}", s, result.error().message))); return result; } }; @@ -387,14 +384,14 @@ namespace argparse { struct parse_number { fn operator()(const String& s)->Result { if (auto [is_hex, rest] = consume_hex_prefix(s); !is_hex) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::hex requires hexfloat format (e.g., 0x1.2p3)")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::hex requires hexfloat format (e.g., 0x1.2p3)")); if (auto [is_bin, rest] = consume_binary_prefix(s); is_bin) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::hex does not parse binfloat")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::hex does not parse binfloat")); Result result = do_strtod(s); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as hexadecimal float: {}", s, result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as hexadecimal float: {}", s, result.error().message))); return result; } }; @@ -403,14 +400,14 @@ namespace argparse { struct parse_number { fn operator()(const String& s)->Result { if (auto [is_hex, rest] = consume_hex_prefix(s); is_hex) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::binary does not parse hexfloat")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::binary does not parse hexfloat")); if (auto [is_bin, rest] = consume_binary_prefix(s); !is_bin) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::binary requires binfloat format (e.g., 0b1.01p2)")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::binary requires binfloat format (e.g., 0b1.01p2)")); Result result = do_strtod(s); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as binary float: {}", s, result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as binary float: {}", s, result.error().message))); return result; } }; @@ -419,18 +416,18 @@ namespace argparse { struct parse_number { fn operator()(const String& s)->Result { if (const auto [is_hex, rest] = consume_hex_prefix(s); is_hex) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::scientific does not parse hexfloat")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::scientific does not parse hexfloat")); if (const auto [is_bin, rest] = consume_binary_prefix(s); is_bin) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::scientific does not parse binfloat")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::scientific does not parse binfloat")); if (s.find_first_of("eE") == String::npos) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::scientific requires exponent part")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::scientific requires exponent part")); Result result = do_strtod(s); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as scientific notation: {}", s, result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as scientific notation: {}", s, result.error().message))); return result; } @@ -440,18 +437,18 @@ namespace argparse { struct parse_number { fn operator()(const String& s)->Result { if (const auto [is_hex, rest] = consume_hex_prefix(s); is_hex) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::fixed does not parse hexfloat")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::fixed does not parse hexfloat")); if (const auto [is_bin, rest] = consume_binary_prefix(s); is_bin) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::fixed does not parse binfloat")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::fixed does not parse binfloat")); if (s.find_first_of("eE") != String::npos) - return Err(util::error::DracError(util::error::DracErrorCode::InvalidArgument, "chars_format::fixed does not parse exponent part")); + return Err(DracError(DracErrorCode::InvalidArgument, "chars_format::fixed does not parse exponent part")); Result result = do_strtod(s); if (!result) - return Err(util::error::DracError(result.error().code, std::format("Failed to parse '{}' as fixed notation: {}", s, result.error().message))); + return Err(DracError(result.error().code, std::format("Failed to parse '{}' as fixed notation: {}", s, result.error().message))); return result; } @@ -538,6 +535,14 @@ namespace argparse { return most_similar; } + template class Ref> + struct is_specialization : std::false_type {}; + + template