From 34784b01f7bdb989e56f268b632091a8a8738906 Mon Sep 17 00:00:00 2001 From: charlydelta <46491912+charlydelta@users.noreply.github.com> Date: Thu, 8 Aug 2019 00:25:34 +0200 Subject: [PATCH] Fix: Make CXXOPTS_NO_EXCEPTIONS compilable and print messages (#196) --- include/cxxopts.hpp | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------ 1 file changed, 63 insertions(+), 126 deletions(-) diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index 0e1aa40..9cde72d 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -467,6 +467,26 @@ namespace cxxopts } }; + template + void throw_or_mimic(const std::string& text) + { + static_assert(std::is_base_of::value, + "throw_or_mimic 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 +515,14 @@ namespace cxxopts { if (u > static_cast((std::numeric_limits::min)())) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic(text); } } else { if (u > static_cast((std::numeric_limits::max)())) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic(text); } } } @@ -544,13 +556,10 @@ namespace cxxopts template 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(text); + return t; } template @@ -562,11 +571,7 @@ namespace cxxopts if (match.length() == 0) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic(text); } if (match.length(4) > 0) @@ -603,21 +608,13 @@ namespace cxxopts } else { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic(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(text); } result = next; @@ -643,11 +640,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(text); } } @@ -727,11 +720,7 @@ namespace cxxopts return; } -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic(text); } inline @@ -1108,11 +1097,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("No value"); } #ifdef CXXOPTS_NO_RTTI @@ -1207,11 +1192,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); } auto riter = m_results.find(iter->second); @@ -1269,8 +1250,8 @@ namespace cxxopts std::vector m_sequential; }; - - struct Option + + struct Option { Option ( @@ -1290,7 +1271,7 @@ namespace cxxopts std::string desc_; std::shared_ptr value_; std::string arg_help_; - }; + }; class Options { @@ -1343,20 +1324,20 @@ namespace cxxopts OptionAdder add_options(std::string group = ""); - - void + + void add_options - ( - const std::string& group, - std::initializer_list