File indexing completed on 2025-01-18 09:11:49
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Utilities/Options.hpp"
0010
0011 #include <algorithm>
0012 #include <iostream>
0013 #include <sstream>
0014 #include <stdexcept>
0015 #include <string>
0016 #include <utility>
0017
0018 namespace {
0019 constexpr char s_separator = ':';
0020 }
0021
0022
0023
0024 std::istream& ActsExamples::Options::operator>>(
0025 std::istream& is, ActsExamples::Options::Interval& interval) {
0026 std::string buf;
0027 is >> buf;
0028
0029
0030 interval.lower.reset();
0031 interval.upper.reset();
0032
0033
0034 auto pos = buf.find_first_of(s_separator);
0035
0036 if (pos == std::string::npos) {
0037 return is;
0038 }
0039
0040
0041 if (0 < pos) {
0042 auto lowerStr = buf.substr(0, pos);
0043 interval.lower = std::stod(lowerStr);
0044 }
0045
0046 if ((pos + 1) < buf.size()) {
0047 auto upperStr = buf.substr(pos + 1);
0048 interval.upper = std::stod(upperStr);
0049 }
0050
0051 return is;
0052 }
0053
0054 std::ostream& ActsExamples::Options::operator<<(
0055 std::ostream& os, const ActsExamples::Options::Interval& interval) {
0056 if (!interval.lower.has_value() && !interval.upper.has_value()) {
0057 os << "unbounded";
0058 } else {
0059 if (interval.lower.has_value()) {
0060 os << interval.lower.value();
0061 }
0062 os << s_separator;
0063 if (interval.upper.has_value()) {
0064 os << interval.upper.value();
0065 }
0066 }
0067 return os;
0068 }
0069
0070
0071
0072 namespace {
0073
0074 template <typename value_t, typename converter_t>
0075 void parseVariable(std::istream& is, std::vector<value_t>& values,
0076 converter_t&& convert) {
0077 values.clear();
0078
0079 std::string buf;
0080 is >> buf;
0081 std::string bufValue;
0082 std::string::size_type pos = 0;
0083 std::string::size_type end = std::string::npos;
0084 do {
0085 end = buf.find_first_of(s_separator, pos);
0086 if (end == std::string::npos) {
0087
0088 bufValue = buf.substr(pos);
0089 } else {
0090 bufValue = buf.substr(pos, end - pos);
0091 pos = end + 1u;
0092 }
0093 values.push_back(convert(bufValue));
0094 } while (end != std::string::npos);
0095 }
0096
0097 template <typename value_t, typename converter_t>
0098 void parseFixed(std::istream& is, std::size_t size, value_t* values,
0099 converter_t&& convert) {
0100
0101 std::vector<value_t> tmp(size, 0);
0102 parseVariable(is, tmp, std::forward<converter_t>(convert));
0103 if (tmp.size() < size) {
0104 throw std::invalid_argument(
0105 "Not enough values for fixed-size user option, expected " +
0106 std::to_string(size) + " received " + std::to_string(tmp.size()));
0107 }
0108 if (size < tmp.size()) {
0109 throw std::invalid_argument(
0110 "Too many values for fixed-size user option, expected " +
0111 std::to_string(size) + " received " + std::to_string(tmp.size()));
0112 }
0113 std::copy(tmp.begin(), tmp.end(), values);
0114 }
0115
0116 template <typename value_t>
0117 void print(std::ostream& os, std::size_t size, const value_t* values) {
0118 for (std::size_t i = 0; i < size; ++i) {
0119 if (0u < i) {
0120 os << s_separator;
0121 }
0122 os << values[i];
0123 }
0124 }
0125
0126 }
0127
0128
0129
0130 void ActsExamples::Options::detail::parseDoublesFixed(std::istream& is,
0131 std::size_t size,
0132 double* values) {
0133 parseFixed(is, size, values,
0134 [](const std::string& s) { return std::stod(s); });
0135 }
0136
0137 void ActsExamples::Options::detail::parseDoublesVariable(
0138 std::istream& is, std::vector<double>& values) {
0139 parseVariable(is, values, [](const std::string& s) { return std::stod(s); });
0140 }
0141
0142 void ActsExamples::Options::detail::printDoubles(std::ostream& os,
0143 std::size_t size,
0144 const double* values) {
0145 print(os, size, values);
0146 }
0147
0148
0149
0150 void ActsExamples::Options::detail::parseIntegersFixed(std::istream& is,
0151 std::size_t size,
0152 int* values) {
0153 parseFixed(is, size, values,
0154 [](const std::string& s) { return std::stoi(s); });
0155 }
0156
0157 void ActsExamples::Options::detail::parseIntegersVariable(
0158 std::istream& is, std::vector<int>& values) {
0159 parseVariable(is, values, [](const std::string& s) { return std::stoi(s); });
0160 }
0161
0162 void ActsExamples::Options::detail::printIntegers(std::ostream& os,
0163 std::size_t size,
0164 const int* values) {
0165 print(os, size, values);
0166 }