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