CPP-AP 2.2.6
Command-line argument parser for C++20
Loading...
Searching...
No Matches
argument_descriptor.hpp
Go to the documentation of this file.
1// Copyright (c) 2023-2025 Jakub MusiaƂ
2// This file is part of the CPP-AP project (https://github.com/SpectraL519/cpp-ap).
3// Licensed under the MIT License. See the LICENSE file in the project root for full license information.
4
10#pragma once
11
13#include "concepts.hpp"
14#include "str_utility.hpp"
15
16#include <cstdint>
17#include <format>
18#include <iomanip>
19#include <optional>
20#include <sstream>
21#include <vector>
22
23namespace ap::detail {
24
27 std::string name;
28 std::string value;
29};
30
33public:
38 argument_descriptor(const std::string& name, const std::optional<std::string>& help)
39 : name(name), help(help) {}
40
46 void add_param(const std::string& name, const std::string& value) {
47 this->params.emplace_back(name, value);
48 }
49
56 template <c_writable T>
57 void add_param(const std::string& name, const T& value) {
58 std::ostringstream oss;
59 oss << std::boolalpha << value;
60 this->params.emplace_back(name, oss.str());
61 }
62
70 template <std::ranges::range R>
73 const std::string& name,
74 const R& range,
75 const std::string_view delimiter = default_delimiter
76 ) {
77 this->params.emplace_back(name, join(range, delimiter));
78 }
79
86 [[nodiscard]] std::string get_basic(
87 const uint8_t indent_width, const std::optional<std::size_t> align_to = std::nullopt
88 ) const {
89 std::ostringstream oss;
90
91 oss << std::string(indent_width, ' ');
92 if (align_to.has_value())
93 oss << std::setw(static_cast<int>(align_to.value())) << std::left;
94 oss << this->name;
95
96 if (this->help.has_value())
97 oss << " : " << this->help.value();
98
99 return oss.str();
100 }
101
120 [[nodiscard]] std::string get(
121 const uint8_t indent_width, std::optional<std::size_t> max_line_width = std::nullopt
122 ) const {
123 std::ostringstream oss;
124
125 if (this->params.empty())
126 return this->_get_single_line(indent_width);
127
128 if (max_line_width.has_value()) {
129 std::string single_line_str = this->_get_single_line(indent_width);
130 if (single_line_str.size() <= max_line_width.value())
131 return single_line_str;
132 }
133
134 return this->_get_multi_line(indent_width);
135 }
136
137 std::string name;
138 std::optional<std::string> help;
139 std::vector<parameter_descriptor> params;
140
141private:
147 // clang-format off
148 [[nodiscard]] std::string _get_single_line(const uint8_t indent_width) const {
149 std::ostringstream oss;
150
151 oss << this->get_basic(indent_width);
152 if (not this->params.empty()) {
153 oss << " ("
154 << join(this->params | std::views::transform(
155 [](const auto& param) { return std::format("{}: {}", param.name, param.value); }
156 ))
157 << ")";
158 }
159
160 return oss.str();
161 }
162
163 // clang-format on
164
170 [[nodiscard]] std::string _get_multi_line(const uint8_t indent_width) const {
171 std::ostringstream oss;
172
173 oss << this->get_basic(indent_width);
174
175 std::size_t max_param_name_len = 0ull;
176 for (const auto& param : this->params)
177 max_param_name_len = std::max(max_param_name_len, param.name.size());
178
179 for (const auto& param : this->params) {
180 oss << "\n"
181 << std::string(indent_width * 2, ' ') << "- "
182 << std::setw(static_cast<int>(max_param_name_len)) << std::left << param.name
183 << " = " << param.value;
184 }
185
186 return oss.str();
187 }
188
189 static constexpr std::string_view default_delimiter = ", ";
190};
191
192} // namespace ap::detail
A structure used to represent an argument's description.
std::string get(const uint8_t indent_width, std::optional< std::size_t > max_line_width=std::nullopt) const
std::string get_basic(const uint8_t indent_width, const std::optional< std::size_t > align_to=std::nullopt) const
argument_descriptor(const std::string &name, const std::optional< std::string > &help)
void add_range_param(const std::string &name, const R &range, const std::string_view delimiter=default_delimiter)
Adds a range parameter descriptor with the given value.
void add_param(const std::string &name, const T &value)
Adds a parameter descriptor with the given value.
void add_param(const std::string &name, const std::string &value)
Adds a parameter descriptor with the given string value.
The concept is satisfied when T overloads the std::ostream operator <<.
Definition concepts.hpp:29
Provides the general concept definitions.
Provides common string utility functions.
std::string join(const R &range, const std::string_view delimiter=", ")
Joins elements of a range into a single string with a delimiter.
A structure used to represent an argument's parameter description.