Skip to content

Commit 1dc4a60

Browse files
committed
extracted argument_name
1 parent 5d507ff commit 1dc4a60

10 files changed

+129
-124
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ else()
88
endif()
99

1010
project(cpp-ap
11-
VERSION 1.0
11+
VERSION 2.0.0
1212
DESCRIPTION "Command-line argument parser for C++20"
1313
HOMEPAGE_URL "https://github.com/SpectraL519/cpp-ap"
1414
LANGUAGES CXX

Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ PROJECT_NAME = "CPP-AP"
4848
# could be handy for archiving the generated documentation or if some version
4949
# control system is used.
5050

51-
PROJECT_NUMBER = 1.2
51+
PROJECT_NUMBER = 2.0.0
5252

5353
# Using the PROJECT_BRIEF tag one can provide an optional one line description
5454
# for a project that appears at the top of each page and should give viewer a

include/ap/argument_parser.hpp

Lines changed: 23 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ SOFTWARE.
3131
*
3232
* This header file contians the entire CPP-AP library implementation.
3333
*
34-
* @version 1.2
34+
* @version 2.0.0
3535
*/
3636

3737
#pragma once
3838

39+
#include "detail/argument_name.hpp"
3940
#include "detail/concepts.hpp"
4041

4142
#include <algorithm>
@@ -75,95 +76,6 @@ class argument_parser;
7576
/// @brief Internal argument handling utility.
7677
namespace argument::detail {
7778

78-
/// @brief Structure holding the argument name.
79-
struct argument_name {
80-
argument_name() = delete;
81-
82-
argument_name(const argument_name&) = default;
83-
argument_name(argument_name&&) = default;
84-
85-
argument_name& operator=(const argument_name&) = delete;
86-
argument_name& operator=(argument_name&&) = delete;
87-
88-
/**
89-
* @brief Primary name constructor.
90-
* @param primary The primary name of the argument.
91-
*/
92-
argument_name(std::string_view primary) : primary(primary) {}
93-
94-
/**
95-
* @brief Primary and secondary name constructor.
96-
* @param primary The primary name of the argument.
97-
* @param secondary The secondary (short) name of the argument.
98-
*/
99-
argument_name(std::string_view primary, std::string_view secondary)
100-
: primary(primary), secondary(secondary) {}
101-
102-
/// @brief Class destructor.
103-
~argument_name() = default;
104-
105-
/**
106-
* @brief Equality comparison operator.
107-
* @param other The argument_name instance to compare with.
108-
* @return Equality of argument names.
109-
*/
110-
bool operator==(const argument_name& other) const noexcept {
111-
if (not (this->secondary and other.secondary) and (this->secondary or other.secondary))
112-
return false;
113-
114-
if (this->primary != other.primary)
115-
return false;
116-
117-
return this->secondary ? this->secondary.value() == other.secondary.value() : true;
118-
}
119-
120-
/**
121-
* @brief Matches the given string to the argument_name instance.
122-
* @param arg_name The name string to match.
123-
* @return True if name is equal to either the primary or the secondary name of the argument_name instance.
124-
*/
125-
[[nodiscard]] bool match(std::string_view arg_name) const noexcept {
126-
return arg_name == this->primary
127-
or (this->secondary and arg_name == this->secondary.value());
128-
}
129-
130-
/**
131-
* @brief Matches the given argument name to the argument_name instance.
132-
* @param arg_name The argument_name instance to match.
133-
* @return True if arg_name's primary or secondary value matches the argument_name instance.
134-
*/
135-
[[nodiscard]] bool match(const argument_name& arg_name) const noexcept {
136-
if (this->match(arg_name.primary))
137-
return true;
138-
139-
if (arg_name.secondary)
140-
return this->match(arg_name.secondary.value());
141-
142-
return false;
143-
}
144-
145-
/// @brief Get a string representation of the argument_name.
146-
[[nodiscard]] std::string str() const noexcept {
147-
return this->secondary
148-
? ("[" + this->primary + "," + this->secondary.value() + "]")
149-
: ("[" + this->primary + "]");
150-
}
151-
152-
/**
153-
* @brief Stream insertion operator for argument names.
154-
* @param os The output stream.
155-
* @param arg_name The argument name to be inserted into the stream.
156-
* @return The modified output stream.
157-
*/
158-
friend std::ostream& operator<<(std::ostream& os, const argument_name& arg_name) noexcept {
159-
os << arg_name.str();
160-
return os;
161-
}
162-
163-
const std::string primary; ///< The primary name of the argument.
164-
const std::optional<std::string> secondary; ///< The optional (short) name of the argument.
165-
};
166-
16779
/// @brief Argument class interface
16880
class argument_interface {
16981
public:
@@ -196,7 +108,7 @@ class argument_interface {
196108

197109
protected:
198110
/// @return Reference to the name of the argument.
199-
virtual const argument_name& name() const noexcept = 0;
111+
virtual const ap::detail::argument_name& name() const noexcept = 0;
200112

201113
/// @return True if the argument is required, false otherwise
202114
virtual bool is_required() const noexcept = 0;
@@ -266,7 +178,7 @@ class value_already_set_error : public argument_parser_error {
266178
* @brief Constructor for the value_already_set_error class.
267179
* @param arg_name The name of the argument that already has a value set.
268180
*/
269-
explicit value_already_set_error(const argument::detail::argument_name& arg_name)
181+
explicit value_already_set_error(const detail::argument_name& arg_name)
270182
: argument_parser_error(
271183
std::format("Value for argument {} has already been set.", arg_name.str())
272184
) {}
@@ -280,9 +192,7 @@ class invalid_value_error : public argument_parser_error {
280192
* @param arg_name The name of the argument for which the value parsing failed.
281193
* @param value The value that failed to parse.
282194
*/
283-
explicit invalid_value_error(
284-
const argument::detail::argument_name& arg_name, const std::string& value
285-
)
195+
explicit invalid_value_error(const detail::argument_name& arg_name, const std::string& value)
286196
: argument_parser_error(
287197
std::format("Cannot parse value `{}` for argument {}.", value, arg_name.str())
288198
) {}
@@ -296,9 +206,7 @@ class invalid_choice_error : public argument_parser_error {
296206
* @param arg_name The name of the argument for which the value is not in choices.
297207
* @param value The value that is not in the allowed choices.
298208
*/
299-
explicit invalid_choice_error(
300-
const argument::detail::argument_name& arg_name, const std::string& value
301-
)
209+
explicit invalid_choice_error(const detail::argument_name& arg_name, const std::string& value)
302210
: argument_parser_error(
303211
std::format("Value `{}` is not a valid choice for argument {}.", value, arg_name.str())
304212
) {}
@@ -311,7 +219,7 @@ class argument_name_used_error : public argument_parser_error {
311219
* @brief Constructor for the argument_name_used_error class.
312220
* @param arg_name The name of the argument causing the collision.
313221
*/
314-
explicit argument_name_used_error(const argument::detail::argument_name& arg_name)
222+
explicit argument_name_used_error(const detail::argument_name& arg_name)
315223
: argument_parser_error(std::format("Given name `{}` already used.", arg_name.str())) {}
316224
};
317225

@@ -335,7 +243,7 @@ class invalid_value_type_error : public argument_parser_error {
335243
* @param value_type The type information that failed to cast.
336244
*/
337245
explicit invalid_value_type_error(
338-
const argument::detail::argument_name& arg_name, const std::type_info& value_type
246+
const detail::argument_name& arg_name, const std::type_info& value_type
339247
)
340248
: argument_parser_error(std::format(
341249
"Invalid value type specified for argument {} = {}.", arg_name.str(), value_type.name()
@@ -349,7 +257,7 @@ class required_argument_not_parsed_error : public argument_parser_error {
349257
* @brief Constructor for the required_argument_not_parsed_error class.
350258
* @param arg_name The name of the required argument that was not parsed.
351259
*/
352-
explicit required_argument_not_parsed_error(const argument::detail::argument_name& arg_name)
260+
explicit required_argument_not_parsed_error(const detail::argument_name& arg_name)
353261
: argument_parser_error("No values parsed for a required argument " + arg_name.str()) {}
354262
};
355263

@@ -376,7 +284,7 @@ class invalid_nvalues_error : public argument_parser_error {
376284
* @return The error message.
377285
*/
378286
[[nodiscard]] static std::string msg(
379-
const std::weak_ordering ordering, const argument::detail::argument_name& arg_name
287+
const std::weak_ordering ordering, const detail::argument_name& arg_name
380288
) {
381289
if (std::is_lt(ordering))
382290
return "Too few values provided for optional argument " + arg_name.str();
@@ -390,7 +298,7 @@ class invalid_nvalues_error : public argument_parser_error {
390298
* @param arg_name The name of the argument for which the error occurred.
391299
*/
392300
explicit invalid_nvalues_error(
393-
const std::weak_ordering ordering, const argument::detail::argument_name& arg_name
301+
const std::weak_ordering ordering, const detail::argument_name& arg_name
394302
)
395303
: argument_parser_error(invalid_nvalues_error::msg(ordering, arg_name)) {}
396304
};
@@ -617,7 +525,7 @@ class positional_argument : public detail::argument_interface {
617525
* @brief Constructor for positional_argument with the `name` identifier.
618526
* @param name The `name` identifier of the positional argument.
619527
*/
620-
positional_argument(const detail::argument_name& name) : _name(name) {}
528+
positional_argument(const ap::detail::argument_name& name) : _name(name) {}
621529

622530
~positional_argument() = default;
623531

@@ -685,7 +593,7 @@ class positional_argument : public detail::argument_interface {
685593

686594
private:
687595
/// @return Reference the name of the positional argument.
688-
[[nodiscard]] const detail::argument_name& name() const noexcept override {
596+
[[nodiscard]] const ap::detail::argument_name& name() const noexcept override {
689597
return this->_name;
690598
}
691599

@@ -803,7 +711,7 @@ class positional_argument : public detail::argument_interface {
803711
using action_type = ap::action::detail::action_variant_type<T>;
804712

805713
static constexpr bool _optional = false;
806-
const detail::argument_name _name;
714+
const ap::detail::argument_name _name;
807715
std::optional<std::string> _help_msg;
808716

809717
static constexpr bool _required = true; ///< Positional arguments are required by default.
@@ -834,7 +742,7 @@ class optional_argument : public detail::argument_interface {
834742
* @brief Constructor for optional_argument with the `name` identifier.
835743
* @param name The `name` identifier of the optional argument.
836744
*/
837-
optional_argument(const detail::argument_name& name) : _name(name) {}
745+
optional_argument(const ap::detail::argument_name& name) : _name(name) {}
838746

839747
~optional_argument() = default;
840748

@@ -970,7 +878,7 @@ class optional_argument : public detail::argument_interface {
970878

971879
private:
972880
/// @return Reference to the name of the optional argument.
973-
[[nodiscard]] const detail::argument_name& name() const noexcept override {
881+
[[nodiscard]] const ap::detail::argument_name& name() const noexcept override {
974882
return this->_name;
975883
}
976884

@@ -1112,7 +1020,7 @@ class optional_argument : public detail::argument_interface {
11121020
using action_type = ap::action::detail::action_variant_type<T>;
11131021

11141022
static constexpr bool _optional = true;
1115-
const detail::argument_name _name;
1023+
const ap::detail::argument_name _name;
11161024
std::optional<std::string> _help_msg;
11171025

11181026
bool _required = false;
@@ -1215,7 +1123,7 @@ class argument_parser {
12151123
argument::positional_argument<T>& add_positional_argument(std::string_view primary_name) {
12161124
// TODO: check forbidden characters
12171125

1218-
const argument::detail::argument_name arg_name = {primary_name};
1126+
const ap::detail::argument_name arg_name = {primary_name};
12191127
if (this->_is_arg_name_used(arg_name))
12201128
throw error::argument_name_used_error(arg_name);
12211129

@@ -1238,7 +1146,7 @@ class argument_parser {
12381146
) {
12391147
// TODO: check forbidden characters
12401148

1241-
const argument::detail::argument_name arg_name = {primary_name, secondary_name};
1149+
const ap::detail::argument_name arg_name = {primary_name, secondary_name};
12421150
if (this->_is_arg_name_used(arg_name))
12431151
throw error::argument_name_used_error(arg_name);
12441152

@@ -1258,7 +1166,7 @@ class argument_parser {
12581166
argument::optional_argument<T>& add_optional_argument(std::string_view primary_name) {
12591167
// TODO: check forbidden characters
12601168

1261-
const argument::detail::argument_name arg_name = {primary_name};
1169+
const ap::detail::argument_name arg_name = {primary_name};
12621170
if (this->_is_arg_name_used(arg_name))
12631171
throw error::argument_name_used_error(arg_name);
12641172

@@ -1279,7 +1187,7 @@ class argument_parser {
12791187
) {
12801188
// TODO: check forbidden characters
12811189

1282-
const argument::detail::argument_name arg_name = {primary_name, secondary_name};
1190+
const ap::detail::argument_name arg_name = {primary_name, secondary_name};
12831191
if (this->_is_arg_name_used(arg_name))
12841192
throw error::argument_name_used_error(arg_name);
12851193

@@ -1554,7 +1462,7 @@ class argument_parser {
15541462
* @return Argument predicate based on the provided name.
15551463
*/
15561464
[[nodiscard]] argument_predicate_type _name_match_predicate(
1557-
const argument::detail::argument_name& arg_name
1465+
const ap::detail::argument_name& arg_name
15581466
) const noexcept {
15591467
return [&arg_name](const argument_ptr_type& arg) { return arg->name().match(arg_name); };
15601468
}
@@ -1564,8 +1472,7 @@ class argument_parser {
15641472
* @param arg_name The name of the argument.
15651473
* @return True if the argument name is already used, false otherwise.
15661474
*/
1567-
[[nodiscard]] bool _is_arg_name_used(const argument::detail::argument_name& arg_name
1568-
) const noexcept {
1475+
[[nodiscard]] bool _is_arg_name_used(const ap::detail::argument_name& arg_name) const noexcept {
15691476
const auto predicate = this->_name_match_predicate(arg_name);
15701477

15711478
if (std::ranges::find_if(this->_positional_args, predicate) != this->_positional_args.end())

0 commit comments

Comments
 (0)