Auto.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <optional>
7 #include <ostream>
8 #include <string>
9 #include <utility>
10 
11 #include "Options/Options.hpp"
12 #include "Utilities/GetOutput.hpp"
13 
14 namespace Options {
15 /// \ingroup OptionParsingGroup
16 /// \brief A class indicating that a parsed value can be automatically
17 /// computed instead of specified.
18 ///
19 /// When an `Auto<T>` is parsed from an input file, the value may be
20 /// specified either as "Auto" or as a value of type `T`. When this
21 /// class is passed to the constructor of the class taking it as an
22 /// option, it can be implicitly converted to a `std::optional<T>`.
23 ///
24 /// \snippet Test_Auto.cpp example_class
25 /// \snippet Test_Auto.cpp example_create
26 template <typename T>
27 class Auto {
28  public:
29  Auto() = default;
30  explicit Auto(T value) noexcept : value_(std::move(value)) {}
31 
32  // NOLINTNEXTLINE(google-explicit-constructor)
33  operator std::optional<T>() && { return std::move(value_); }
34 
35  // NOLINTNEXTLINE(google-explicit-constructor)
36  operator const std::optional<T>&() const { return value_; }
37 
38  private:
39  std::optional<T> value_{};
40 };
41 
42 template <typename T>
43 std::ostream& operator<<(std::ostream& os, const Auto<T>& x) noexcept {
44  const std::optional<T>& value = x;
45  if (value) {
46  return os << get_output(*value);
47  } else {
48  return os << "Auto";
49  }
50 }
51 
52 template <typename T>
53 struct create_from_yaml<Auto<T>> {
54  template <typename Metavariables>
55  static Auto<T> create(const Option& options) {
56  try {
57  if (options.parse_as<std::string>() == "Auto") {
58 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 8 && __GNUC__ < 10
59 #pragma GCC diagnostic push
60 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
61 #endif // defined(__GNUC__) && !defined(__clang__) && __GNUC__ => 8 && __GNUC__ < 10
62  return {};
63 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 8 && __GNUC__ < 10
64 #pragma GCC diagnostic pop
65 #endif // defined(__GNUC__) && !defined(__clang__) && __GNUC__ => 8 && __GNUC__ < 10
66  }
67  } catch (...) {
68  // The node failed to parse as a string. It is not "Auto".
69  }
70  return Auto<T>{options.parse_as<T>()};
71  }
72 };
73 } // namespace Options
std::string
utility
Options.hpp
get_output
std::string get_output(const T &t) noexcept
Get the streamed output of t as a std::string
Definition: GetOutput.hpp:14
Options::Option
Definition: Options.hpp:108
Options
Utilities for parsing input files.
Definition: MinmodType.hpp:8
std::ostream
Options::create_from_yaml
Definition: MinmodType.hpp:11
Options::Auto
A class indicating that a parsed value can be automatically computed instead of specified.
Definition: Auto.hpp:27
Options::Option::parse_as
T parse_as() const
Convert to an object of type T.
Definition: ParseOptions.hpp:75
optional
ostream
string