From 457dd5203b3f440ba322d809a879164f13af4e13 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Wed, 12 Feb 2025 19:42:50 -0500 Subject: [PATCH] hi --- CMakeLists.txt | 2 +- include/blt/parse/argparse_v2.h | 63 ++++++++++++++++++++++++++------- src/blt/parse/argparse_v2.cpp | 53 +++++++++++++++++++++------ 3 files changed, 95 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d87cc7..5863b5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 4.0.0) +set(BLT_VERSION 4.0.1) set(BLT_TARGET BLT) diff --git a/include/blt/parse/argparse_v2.h b/include/blt/parse/argparse_v2.h index 1914870..d9bfa37 100644 --- a/include/blt/parse/argparse_v2.h +++ b/include/blt/parse/argparse_v2.h @@ -26,7 +26,10 @@ #include #include #include +#include #include +#include +#include namespace blt::argparse { @@ -35,8 +38,10 @@ namespace blt::argparse inline hashset_t allowed_flag_prefixes = {"-", "--", "+"}; std::string flag_prefixes_as_string(); + hashset_t prefix_characters(); inline std::string flag_prefix_list_string = flag_prefixes_as_string(); + inline auto prefix_characters_set = prefix_characters(); class bad_flag final : public std::runtime_error { @@ -64,7 +69,42 @@ namespace blt::argparse using arg_data_t = std::variant; template - class arg_type_t; + struct arg_type_t + { + static T convert(const std::string_view value) + { + const std::string temp{value}; + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + return static_cast(std::stoi(temp)); + } + else if constexpr (std::is_same_v) + { + return static_cast(std::stoll(temp)); + } + else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + return static_cast(std::stoul(temp)); + } + else if constexpr (std::is_same_v) + { + return static_cast(std::stoull(temp)); + } + else if constexpr (std::is_same_v) + { + return std::stof(temp); + } + else if constexpr (std::is_same_v) + { + return std::stod(temp); + } else + { + static_assert(std::is_arithmetic_v, "Unsupported type for this specialization"); + } + BLT_UNREACHABLE; + } + }; void test(); } @@ -115,7 +155,7 @@ namespace blt::argparse size_t start = m_argument.size(); for (auto [i, c] : enumerate(m_argument)) { - if (std::isalnum(c)) + if (!detail::prefix_characters_set.contains(c)) { start = i; break; @@ -140,38 +180,37 @@ namespace blt::argparse class argument_consumer_t { public: - argument_consumer_t(const i32 argc, const char** argv): argv(argv), argc(argc) + explicit argument_consumer_t(const span& args): args(args) { } - [[nodiscard]] std::string_view peek(const i32 offset = 0) const + [[nodiscard]] argument_string_t peek(const i32 offset = 0) const { - return argv[forward_index + offset]; + return args[forward_index + offset]; } - std::string_view consume() + argument_string_t consume() { - return argv[forward_index++]; + return args[forward_index++]; } [[nodiscard]] i32 position() const { - return argc; + return forward_index; } [[nodiscard]] i32 remaining() const { - return argc - forward_index; + return static_cast(args.size()) - forward_index; } [[nodiscard]] bool has_next(const i32 offset = 0) const { - return (offset + forward_index) < argc; + return (offset + forward_index) < args.size(); } private: - const char** argv; - i32 argc; + span args; i32 forward_index = 0; }; } diff --git a/src/blt/parse/argparse_v2.cpp b/src/blt/parse/argparse_v2.cpp index 2d9cc8d..09fcee3 100644 --- a/src/blt/parse/argparse_v2.cpp +++ b/src/blt/parse/argparse_v2.cpp @@ -41,6 +41,15 @@ namespace blt::argparse } return result; } + + hashset_t prefix_characters() + { + hashset_t result; + for (auto [i, v] : enumerate(allowed_flag_prefixes)) + for (auto c : v) + result.insert(c); + return result; + } } @@ -100,16 +109,9 @@ namespace blt::argparse // Test Case 9: Validate edge case of an argument with spaces void test_argument_string_t_with_spaces() { - try - { - const argument_string_t arg(" "); - BLT_ASSERT(!arg.is_flag() && "Arguments with spaces should not be treated as flags."); - BLT_ASSERT(arg.value() == " " && "Arguments with spaces should match the input string."); - } catch (bad_flag&) - { - return; - } - BLT_ASSERT(false && "Expected an exception to be thrown for arguments with spaces."); + const argument_string_t arg(" "); + BLT_ASSERT(!arg.is_flag() && "Arguments with spaces should not be treated as flags."); + BLT_ASSERT(arg.value() == " " && "Arguments with spaces should match the input string."); } // Test Case 10: Validate arguments with numeric characters @@ -120,6 +122,33 @@ namespace blt::argparse BLT_ASSERT(arg.value() == "123" && "Numeric flag value should match the input string."); } + + // Test Case 11: Ensure the constructor handles '+' flag correctly + void test_argument_string_t_plus_flag_basic() + { + const argument_string_t arg("+f"); + BLT_ASSERT(arg.is_flag() && "Expected argument to be identified as a flag."); + BLT_ASSERT(arg.value() == "f" && "Plus flag value should match the input string."); + } + + // Test Case 13: Handle edge case of a single plus (`+`) which might be ambiguous + void test_argument_string_t_single_plus() + { + const argument_string_t arg("+"); + BLT_ASSERT(arg.is_flag() && "Expected single plus (`+`) to be treated as a flag."); + BLT_ASSERT(arg.value().empty() && "Single plus flag should have empty value."); + BLT_ASSERT(arg.get_flag() == "+" && "Single plus flag should match the input string."); + } + + // Test Case 14: Handle arguments with prefix only (like '++') + void test_argument_string_t_double_plus() + { + const argument_string_t arg("++"); + BLT_ASSERT(arg.is_flag() && "Double plus ('++') should be treated as a flag."); + BLT_ASSERT(arg.value().empty() && "Double plus flag should have empty value."); + BLT_ASSERT(arg.get_flag() == "++" && "Double plus value should match the input string."); + } + void run_all_tests_argument_string_t() { test_argument_string_t_flag_basic(); @@ -130,7 +159,11 @@ namespace blt::argparse test_argument_string_t_double_hyphen(); test_argument_string_t_with_spaces(); test_argument_string_t_numeric_flag(); + test_argument_string_t_plus_flag_basic(); + test_argument_string_t_single_plus(); + test_argument_string_t_double_plus(); } + void test() { run_all_tests_argument_string_t();