kaycxx-cli
C++ CLI library
Loading...
Searching...
No Matches
option.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Klaus Reimer <k@ailis.de>
2// SPDX-License-Identifier: MIT
3
9#pragma once
10
11#include <any>
12#include <format>
13#include <optional>
14#include <stdexcept>
15#include <string>
16#include <string_view>
17#include <utility>
18#include <vector>
19
20#include <kaycxx/cli/detail/to_string.hpp>
23
24namespace kaycxx::cli {
25
26template <parseable_value T>
27class option_handle;
28
29template <parseable_value T>
30class repeatable_option_handle;
31
35class option_base : public switch_base {
36public:
38
44 [[nodiscard]] virtual std::string const& value_name() const noexcept = 0;
45
52
59 return default_value_text_;
60 }
61
68 return required_;
69 }
70
77 return repeatable_;
78 }
79
80protected:
86 void mark_as_defaulted(std::string text) {
87 if (required_) {
88 throw std::invalid_argument{std::format("Option --{} cannot be both required and defaulted", name())};
89 }
90 default_value_text_ = std::move(text);
91 }
92
93private:
94 friend class command;
95
96 template <parseable_value T>
97 friend class option_handle;
98
99 template <parseable_value T>
100 friend class repeatable_option_handle;
101
107 void mark_as_required() {
108 if (default_value_text_) {
109 throw std::invalid_argument{std::format("Option --{} cannot be both required and defaulted", name())};
110 }
111 required_ = true;
112 }
113
115 void mark_as_repeatable() noexcept {
116 repeatable_ = true;
117 }
118
128 [[nodiscard]] virtual std::any parse_value(std::string_view text) const = 0;
129
138 virtual void append_value(std::any& storage, std::string_view text) const = 0;
139
141 bool repeatable_ = false;
142
144 bool required_ = false;
145
147 std::optional<std::string> default_value_text_;
148};
149
155template <parseable_value T>
156class option : public option_base {
157public:
165 explicit option(std::string_view name, std::string_view value_name, std::optional<std::string_view> description = std::nullopt)
167 value_name_(value_name) {}
168
177 explicit option(std::string_view name, char alias, std::string_view value_name, std::optional<std::string_view> description = std::nullopt)
179 value_name_(value_name) {}
180
186 [[nodiscard]] std::string const& value_name() const noexcept override {
187 return value_name_;
188 }
189
200 mark_as_defaulted(detail::to_string(value));
201 default_value_ = std::move(value);
202 }
203
209 [[nodiscard]] std::string usage() const override {
210 if (auto alias = this->alias()) {
211 return std::format("-{}, --{} <{}>", *alias, name(), value_name_);
212 }
213
214 return std::format(" --{} <{}>", name(), value_name_);
215 }
216
222 [[nodiscard]] bool expects_value() const noexcept override {
223 return true;
224 }
225
231 [[nodiscard]] std::optional<std::any> default_value() const override {
232 if (default_value_) {
233 if (is_repeatable()) {
234 auto values = std::vector<T>();
235 values.push_back(*default_value_);
236 return std::any(std::move(values));
237 }
238 return std::any(*default_value_);
239 }
240
241 return std::nullopt;
242 }
243
244private:
254 [[nodiscard]] std::any parse_value(std::string_view text) const override {
255 return detail::parse_value<T>(text);
256 }
257
266 void append_value(std::any& storage, std::string_view text) const override {
267 auto value = detail::parse_value<T>(text);
268 if (!storage.has_value()) {
269 storage = std::vector<T>();
270 }
271 std::any_cast<std::vector<T>&>(storage).push_back(std::move(value));
272 }
273
275 std::string value_name_;
276
278 std::optional<T> default_value_;
279};
280
281} // namespace kaycxx::cli
Common base class for an application and its commands.
Definition command.hpp:45
Common base class for typed options.
Definition option.hpp:35
virtual std::string const & value_name() const noexcept=0
Returns the value placeholder name.
bool is_required() const noexcept
Checks whether this option must be specified explicitly.
Definition option.hpp:67
void mark_as_defaulted(std::string text)
Marks this option as having a default value.
Definition option.hpp:86
bool is_repeatable() const noexcept
Checks whether this option accepts multiple occurrences.
Definition option.hpp:76
std::optional< std::string > const & default_value_text() const noexcept
Returns the configured default value rendered for help output.
Definition option.hpp:58
virtual std::optional< std::any > default_value() const =0
Returns the configured default value.
Handle for a registered option.
Definition option_handle.hpp:25
Typed command line option definition.
Definition option.hpp:156
std::string const & value_name() const noexcept override
Returns the value placeholder name.
Definition option.hpp:186
bool expects_value() const noexcept override
Checks whether this option expects a value.
Definition option.hpp:222
std::string usage() const override
Returns generated help usage for this option.
Definition option.hpp:209
std::optional< std::any > default_value() const override
Returns the configured default value.
Definition option.hpp:231
option(std::string_view name, std::string_view value_name, std::optional< std::string_view > description=std::nullopt)
Creates an option without a short alias.
Definition option.hpp:165
void default_value(T value)
Sets the default option value.
Definition option.hpp:199
option(std::string_view name, char alias, std::string_view value_name, std::optional< std::string_view > description=std::nullopt)
Creates an option with a short alias.
Definition option.hpp:177
Handle for a registered repeatable option.
Definition repeatable_option_handle.hpp:25
Common base class for command line switches.
Definition switch_base.hpp:22
std::optional< std::string > const & description() const noexcept
Returns the switch description.
std::optional< char > alias() const noexcept
Returns the short switch alias.
switch_base(std::string_view name, std::optional< std::string_view > description=std::nullopt)
Creates a switch without a short alias.
std::string const & name() const noexcept
Returns the long switch name.
Defines value parsing support used by typed options and positional parameters.
Defines the common base class for flags and options.