AutoPas  3.0.0
Loading...
Searching...
No Matches
Option.h
Go to the documentation of this file.
1
7#pragma once
8
9#include <algorithm>
10#include <iterator>
11#include <map>
12#include <set>
13#include <string>
14#include <type_traits>
15#include <vector>
16
18
19namespace autopas {
20inline namespace options {
25template <typename actualOption_T>
26class Option {
27 public:
32 explicit operator bool() = delete;
33
38 static std::set<actualOption_T> getAllOptions() {
39 const auto mapOptionNames = actualOption_T::getOptionNames();
40 std::set<actualOption_T> retSet;
41 std::for_each(mapOptionNames.begin(), mapOptionNames.end(),
42 [&](auto pairOpStr) { retSet.insert(pairOpStr.first); });
43 return retSet;
44 };
45
51 static std::set<actualOption_T> getMostOptions() {
52 const auto allOptions = getAllOptions();
53 const auto discouragedOptions = actualOption_T::getDiscouragedOptions();
54 std::set<actualOption_T> retSet;
55 std::set_difference(allOptions.begin(), allOptions.end(), discouragedOptions.begin(), discouragedOptions.end(),
56 std::inserter(retSet, retSet.begin()));
57 return retSet;
58 }
59
65 [[nodiscard]] std::string to_string(bool fixedLength = false) const {
66 const auto &actualThis = *static_cast<const actualOption_T *>(this);
67 const auto mapOptNames = actualOption_T::getOptionNames(); // <- not copying the map destroys the strings
68 const auto match = mapOptNames.find(actualThis);
69 if (match == mapOptNames.end()) {
70 return "Unknown Option (" + std::to_string(actualThis) + ")";
71 } else {
72 std::string result = match->second;
73 if (fixedLength) {
74 result.resize(maxStringLength(), ' ');
75 }
76 return result;
77 }
78 }
79
84 [[nodiscard]] static size_t maxStringLength() {
85 static size_t maxLength = 0;
86 if (maxLength == 0) {
87 for (const auto &[_, name] : actualOption_T::getOptionNames()) {
88 maxLength = std::max(maxLength, name.size());
89 }
90 }
91 return maxLength;
92 }
93
110 template <class OutputContainer = std::set<actualOption_T>>
111 static OutputContainer parseOptions(const std::string &optionsString) {
113
114 // Shorthand to get everything
115 if (needles.size() == 1 and needles.front() == "all") {
116 if constexpr (std::is_same_v<OutputContainer, std::set<actualOption_T>>) {
117 return actualOption_T::getAllOptions();
118 } else {
119 const auto allOptionsSet = actualOption_T::getAllOptions();
120 OutputContainer allOptionsOut;
121 std::copy(allOptionsSet.begin(), allOptionsSet.end(),
122 std::insert_iterator(allOptionsOut, allOptionsOut.begin()));
123 return allOptionsOut;
124 }
125 }
126
127 // create a map of enum -> string with lowercase enums as a lookup and fill strings in the haystack
128 std::map<std::string, actualOption_T> allOptionNamesLower;
129 std::vector<std::string> haystack;
130 for (auto &[optionEnum, optionString] : actualOption_T::getOptionNames()) {
131 std::transform(optionString.begin(), optionString.end(), optionString.begin(), ::tolower);
132 allOptionNamesLower.emplace(optionString, optionEnum);
133 haystack.push_back(optionString);
134 }
135
136 // convert all needles to options.
137 OutputContainer foundOptions;
138 std::transform(needles.begin(), needles.end(), std::insert_iterator(foundOptions, foundOptions.begin()),
139 [&](const auto &needle) {
140 // first find the best matching string
141 const auto matchingString = autopas::utils::StringUtils::matchStrings(haystack, needle);
142 // then find the corresponding enum and add it to the return set
143 return allOptionNamesLower[matchingString];
144 });
145
146 return foundOptions;
147 }
148
158 template <bool lowercase = false>
159 static actualOption_T parseOptionExact(const std::string &optionString) {
160 for (auto [optionEnum, optionName] : actualOption_T::getOptionNames()) {
161 if constexpr (lowercase) {
162 std::transform(std::begin(optionName), std::end(optionName), std::begin(optionName), ::tolower);
163 }
164 if (optionString == optionName) {
165 return optionEnum;
166 }
167 }
168
169 // the end of the function should not be reached
170 utils::ExceptionHandler::exception("Option::parseOptionExact() no match found for: {}", optionString);
171 return actualOption_T();
172 }
173
180 friend std::ostream &operator<<(std::ostream &os, const Option &option) {
181 os << option.to_string();
182 return os;
183 }
184
191 friend std::istream &operator>>(std::istream &in, actualOption_T &option) {
192 // Buffer for the current char.
193 char c = ' ';
194 // Skip any leading whitespace
195 while (std::iswspace(c)) {
196 in.get(c);
197 }
198 // String that is parsed.
199 std::string str{c};
200 // Concat c to str until an unexpected char is encountered
201 do {
202 in.get(c);
203 str.push_back(c);
204 } while (std::isalnum(c) or c == '_' or c == '-'); // This assumes that an option only contains alphanum, _, or -.
205 // Pop the last char which is an undesired one.
206 str.pop_back();
207
208 // Actual parsing.
209 option = parseOptionExact(str);
210 return in;
211 }
212};
213
220template <typename actualOption_T>
221inline std::string format_as(const Option<actualOption_T> &opt) {
222 return opt.to_string();
223}
224
225} // namespace options
226} // namespace autopas
Base class for autopas options.
Definition: Option.h:26
static std::set< actualOption_T > getAllOptions()
Provides a way to iterate over the possible options.
Definition: Option.h:38
friend std::ostream & operator<<(std::ostream &os, const Option &option)
Stream output operator.
Definition: Option.h:180
static size_t maxStringLength()
Returns the number of characters in the string representation of the longest option.
Definition: Option.h:84
static OutputContainer parseOptions(const std::string &optionsString)
Converts a string of options to a set of enums.
Definition: Option.h:111
static actualOption_T parseOptionExact(const std::string &optionString)
Converts a string to an enum.
Definition: Option.h:159
static std::set< actualOption_T > getMostOptions()
Provides a way to iterate over the possible options minus those that are very unlikely to be on inter...
Definition: Option.h:51
std::string to_string(bool fixedLength=false) const
Converts an Option object to its respective string representation.
Definition: Option.h:65
friend std::istream & operator>>(std::istream &in, actualOption_T &option)
Stream extraction operator.
Definition: Option.h:191
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:64
std::string format_as(const Option< actualOption_T > &opt)
Function required for modern fmt/spdlog integration (fmt v9+).
Definition: Option.h:221
constexpr char delimiters[]
All accepted delimiters to split input strings.
Definition: StringUtils.h:111
std::vector< std::string > tokenize(const std::string &searchString, const std::string &delimiters)
Splits a string by multiple delimiters.
Definition: StringUtils.h:141
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:34