Fix: Make CXXOPTS_NO_EXCEPTIONS compilable, better try to mimic exceptions

This commit is contained in:
charlydelta 2019-08-02 22:39:33 +02:00
parent 6e31c227e2
commit 5891b6b5df

View File

@ -467,6 +467,25 @@ namespace cxxopts
}
};
template <typename T>
void throw_or_mimic(const std::string& text)
{
static_assert(std::is_base_of<std::exception, T>::value,
"mimic_throw only works on std::exception and deriving classes");
#ifndef CXXOPTS_NO_EXCEPTIONS
// If CXXOPTS_NO_EXCEPTIONS is not defined, just throw
throw T{text};
#else
// Otherwise manually instantiate the exception, print what() to stderr,
// and abort
T exception{text};
std::cerr << exception.what() << std::endl;
std::cerr << "Aborting (exceptions disabled)..." << std::endl;
std::abort();
#endif
}
namespace values
{
namespace
@ -495,22 +514,14 @@ namespace cxxopts
{
if (u > static_cast<U>((std::numeric_limits<T>::min)()))
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw argument_incorrect_type(text);
#else
std::abort();
#endif
throw_or_mimic<argument_incorrect_type>(text);
}
}
else
{
if (u > static_cast<U>((std::numeric_limits<T>::max)()))
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw argument_incorrect_type(text);
#else
std::abort();
#endif
throw_or_mimic<argument_incorrect_type>(text);
}
}
}
@ -544,13 +555,10 @@ namespace cxxopts
template <typename R, typename T>
T
checked_negate(T&&, const std::string& text, std::false_type)
checked_negate(T&& t, const std::string& text, std::false_type)
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw argument_incorrect_type(text);
#else
std::abort();
#endif
throw_or_mimic<argument_incorrect_type>(text);
return t;
}
template <typename T>
@ -562,11 +570,7 @@ namespace cxxopts
if (match.length() == 0)
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw argument_incorrect_type(text);
#else
std::abort();
#endif
throw_or_mimic<argument_incorrect_type>(text);
}
if (match.length(4) > 0)
@ -603,21 +607,13 @@ namespace cxxopts
}
else
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw argument_incorrect_type(text);
#else
std::abort();
#endif
throw_or_mimic<argument_incorrect_type>(text);
}
US next = result * base + digit;
if (result > next)
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw argument_incorrect_type(text);
#else
std::abort();
#endif
throw_or_mimic<argument_incorrect_type>(text);
}
result = next;
@ -643,11 +639,7 @@ namespace cxxopts
std::stringstream in(text);
in >> value;
if (!in) {
#ifndef CXXOPTS_NO_EXCEPTIONS
throw argument_incorrect_type(text);
#else
std::abort();
#endif
throw_or_mimic<argument_incorrect_type>(text);
}
}
@ -727,11 +719,7 @@ namespace cxxopts
return;
}
#ifndef CXXOPTS_NO_EXCEPTIONS
throw argument_incorrect_type(text);
#else
std::abort();
#endif
throw_or_mimic<argument_incorrect_type>(text);
}
inline
@ -1100,11 +1088,7 @@ namespace cxxopts
as() const
{
if (m_value == nullptr) {
#ifndef CXXOPTS_NO_EXCEPTIONS
throw std::domain_error("No value");
#else
std::abort();
#endif
throw_or_mimic<std::domain_error>("No value");
}
#ifdef CXXOPTS_NO_RTTI
@ -1198,11 +1182,7 @@ namespace cxxopts
if (iter == m_options->end())
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw option_not_present_exception(option);
#else
std::abort();
#endif
throw_or_mimic<option_not_present_exception>(option);
}
auto riter = m_results.find(iter->second);
@ -1260,8 +1240,8 @@ namespace cxxopts
std::vector<KeyValue> m_sequential;
};
struct Option
struct Option
{
Option
(
@ -1281,7 +1261,7 @@ namespace cxxopts
std::string desc_;
std::shared_ptr<const Value> value_;
std::string arg_help_;
};
};
class Options
{
@ -1334,20 +1314,20 @@ namespace cxxopts
OptionAdder
add_options(std::string group = "");
void
add_options
(
const std::string& group,
std::initializer_list<Option> options
);
void
add_option
(
const std::string& group,
const Option& option
);
void
add_options
(
const std::string& group,
std::initializer_list<Option> options
);
void
add_option
(
const std::string& group,
const Option& option
);
void
add_option
@ -1588,15 +1568,15 @@ ParseResult::ParseResult
}
inline
void
void
Options::add_options
(
const std::string &group,
std::initializer_list<Option> options
)
)
{
OptionAdder option_adder(*this, group);
for (const auto &option: options)
for (const auto &option: options)
{
option_adder(option.opts_, option.desc_, option.value_, option.arg_help_);
}
@ -1624,11 +1604,7 @@ OptionAdder::operator()
if (result.empty())
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw invalid_option_format_error(opts);
#else
std::abort();
#endif
throw_or_mimic<invalid_option_format_error>(opts);
}
const auto& short_match = result[2];
@ -1636,18 +1612,10 @@ OptionAdder::operator()
if (!short_match.length() && !long_match.length())
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw invalid_option_format_error(opts);
#else
std::abort();
#endif
throw_or_mimic<invalid_option_format_error>(opts);
} else if (long_match.length() == 1 && short_match.length())
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw invalid_option_format_error(opts);
#else
std::abort();
#endif
throw_or_mimic<invalid_option_format_error>(opts);
}
auto option_names = []
@ -1720,11 +1688,7 @@ ParseResult::checked_parse_arg
}
else
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw missing_argument_exception(name);
#else
std::abort();
#endif
throw_or_mimic<missing_argument_exception>(name);
}
}
else
@ -1749,11 +1713,7 @@ ParseResult::add_to_option(const std::string& option, const std::string& arg)
if (iter == m_options->end())
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw option_not_exists_exception(option);
#else
std::abort();
#endif
throw_or_mimic<option_not_exists_exception>(option);
}
parse_option(iter->second, option, arg);
@ -1791,11 +1751,7 @@ ParseResult::consume_positional(std::string a)
}
else
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw option_not_exists_exception(*m_next_positional);
#else
std::abort();
#endif
throw_or_mimic<option_not_exists_exception>(*m_next_positional);
}
}
@ -1863,11 +1819,7 @@ ParseResult::parse(int& argc, char**& argv)
// but if it starts with a `-`, then it's an error
if (argv[current][0] == '-' && argv[current][1] != '\0') {
if (!m_allow_unrecognised) {
#ifndef CXXOPTS_NO_EXCEPTIONS
throw option_syntax_exception(argv[current]);
#else
std::abort();
#endif
throw_or_mimic<option_syntax_exception>(argv[current]);
}
}
@ -1904,11 +1856,7 @@ ParseResult::parse(int& argc, char**& argv)
else
{
//error
#ifndef CXXOPTS_NO_EXCEPTIONS
throw option_not_exists_exception(name);
#else
std::abort();
#endif
throw_or_mimic<option_not_exists_exception>(name);
}
}
@ -1926,11 +1874,7 @@ ParseResult::parse(int& argc, char**& argv)
else
{
//error
#ifndef CXXOPTS_NO_EXCEPTIONS
throw option_requires_argument_exception(name);
#else
std::abort();
#endif
throw_or_mimic<option_requires_argument_exception>(name);
}
}
}
@ -1953,11 +1897,7 @@ ParseResult::parse(int& argc, char**& argv)
else
{
//error
#ifndef CXXOPTS_NO_EXCEPTIONS
throw option_not_exists_exception(name);
#else
std::abort();
#endif
throw_or_mimic<option_not_exists_exception>(name);
}
}
@ -2024,7 +1964,7 @@ Options::add_option
const Option& option
)
{
add_options(group, {option});
add_options(group, {option});
}
inline
@ -2075,11 +2015,7 @@ Options::add_one_option
if (!in.second)
{
#ifndef CXXOPTS_NO_EXCEPTIONS
throw option_exists_error(option);
#else
std::abort();
#endif
throw_or_mimic<option_exists_error>(option);
}
}