v2
parent
a437935ab0
commit
457dd5203b
|
@ -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)
|
||||
|
||||
|
|
|
@ -26,7 +26,10 @@
|
|||
#include <vector>
|
||||
#include <variant>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <blt/iterator/enumerate.h>
|
||||
#include <blt/std/ranges.h>
|
||||
#include <blt/std/utility.h>
|
||||
|
||||
namespace blt::argparse
|
||||
{
|
||||
|
@ -35,8 +38,10 @@ namespace blt::argparse
|
|||
inline hashset_t<std::string_view> allowed_flag_prefixes = {"-", "--", "+"};
|
||||
|
||||
std::string flag_prefixes_as_string();
|
||||
hashset_t<char> 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<arg_primitive_data_t, arg_list_data_t>;
|
||||
|
||||
template <typename T>
|
||||
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<T, i8> || std::is_same_v<T, i16> || std::is_same_v<T, i32>)
|
||||
{
|
||||
return static_cast<T>(std::stoi(temp));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, i64>)
|
||||
{
|
||||
return static_cast<i64>(std::stoll(temp));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, u8> || std::is_same_v<T, u16> || std::is_same_v<T, u32>)
|
||||
{
|
||||
return static_cast<T>(std::stoul(temp));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, u64>)
|
||||
{
|
||||
return static_cast<u64>(std::stoull(temp));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, float>)
|
||||
{
|
||||
return std::stof(temp);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, double>)
|
||||
{
|
||||
return std::stod(temp);
|
||||
} else
|
||||
{
|
||||
static_assert(std::is_arithmetic_v<T>, "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<argument_string_t>& 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<i32>(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<argument_string_t> args;
|
||||
i32 forward_index = 0;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -41,6 +41,15 @@ namespace blt::argparse
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
hashset_t<char> prefix_characters()
|
||||
{
|
||||
hashset_t<char> 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();
|
||||
|
|
Loading…
Reference in New Issue