help with choices

v2
Brett 2025-02-25 12:34:14 -05:00
parent 1b6d23fad4
commit 0913208e6b
3 changed files with 44 additions and 20 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake) include(cmake/color.cmake)
set(BLT_VERSION 4.0.28) set(BLT_VERSION 4.0.29)
set(BLT_TARGET BLT) set(BLT_TARGET BLT)

View File

@ -32,6 +32,7 @@
#include <functional> #include <functional>
#include <type_traits> #include <type_traits>
#include <blt/iterator/iterator.h> #include <blt/iterator/iterator.h>
#include <blt/meta/type_traits.h>
#include <blt/std/assert.h> #include <blt/std/assert.h>
#include <blt/std/expected.h> #include <blt/std/expected.h>
#include <blt/std/ranges.h> #include <blt/std/ranges.h>
@ -227,6 +228,16 @@ namespace blt::argparse
} }
}; };
template <typename T>
auto ensure_is_string(T&& t)
{
if constexpr (std::is_arithmetic_v<meta::remove_cvref_t<T>> && !(std::is_same_v<T, char>
|| std::is_same_v<T, unsigned char> || std::is_same_v<T, signed char>))
return std::to_string(std::forward<T>(t));
else
return std::forward<T>(t);
}
void test(); void test();
} }
@ -493,6 +504,14 @@ namespace blt::argparse
return *this; return *this;
} }
template <typename... Args>
argument_builder_t& set_choices(Args&&... args)
{
m_choices = hashset_t<std::string>{};
((m_choices->emplace(detail::ensure_is_string(std::forward<Args>(args)))), ...);
return *this;
}
argument_builder_t& set_default(const detail::arg_data_t& default_value) argument_builder_t& set_default(const detail::arg_data_t& default_value)
{ {
m_default_value = default_value; m_default_value = default_value;
@ -566,7 +585,7 @@ namespace blt::argparse
public: public:
explicit argument_parser_t(const std::optional<std::string_view> description = {}, const std::optional<std::string_view> epilogue = {}, explicit argument_parser_t(const std::optional<std::string_view> description = {}, const std::optional<std::string_view> epilogue = {},
const std::optional<std::string_view> version = {}, const std::optional<std::string_view> version = {},
const std::optional<std::string_view> usage = {}, const std::optional<std::string_view> name = {}): const std::optional<std::string_view> usage = {}, const std::optional<std::string_view> name = {}):
m_name(name), m_usage(usage), m_description(description), m_epilogue(epilogue), m_version(version) m_name(name), m_usage(usage), m_description(description), m_epilogue(epilogue), m_version(version)
{ {

View File

@ -67,16 +67,6 @@ namespace blt::argparse
} }
} }
template <typename T>
auto ensure_is_string(T&& t)
{
if constexpr (std::is_arithmetic_v<meta::remove_cvref_t<T>> && !(std::is_same_v<T, char>
|| std::is_same_v<T, unsigned char> || std::is_same_v<T, signed char>))
return std::to_string(std::forward<T>(t));
else
return std::forward<T>(t);
}
template <typename T> template <typename T>
std::string to_string(const T& t) std::string to_string(const T& t)
{ {
@ -99,7 +89,7 @@ namespace blt::argparse
{ {
std::string out; std::string out;
out.reserve((get_const_char_size(strings) + ...)); out.reserve((get_const_char_size(strings) + ...));
((out += ensure_is_string(std::forward<Strings>(strings))), ...); ((out += detail::ensure_is_string(std::forward<Strings>(strings))), ...);
return out; return out;
} }
@ -151,7 +141,7 @@ namespace blt::argparse
template <typename T> template <typename T>
aligned_internal_string_t& operator+=(T&& value) aligned_internal_string_t& operator+=(T&& value)
{ {
const auto str = to_string(ensure_is_string(std::forward<T>(value))); const auto str = to_string(detail::ensure_is_string(std::forward<T>(value)));
for (size_t i = 0; i < str.size(); i++) for (size_t i = 0; i < str.size(); i++)
{ {
size_t j = i; size_t j = i;
@ -166,6 +156,11 @@ namespace blt::argparse
return *this; return *this;
} }
[[nodiscard]] std::string& str() const
{
return string;
}
private: private:
std::string& string; std::string& string;
size_t max_line_size; size_t max_line_size;
@ -264,7 +259,7 @@ namespace blt::argparse
template <typename T> template <typename T>
aligned_printer_t& add(T&& value) aligned_printer_t& add(T&& value)
{ {
const auto str = to_string(ensure_is_string(std::forward<T>(value))); const auto str = to_string(detail::ensure_is_string(std::forward<T>(value)));
if (buffer.back().size() + str.size() > max_line_size) if (buffer.back().size() + str.size() > max_line_size)
newline(); newline();
buffer.back() += replace_tabs(str); buffer.back() += replace_tabs(str);
@ -458,13 +453,10 @@ namespace blt::argparse
{ {
auto& [builder, flag_list] = pair; auto& [builder, flag_list] = pair;
str += builder->m_help.value_or(""); str += builder->m_help.value_or("");
}
mark.align(4);
for (auto [str, pair] : mark.iter().zip(same_flags))
{
auto& [builder, flag_list] = pair;
if (builder->m_default_value) if (builder->m_default_value)
{ {
if (!std::isblank(str.str().back()))
str += " ";
str += "(Default: "; str += "(Default: ";
std::visit(detail::arg_meta_type_helper_t::make_visitor( std::visit(detail::arg_meta_type_helper_t::make_visitor(
[&](auto& value) [&](auto& value)
@ -487,6 +479,19 @@ namespace blt::argparse
}), *builder->m_default_value); }), *builder->m_default_value);
str += ")"; str += ")";
} }
if (builder->m_choices)
{
if (!std::isblank(str.str().back()))
str += " ";
str += "(Choices: ";
for (const auto& [i, v] : enumerate(*builder->m_choices))
{
str += v;
if (i != builder->m_choices->size() - 1)
str += ", ";
}
str += ')';
}
} }
} }