Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions include/argon/argument.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#include "argon/action/predefined.hpp"
#include "argon/action/util.hpp"
#include "argon/detail/argument_base.hpp"
#include "argon/argument_base.hpp"
#include "argon/detail/help_builder.hpp"
#include "argon/nargs/range.hpp"
#include "argon/traits.hpp"
Expand Down Expand Up @@ -54,7 +54,7 @@ enum class argument_type : bool { positional, optional };
* @tparam T The value type accepted by the argument (defaults to std::string).
*/
template <argument_type ArgT, traits::c_argument_value_type T = std::string>
class argument : public detail::typed_argument_base<T> {
class argument : public typed_argument_base<T> {
public:
using value_type = T; ///< The argument's value type alias.
using count_type = nargs::count_type; ///< The argument's count type alias.
Expand All @@ -68,7 +68,7 @@ class argument : public detail::typed_argument_base<T> {
* @param name The name of the positional argument.
* @note The constructor is enabled only if `type` is `argument_type::positional`.
*/
argument(const detail::argument_name& name)
argument(const argument_name& name)
requires(type == argument_type::positional)
: _name(name), _nargs_range(_default_nargs_range_actual), _required(_default_required) {}

Expand All @@ -77,7 +77,7 @@ class argument : public detail::typed_argument_base<T> {
* @param name The name of the optional argument.
* @note The constructor is enabled only if `type` is `argument_type::optional`.
*/
argument(const detail::argument_name& name)
argument(const argument_name& name)
requires(type == argument_type::optional)
: _name(name),
_nargs_range(_default_nargs_range_actual),
Expand All @@ -97,7 +97,7 @@ class argument : public detail::typed_argument_base<T> {
}

/// @return Reference the name of the positional argument.
[[nodiscard]] const argon::detail::argument_name& name() const noexcept override {
[[nodiscard]] const argon::argument_name& name() const noexcept override {
return this->_name;
}

Expand Down Expand Up @@ -442,6 +442,16 @@ class argument : public detail::typed_argument_base<T> {
return this->has_parsed_values() or this->_has_predefined_values_impl();
}

/// @return `true` if parsed values are available for the argument, `false` otherwise.
[[nodiscard]] bool has_parsed_values() const noexcept override {
return not this->_values.empty();
}

/// @return `true` if the argument has predefined values, `false` otherwise.
[[nodiscard]] bool has_predefined_values() const noexcept override {
return this->_has_predefined_values_impl();
}

/**
* @return Reference to the stored value of the argument.
* @note If multiple values are available, the first one is returned.
Expand Down Expand Up @@ -571,16 +581,6 @@ class argument : public detail::typed_argument_base<T> {
return this->_set_value_impl(str_value);
}

/// @return `true` if parsed values are available for the argument, `false` otherwise.
[[nodiscard]] bool has_parsed_values() const noexcept override {
return not this->_values.empty();
}

/// @return `true` if the argument has predefined values, `false` otherwise.
[[nodiscard]] bool has_predefined_values() const noexcept override {
return this->_has_predefined_values_impl();
}

/// @return The ordering relationship of the argument's values and its nargs range attribute.
[[nodiscard]] std::weak_ordering nvalues_ordering() const noexcept override {
if (this->_values.empty() and this->_has_predefined_values_impl())
Expand Down Expand Up @@ -768,7 +768,7 @@ class argument : public detail::typed_argument_base<T> {
}

// attributes
const argon::detail::argument_name _name; ///< The argument's name.
const argon::argument_name _name; ///< The argument's name.
std::optional<std::string> _help_msg; ///< The argument's help message.
nargs::range _nargs_range; ///< The argument's nargs range attribute value.
[[no_unique_address]] value_arg_specific_type<std::vector<value_type>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
// Licensed under the MIT License. See the LICENSE file in the project root for full license information.

/**
* @file argon/detail/argument_base.hpp
* @file argon/argument_base.hpp
* @brief Defines the base argument class and common utility.
*/

#pragma once

#include "argon/detail/argument_name.hpp"
#include "argon/argument_name.hpp"
#include "argon/detail/help_builder.hpp"
#include "argon/traits.hpp"

Expand All @@ -21,13 +21,13 @@ namespace argon {

class argument_parser;

namespace detail {

/// @brief Argument class interface
class argument_base {
public:
virtual ~argument_base() = default;

// --- attribute getters ---

/// @return `true` if the argument is a positional argument instance, `false` otherwise.
virtual bool is_positional() const noexcept = 0;

Expand Down Expand Up @@ -55,28 +55,14 @@ class argument_base {
/// @return `true` if the argument is greedy, `false` otherwise.
virtual bool is_greedy() const noexcept = 0;

friend class ::argon::argument_parser;

protected:
/// @param verbose The verbosity mode value. If `true` all non-default parameters will be included in the output.
/// @return A help message builder object for the argument.
virtual detail::help_builder help_builder(const bool verbose) const noexcept = 0;

/// @brief Mark the argument as used.
/// @return `true` if the argument accepts further values, `false` otherwise.
virtual bool mark_used() = 0;
// --- state getters ---

/// @return `true` if the argument has been used, `false` otherwise.
virtual bool is_used() const noexcept = 0;

/// @return The number of times an argument has been used.
virtual std::size_t count() const noexcept = 0;

/// @brief Set the value for the argument.
/// @param value The string representation of the value.
/// @return `true` if the argument accepts further values, `false` otherwise.
virtual bool set_value(const std::string& value) = 0;

/// @return `true` if the argument has a value, `false` otherwise.
virtual bool has_value() const noexcept = 0;

Expand All @@ -86,6 +72,22 @@ class argument_base {
/// @return `true` if the argument has predefined values, `false` otherwise.
virtual bool has_predefined_values() const noexcept = 0;

friend class ::argon::argument_parser;

protected:
/// @param verbose The verbosity mode value. If `true` all non-default parameters will be included in the output.
/// @return A help message builder object for the argument.
virtual detail::help_builder help_builder(const bool verbose) const noexcept = 0;

/// @brief Mark the argument as used.
/// @return `true` if the argument accepts further values, `false` otherwise.
virtual bool mark_used() = 0;

/// @brief Set the value for the argument.
/// @param value The string representation of the value.
/// @return `true` if the argument accepts further values, `false` otherwise.
virtual bool set_value(const std::string& value) = 0;

/// @return The ordering relationship of argument range.
virtual std::weak_ordering nvalues_ordering() const noexcept = 0;
};
Expand All @@ -101,5 +103,4 @@ class typed_argument_base : public argument_base {
virtual const std::vector<T>& values() const = 0;
};

} // namespace detail
} // namespace argon
4 changes: 2 additions & 2 deletions include/argon/argument_group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#pragma once

#include "argon/detail/argument_base.hpp"
#include "argon/argument_base.hpp"

#include <memory>

Expand Down Expand Up @@ -130,7 +130,7 @@ class argument_group {
friend class argument_parser;

private:
using arg_ptr_t = std::shared_ptr<detail::argument_base>; ///< The argument pointer type alias.
using arg_ptr_t = std::shared_ptr<argument_base>; ///< The argument pointer type alias.
using arg_ptr_vec_t = std::vector<arg_ptr_t>; ///< The argument pointer list type alias.

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// This file is part of the CPP-ARGON project (https://github.com/SpectraL519/cpp-argon).
// Licensed under the MIT License. See the LICENSE file in the project root for full license information.

/// @file argon/detail/argument_name.hpp
/// @file argon/argument_name.hpp

#pragma once

Expand All @@ -15,10 +15,9 @@

namespace argon {

namespace detail {

/// @brief Structure holding the argument's name.
struct argument_name {
/// @brief Class holding the argument's name.
class argument_name {
public:
/// @brief Specifies the type of argument name match.
enum class match_type : std::uint8_t {
m_any, ///< Matches either the primary or the secondary name.
Expand All @@ -29,12 +28,12 @@ struct argument_name {

argument_name() = delete;

argument_name& operator=(const argument_name&) = delete;
argument_name& operator=(argument_name&&) = delete;

argument_name(const argument_name&) = default;
argument_name(argument_name&&) = default;

argument_name& operator=(const argument_name&) = default;
argument_name& operator=(argument_name&&) = default;

/**
* @brief Primary and secondary name constructor.
* @param primary The primary name of the argument.
Expand All @@ -44,8 +43,8 @@ struct argument_name {
explicit argument_name(
std::string primary, std::string secondary = "", char flag_char = flag_char_sentinel
)
: primary(std::move(primary)), secondary(std::move(secondary)), flag_char(flag_char) {
if (this->primary.empty() and this->secondary.empty())
: _primary(std::move(primary)), _secondary(std::move(secondary)), _flag_char(flag_char) {
if (this->_primary.empty() and this->_secondary.empty())
throw std::logic_error("An argument name cannot be empty! At least one of "
"primary/secondary must be specified");
}
Expand All @@ -59,17 +58,32 @@ struct argument_name {
* @return Equality of argument names.
*/
bool operator==(const argument_name& other) const noexcept {
return this->primary == other.primary and this->secondary == other.secondary;
return this->_primary == other._primary and this->_secondary == other._secondary;
}

/// @brief Checks if the argument name instance has a primary name.
[[nodiscard]] bool has_primary() const noexcept {
return not this->primary.empty();
return not this->_primary.empty();
}

/// @brief Checks if the argument name instance has a secondary name.
[[nodiscard]] bool has_secondary() const noexcept {
return not this->secondary.empty();
return not this->_secondary.empty();
}

/// @return The primary name of the argument.
[[nodiscard]] const std::string& primary() const noexcept {
return this->_primary;
}

/// @return The secondary (short) name of the argument.
[[nodiscard]] const std::string& secondary() const noexcept {
return this->_secondary;
}

/// @return The flag character (used for optional argument names).
[[nodiscard]] char flag_char() const noexcept {
return this->_flag_char;
}

/**
Expand All @@ -82,12 +96,12 @@ struct argument_name {
const noexcept {
switch (m_type) {
case m_any:
return (this->has_primary() and this->primary == arg_name)
or (this->has_secondary() and this->secondary == arg_name);
return (this->has_primary() and this->_primary == arg_name)
or (this->has_secondary() and this->_secondary == arg_name);
case m_primary:
return this->has_primary() and this->primary == arg_name;
return this->has_primary() and this->_primary == arg_name;
case m_secondary:
return this->has_secondary() and this->secondary == arg_name;
return this->has_secondary() and this->_secondary == arg_name;
}

return false;
Expand All @@ -99,11 +113,11 @@ struct argument_name {
* @return True if arg_name's primary or secondary value matches the argument_name instance.
*/
[[nodiscard]] bool match(const argument_name& arg_name) const noexcept {
if (arg_name.has_primary() and this->match(arg_name.primary))
if (arg_name.has_primary() and this->match(arg_name._primary))
return true;

if (arg_name.has_secondary())
return this->match(arg_name.secondary);
return this->match(arg_name._secondary);

return false;
}
Expand All @@ -113,14 +127,14 @@ struct argument_name {
*/
[[nodiscard]] std::string str() const noexcept {
const std::string fc(
static_cast<std::size_t>(this->flag_char != flag_char_sentinel), this->flag_char
static_cast<std::size_t>(this->_flag_char != flag_char_sentinel), this->_flag_char
);

std::string primary_str =
this->has_primary() ? std::format("{}{}{}", fc, fc, this->primary) : "";
this->has_primary() ? std::format("{}{}{}", fc, fc, this->_primary) : "";
std::string separator = this->has_primary() and this->has_secondary() ? ", " : "";
std::string secondary_str =
this->has_secondary() ? std::format("{}{}", fc, this->secondary) : "";
this->has_secondary() ? std::format("{}{}", fc, this->_secondary) : "";

return std::format("{}{}{}", primary_str, separator, secondary_str);
}
Expand All @@ -136,12 +150,13 @@ struct argument_name {
return os;
}

const std::string primary; ///< The primary name of the argument.
const std::string secondary; ///< The optional (short) name of the argument.
const char flag_char; ///< The flag character (used for optional argument names).

// --- constants ---
static constexpr char flag_char_sentinel = '\0'; ///< Sentinel value for the flag character.

private:
std::string _primary; ///< The primary name of the argument.
std::string _secondary; ///< The optional (short) name of the argument.
char _flag_char; ///< The flag character (used for optional argument names).
};

/**
Expand All @@ -154,8 +169,6 @@ enum class argument_name_discriminator : bool {
n_secondary ///< Represents the secondary name (used with a short flag prefix --).
};

} // namespace detail

using enum detail::argument_name_discriminator;
using enum argument_name_discriminator;

} // namespace argon
Loading
Loading