Sfoglia il codice sorgente

feat: add initializer_list based construction for default arguments

Sam Jaffe 3 anni fa
parent
commit
55b229841c

+ 5 - 3
include/program_args/arguments.h

@@ -131,6 +131,7 @@ template <typename Impl> struct Arguments<Impl>::Option {
   char abbrev;
   std::string description;
 
+  template <typename T> auto operator=(std::initializer_list<T> value);
   template <typename T> auto operator=(T && value);
   template <typename T> operator T() const;
   bool primed() const;
@@ -143,10 +144,11 @@ struct Arguments<Impl>::WithDefault {
   B impl;
   V default_value;
   template <typename T> operator T() const {
-    if constexpr (std::is_convertible<V, T>{}) {
-      return impl ?: T(default_value);
+    if (impl) { return impl; }
+    if constexpr (std::is_invocable_r<T, V>{}) {
+      return T(default_value());
     } else {
-      return impl ?: T(default_value());
+      return T{default_value};
     }
   }
 };

+ 11 - 0
include/program_args/arguments_impl.hpp

@@ -144,6 +144,17 @@ auto Arguments<Impl>::Option::operator=(T && value) {
   return WithDefault<Option, T>{*this, std::forward<T>(value)};
 }
 
+
+template <typename Impl>
+template <typename T>
+auto Arguments<Impl>::Option::operator=(std::initializer_list<T> value) {
+  if (description.size()) {
+    using ::program::to_string;
+    description += "\n    Default Value: " + to_string(value);
+  }
+  return WithDefault<Option, std::initializer_list<T>>{*this, value};
+}
+
 template <typename Impl> bool Arguments<Impl>::Option::primed() const {
   if (self->primed_) { return true; }
   self->add_options(name, abbrev, description);

+ 4 - 2
test/options_test.cpp

@@ -152,13 +152,15 @@ TEST(LongOptionRepeatTest, RepeatingArgumentsAppends) {
 struct LongOptionRepeatWithDefaultTest
     : program::Arguments<LongOptionRepeatWithDefaultTest> {
   using Arguments::Arguments;
-
-  std::vector<int> port = option("port") = std::vector{8080};
+  
+  std::vector<int> port = option("port") = 8080;
+  std::vector<int> default_ports = option("default_ports") = {80, 443};
 };
 
 TEST(LongOptionRepeatWithDefaultTest, DefaultIsProvided) {
   auto const options = parse<LongOptionRepeatWithDefaultTest>({""});
   EXPECT_THAT(options.port, ElementsAre(8080));
+  EXPECT_THAT(options.default_ports, ElementsAre(80, 443));
 }
 
 TEST(LongOptionRepeatWithDefaultTest, ArgumentOverwritesDefault) {