From 49a7743d8cf63e98e8523a7d5c408c34f5985fcd Mon Sep 17 00:00:00 2001 From: Philip Top Date: Sat, 18 Apr 2026 06:24:25 -0700 Subject: [PATCH 1/5] add test for enumeration conversion --- tests/NewParseTest.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/NewParseTest.cpp b/tests/NewParseTest.cpp index 4cf302e79..7031defa6 100644 --- a/tests/NewParseTest.cpp +++ b/tests/NewParseTest.cpp @@ -11,6 +11,7 @@ #include #include #include +#include using cx = std::complex; @@ -645,3 +646,51 @@ TEST_CASE_METHOD(TApp, "vectorComplex", "[newparse]") { CHECK(1.4 == vcomplex[1].real()); CHECK(-4.0 == vcomplex[1].imag()); } + +// enumeration with stream operator +#define COLOR_LIST \ + X(Red) \ + X(Blue) \ + X(Green) \ + +enum class Color { +#define X(name) name, + COLOR_LIST +#undef X +}; + +const std::unordered_map STR_TO_COLOR_MAP { +#define X(name) {#name, Color::name}, + COLOR_LIST +#undef X +}; + +const std::unordered_map COLOR_TO_STR_MAP { +#define X(name) {Color::name, #name}, + COLOR_LIST +#undef X +}; + +// Comment this to stop CLI::ConversionError from being thrown +std::ostream& operator<<(std::ostream& os, Color c) { + auto it = COLOR_TO_STR_MAP.find(c); + if (it != COLOR_TO_STR_MAP.end()) + return os << it->second; + + return os << std::string("Unknown"); +} + +TEST_CASE_METHOD(TApp, "enumDefaultParse", "[newparse]") { + Color color; + app.add_option("--color", color) + ->default_val(Color::Red) + ->transform(CLI::CheckedTransformer(STR_TO_COLOR_MAP)); + + args = {}; + run(); + CHECK(color==Color::Red); + + args={"--color","Green"}; + run(); + CHECK(color==Color::Green); +} From bed5e0f7088926d2784f287716b95bab7d660b29 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Sat, 18 Apr 2026 06:43:16 -0700 Subject: [PATCH 2/5] add more tests --- tests/NewParseTest.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/NewParseTest.cpp b/tests/NewParseTest.cpp index 7031defa6..ebfa52375 100644 --- a/tests/NewParseTest.cpp +++ b/tests/NewParseTest.cpp @@ -682,9 +682,10 @@ std::ostream& operator<<(std::ostream& os, Color c) { TEST_CASE_METHOD(TApp, "enumDefaultParse", "[newparse]") { Color color; + Color other_color; app.add_option("--color", color) ->default_val(Color::Red) - ->transform(CLI::CheckedTransformer(STR_TO_COLOR_MAP)); + ->transform(CLI::CheckedTransformer(STR_TO_COLOR_MAP))->force_callback(); args = {}; run(); @@ -693,4 +694,13 @@ TEST_CASE_METHOD(TApp, "enumDefaultParse", "[newparse]") { args={"--color","Green"}; run(); CHECK(color==Color::Green); + + app.add_option("--color2", other_color) + ->default_str("Green") + ->transform(CLI::CheckedTransformer(STR_TO_COLOR_MAP))->force_callback(); + + args={"--color","Blue"}; + run(); + CHECK(color==Color::Blue); + CHECK(other_color==Color::Green); } From d4f47bf308486037920c2db31e9d42bf11250aaf Mon Sep 17 00:00:00 2001 From: Philip Top Date: Sat, 18 Apr 2026 07:13:28 -0700 Subject: [PATCH 3/5] comment out test if extra validators are not allowed --- tests/NewParseTest.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/NewParseTest.cpp b/tests/NewParseTest.cpp index ebfa52375..9876df580 100644 --- a/tests/NewParseTest.cpp +++ b/tests/NewParseTest.cpp @@ -647,6 +647,9 @@ TEST_CASE_METHOD(TApp, "vectorComplex", "[newparse]") { CHECK(-4.0 == vcomplex[1].imag()); } +#if (defined(CLI11_ENABLE_EXTRA_VALIDATORS) && CLI11_ENABLE_EXTRA_VALIDATORS == 1) || \ + (!defined(CLI11_DISABLE_EXTRA_VALIDATORS) || CLI11_DISABLE_EXTRA_VALIDATORS == 0) + // enumeration with stream operator #define COLOR_LIST \ X(Red) \ @@ -704,3 +707,5 @@ TEST_CASE_METHOD(TApp, "enumDefaultParse", "[newparse]") { CHECK(color==Color::Blue); CHECK(other_color==Color::Green); } + +#endif From 5d02905998dc95078f7458f13998c73913f632d3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 12:19:39 +0000 Subject: [PATCH 4/5] style: pre-commit.ci fixes --- tests/NewParseTest.cpp | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/tests/NewParseTest.cpp b/tests/NewParseTest.cpp index 9876df580..76fc42f42 100644 --- a/tests/NewParseTest.cpp +++ b/tests/NewParseTest.cpp @@ -9,9 +9,9 @@ #include #include #include +#include #include #include -#include using cx = std::complex; @@ -651,10 +651,10 @@ TEST_CASE_METHOD(TApp, "vectorComplex", "[newparse]") { (!defined(CLI11_DISABLE_EXTRA_VALIDATORS) || CLI11_DISABLE_EXTRA_VALIDATORS == 0) // enumeration with stream operator -#define COLOR_LIST \ - X(Red) \ - X(Blue) \ - X(Green) \ +#define COLOR_LIST \ + X(Red) \ + X(Blue) \ + X(Green) enum class Color { #define X(name) name, @@ -662,22 +662,22 @@ enum class Color { #undef X }; -const std::unordered_map STR_TO_COLOR_MAP { +const std::unordered_map STR_TO_COLOR_MAP{ #define X(name) {#name, Color::name}, COLOR_LIST #undef X }; -const std::unordered_map COLOR_TO_STR_MAP { +const std::unordered_map COLOR_TO_STR_MAP{ #define X(name) {Color::name, #name}, COLOR_LIST #undef X }; // Comment this to stop CLI::ConversionError from being thrown -std::ostream& operator<<(std::ostream& os, Color c) { +std::ostream &operator<<(std::ostream &os, Color c) { auto it = COLOR_TO_STR_MAP.find(c); - if (it != COLOR_TO_STR_MAP.end()) + if(it != COLOR_TO_STR_MAP.end()) return os << it->second; return os << std::string("Unknown"); @@ -688,24 +688,26 @@ TEST_CASE_METHOD(TApp, "enumDefaultParse", "[newparse]") { Color other_color; app.add_option("--color", color) ->default_val(Color::Red) - ->transform(CLI::CheckedTransformer(STR_TO_COLOR_MAP))->force_callback(); + ->transform(CLI::CheckedTransformer(STR_TO_COLOR_MAP)) + ->force_callback(); args = {}; run(); - CHECK(color==Color::Red); + CHECK(color == Color::Red); - args={"--color","Green"}; + args = {"--color", "Green"}; run(); - CHECK(color==Color::Green); + CHECK(color == Color::Green); app.add_option("--color2", other_color) ->default_str("Green") - ->transform(CLI::CheckedTransformer(STR_TO_COLOR_MAP))->force_callback(); + ->transform(CLI::CheckedTransformer(STR_TO_COLOR_MAP)) + ->force_callback(); - args={"--color","Blue"}; + args = {"--color", "Blue"}; run(); - CHECK(color==Color::Blue); - CHECK(other_color==Color::Green); + CHECK(color == Color::Blue); + CHECK(other_color == Color::Green); } #endif From e652202a5e632e2574dc2093b27eaddef95057b2 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 29 Jul 2026 18:05:12 -0400 Subject: [PATCH 5/5] test: fix clang-tidy and GCC 4.8 issues in enum conversion test Initialize the test variables (cppcoreguidelines-init-variables) and use std::map for the enum-keyed map, since GCC before 6.1 has no std::hash for enums. Assisted-by: ClaudeCode:claude-fable-5 --- tests/NewParseTest.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/NewParseTest.cpp b/tests/NewParseTest.cpp index 76fc42f42..31350f139 100644 --- a/tests/NewParseTest.cpp +++ b/tests/NewParseTest.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -668,13 +669,14 @@ const std::unordered_map STR_TO_COLOR_MAP{ #undef X }; -const std::unordered_map COLOR_TO_STR_MAP{ +// std::map: GCC < 6.1 has no std::hash for enums +const std::map COLOR_TO_STR_MAP{ #define X(name) {Color::name, #name}, COLOR_LIST #undef X }; -// Comment this to stop CLI::ConversionError from being thrown +// this stream operator triggered the ConversionError in issue #1330 std::ostream &operator<<(std::ostream &os, Color c) { auto it = COLOR_TO_STR_MAP.find(c); if(it != COLOR_TO_STR_MAP.end()) @@ -684,8 +686,8 @@ std::ostream &operator<<(std::ostream &os, Color c) { } TEST_CASE_METHOD(TApp, "enumDefaultParse", "[newparse]") { - Color color; - Color other_color; + Color color{Color::Blue}; + Color other_color{Color::Red}; app.add_option("--color", color) ->default_val(Color::Red) ->transform(CLI::CheckedTransformer(STR_TO_COLOR_MAP))