@@ -47,6 +47,7 @@ struct ArgvOption
4747 std::string description;
4848 std::string defaultValue;
4949 std::function<void (std::string_view, SettingsType &)> parse;
50+ std::function<std::string(const SettingsType &)> toString;
5051};
5152
5253template <typename SettingsType>
@@ -109,6 +110,18 @@ class ArgvInfo
109110 return result;
110111 }
111112
113+ std::string toString (const SettingsType &settings) const
114+ {
115+ auto stream = std::ostringstream ();
116+
117+ for (const auto &[key, option] : _options)
118+ {
119+ stream << " \n --" << key << " : " << option.toString (settings);
120+ }
121+
122+ return stream.str ();
123+ }
124+
112125private:
113126 std::string _description;
114127 ArgvOptions<SettingsType> _options;
@@ -119,7 +132,7 @@ struct ArgvReflector;
119132
120133template <typename T>
121134concept ReflectedArgvOption = std::same_as<std::string, decltype (ArgvReflector<T>::getType())>
122- && std::same_as<std::string, decltype (ArgvReflector<T>::display (T()))>
135+ && std::same_as<std::string, decltype (ArgvReflector<T>::toString (T()))>
123136 && std::same_as<T, decltype (ArgvReflector<T>::parse(std::string_view()))>;
124137
125138template <>
@@ -130,7 +143,7 @@ struct ArgvReflector<bool>
130143 return " boolean" ;
131144 }
132145
133- static std::string display (bool value)
146+ static std::string toString (bool value)
134147 {
135148 return value ? " true" : " false" ;
136149 }
@@ -155,7 +168,7 @@ struct ArgvReflector<T>
155168 return std::is_integral_v<T> ? " integer" : " number" ;
156169 }
157170
158- static std::string display (const T &value)
171+ static std::string toString (const T &value)
159172 {
160173 return fmt::format (" {}" , value);
161174 }
@@ -174,7 +187,7 @@ struct ArgvReflector<std::string>
174187 return " string" ;
175188 }
176189
177- static std::string display (const std::string &value)
190+ static std::string toString (const std::string &value)
178191 {
179192 return value;
180193 }
@@ -203,7 +216,7 @@ class ArgvOptionBuilder
203216 template <ReflectedArgvOption T>
204217 ArgvOptionBuilder defaultValue (const T &value)
205218 {
206- _option->defaultValue = ArgvReflector<T>::display (value);
219+ _option->defaultValue = ArgvReflector<T>::toString (value);
207220 return *this ;
208221 }
209222
@@ -221,7 +234,8 @@ using GetOptionType = std::decay_t<std::remove_pointer_t<std::invoke_result_t<Ge
221234
222235template <typename GetterType, typename SettingsType>
223236concept ArgvOptionGetter =
224- std::invocable<GetterType, SettingsType &> && std::is_pointer_v<std::invoke_result_t <GetterType, SettingsType &>>
237+ std::invocable<GetterType, SettingsType &> && std::invocable<GetterType, const SettingsType &>
238+ && std::is_pointer_v<std::invoke_result_t <GetterType, SettingsType &>>
225239 && ReflectedArgvOption<GetOptionType<GetterType, SettingsType>>;
226240
227241template <typename SettingsType>
@@ -249,6 +263,7 @@ class ArgvBuilder
249263 option.key = std::move (key);
250264 option.type = Reflector::getType ();
251265 option.parse = [=](auto data, auto &settings) { *getOptionPtr (settings) = Reflector::parse (data); };
266+ option.toString = [=](const auto &settings) { return Reflector::toString (*getOptionPtr (settings)); };
252267
253268 return ArgvOptionBuilder<SettingsType>(option);
254269 }
@@ -294,4 +309,10 @@ SettingsType parseArgvAs(int argc, const char **argv)
294309 auto map = parseArgv (argc, argv);
295310 return parseArgvAs<SettingsType>(map);
296311}
312+
313+ template <ReflectedArgvSettings SettingsType>
314+ std::string stringifyArgvSettings (const SettingsType &settings)
315+ {
316+ return reflectArgvSettings<SettingsType>().toString (settings);
317+ }
297318}
0 commit comments