mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-05-03 14:03:52 +00:00
Use e.get_name instead of dynamic_cast (#467)
* Use e.get_name instead of dynamic_cast Also use std::static_pointer_cast instead of std::dynamic_pointer_cast Fixes #466 * feat: Allow RTTI to be turned off * ci: Fix CXX flags * doc: Adding update to book Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
parent
a8185bb499
commit
ccb1ccaa0a
@ -63,7 +63,11 @@ jobs:
|
|||||||
Windowslatest:
|
Windowslatest:
|
||||||
vmImage: 'windows-2019'
|
vmImage: 'windows-2019'
|
||||||
cli11.std: 20
|
cli11.std: 20
|
||||||
cli11.options: -DCMAKE_CXX_FLAG="/std:c++latest"
|
cli11.options: -DCMAKE_CXX_FLAGS="/std:c++latest /EHsc"
|
||||||
|
Linux17nortti:
|
||||||
|
vmImage: 'ubuntu-latest'
|
||||||
|
cli11.std: 17
|
||||||
|
cli11.options: -DCMAKE_CXX_FLAGS="-fno-rtti"
|
||||||
pool:
|
pool:
|
||||||
vmImage: $(vmImage)
|
vmImage: $(vmImage)
|
||||||
steps:
|
steps:
|
||||||
|
@ -115,7 +115,8 @@ The default configuration file will read TOML files, but will write out files in
|
|||||||
```cpp
|
```cpp
|
||||||
app.config_formatter(std::make_shared<CLI::ConfigTOML>());
|
app.config_formatter(std::make_shared<CLI::ConfigTOML>());
|
||||||
```
|
```
|
||||||
which makes use of a predefined modification of the ConfigBase class which INI also uses.
|
|
||||||
|
which makes use of a predefined modification of the ConfigBase class which INI also uses. If a custom formatter is used that is not inheriting from the from ConfigBase class `get_config_formatter_base() will return a nullptr if RTTI is on (usually the default), or garbage if RTTI is off, so some care must be exercised in its use with custom configurations.
|
||||||
|
|
||||||
## Custom formats
|
## Custom formats
|
||||||
|
|
||||||
|
@ -1314,15 +1314,15 @@ class App {
|
|||||||
int exit(const Error &e, std::ostream &out = std::cout, std::ostream &err = std::cerr) const {
|
int exit(const Error &e, std::ostream &out = std::cout, std::ostream &err = std::cerr) const {
|
||||||
|
|
||||||
/// Avoid printing anything if this is a CLI::RuntimeError
|
/// Avoid printing anything if this is a CLI::RuntimeError
|
||||||
if(dynamic_cast<const CLI::RuntimeError *>(&e) != nullptr)
|
if(e.get_name() == "RuntimeError")
|
||||||
return e.get_exit_code();
|
return e.get_exit_code();
|
||||||
|
|
||||||
if(dynamic_cast<const CLI::CallForHelp *>(&e) != nullptr) {
|
if(e.get_name() == "CallForHelp") {
|
||||||
out << help();
|
out << help();
|
||||||
return e.get_exit_code();
|
return e.get_exit_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dynamic_cast<const CLI::CallForAllHelp *>(&e) != nullptr) {
|
if(e.get_name() == "CallForAllHelp") {
|
||||||
out << help("", AppFormatMode::All);
|
out << help("", AppFormatMode::All);
|
||||||
return e.get_exit_code();
|
return e.get_exit_code();
|
||||||
}
|
}
|
||||||
@ -1524,7 +1524,12 @@ class App {
|
|||||||
|
|
||||||
/// Access the config formatter as a configBase pointer
|
/// Access the config formatter as a configBase pointer
|
||||||
std::shared_ptr<ConfigBase> get_config_formatter_base() const {
|
std::shared_ptr<ConfigBase> get_config_formatter_base() const {
|
||||||
|
// This is safer as a dynamic_cast if we have RTTI, as Config -> ConfigBase
|
||||||
|
#if defined(__cpp_rtti) || (defined(__GXX_RTTI) && __GXX_RTTI) || (defined(_HAS_STATIC_RTTI) && (_HAS_STATIC_RTTI == 0))
|
||||||
return std::dynamic_pointer_cast<ConfigBase>(config_formatter_);
|
return std::dynamic_pointer_cast<ConfigBase>(config_formatter_);
|
||||||
|
#else
|
||||||
|
return std::static_pointer_cast<ConfigBase>(config_formatter_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the app or subcommand description
|
/// Get the app or subcommand description
|
||||||
|
@ -506,7 +506,7 @@ class Option : public OptionBase<Option> {
|
|||||||
|
|
||||||
/// Can find a string if needed
|
/// Can find a string if needed
|
||||||
template <typename T = App> Option *needs(std::string opt_name) {
|
template <typename T = App> Option *needs(std::string opt_name) {
|
||||||
auto opt = dynamic_cast<T *>(parent_)->get_option_no_throw(opt_name);
|
auto opt = static_cast<T *>(parent_)->get_option_no_throw(opt_name);
|
||||||
if(opt == nullptr) {
|
if(opt == nullptr) {
|
||||||
throw IncorrectConstruction::MissingOption(opt_name);
|
throw IncorrectConstruction::MissingOption(opt_name);
|
||||||
}
|
}
|
||||||
@ -548,7 +548,7 @@ class Option : public OptionBase<Option> {
|
|||||||
|
|
||||||
/// Can find a string if needed
|
/// Can find a string if needed
|
||||||
template <typename T = App> Option *excludes(std::string opt_name) {
|
template <typename T = App> Option *excludes(std::string opt_name) {
|
||||||
auto opt = dynamic_cast<T *>(parent_)->get_option_no_throw(opt_name);
|
auto opt = static_cast<T *>(parent_)->get_option_no_throw(opt_name);
|
||||||
if(opt == nullptr) {
|
if(opt == nullptr) {
|
||||||
throw IncorrectConstruction::MissingOption(opt_name);
|
throw IncorrectConstruction::MissingOption(opt_name);
|
||||||
}
|
}
|
||||||
@ -585,7 +585,7 @@ class Option : public OptionBase<Option> {
|
|||||||
template <typename T = App> Option *ignore_case(bool value = true) {
|
template <typename T = App> Option *ignore_case(bool value = true) {
|
||||||
if(!ignore_case_ && value) {
|
if(!ignore_case_ && value) {
|
||||||
ignore_case_ = value;
|
ignore_case_ = value;
|
||||||
auto *parent = dynamic_cast<T *>(parent_);
|
auto *parent = static_cast<T *>(parent_);
|
||||||
for(const Option_p &opt : parent->options_) {
|
for(const Option_p &opt : parent->options_) {
|
||||||
if(opt.get() == this) {
|
if(opt.get() == this) {
|
||||||
continue;
|
continue;
|
||||||
@ -610,7 +610,7 @@ class Option : public OptionBase<Option> {
|
|||||||
|
|
||||||
if(!ignore_underscore_ && value) {
|
if(!ignore_underscore_ && value) {
|
||||||
ignore_underscore_ = value;
|
ignore_underscore_ = value;
|
||||||
auto *parent = dynamic_cast<T *>(parent_);
|
auto *parent = static_cast<T *>(parent_);
|
||||||
for(const Option_p &opt : parent->options_) {
|
for(const Option_p &opt : parent->options_) {
|
||||||
if(opt.get() == this) {
|
if(opt.get() == this) {
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user