|
||||
File indexing completed on 2025-01-18 09:28:02
0001 // This file is part of the Acts project. 0002 // 0003 // Copyright (C) 2017-2020 CERN for the benefit of the Acts project 0004 // 0005 // This Source Code Form is subject to the terms of the Mozilla Public 0006 // License, v. 2.0. If a copy of the MPL was not distributed with this 0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 0008 0009 #pragma once 0010 0011 #include <array> 0012 #include <cstddef> 0013 #include <iosfwd> 0014 #include <optional> 0015 #include <vector> 0016 0017 namespace ActsExamples::Options { 0018 0019 /// @defgroup option-types Additional types for program options 0020 /// 0021 /// All types are intended as utility type for the user options and not as a 0022 /// variable type for the configuration structs. They should only be used where 0023 /// a single option can not be represented by an existing primitive types. 0024 /// 0025 /// They also must be distinct types and can not just be typedefs; otherwise we 0026 /// can not define the required operator{<<,>>} overloads in this namespace. 0027 /// 0028 /// @{ 0029 0030 /// Half open [lower,upper) interval type for a single user option. 0031 /// 0032 /// A missing limit represents an unbounded upper or lower limit. With just 0033 /// one defined limit the interval is just a lower/upper bound; with both 0034 /// limits undefined, the interval is unbounded everywhere and thus contains 0035 /// all possible values. 0036 struct Interval { 0037 std::optional<double> lower; 0038 std::optional<double> upper; 0039 }; 0040 0041 /// A fixed number of real values as one user option. 0042 /// 0043 /// @note Implemented as a subclass so it is distinct from `std::array` 0044 /// and we can provide overloads in the same namespace. 0045 template <std::size_t kSize> 0046 class Reals : public std::array<double, kSize> {}; 0047 0048 /// An arbitrary number of revaluesal as one user option. 0049 /// 0050 /// @note Making this a `std::vector<double>` typedef or subclass confuses 0051 /// program options, since `std::vector<double>` is interpreted as a `double` 0052 /// option that can be provided multiple times. 0053 struct VariableReals { 0054 std::vector<double> values; 0055 }; 0056 0057 /// A fixed number of integers as one user option. 0058 /// 0059 /// @note Implemented as a subclass so it is distinct from `std::array` 0060 /// and we can provide overloads in the same namespace. 0061 template <std::size_t kSize> 0062 class Integers : public std::array<int, kSize> {}; 0063 0064 /// An arbitrary number of integers as one user option. 0065 /// 0066 /// @note Making this a `std::vector<int>` typedef or subclass confuses 0067 /// program options, since `std::vector<int>` is interpreted as an `int` 0068 /// option that can be provided multiple times. 0069 struct VariableIntegers { 0070 std::vector<int> values; 0071 }; 0072 0073 /// @} 0074 0075 /// Extract an interval from an input of the form 'lower:upper'. 0076 /// 0077 /// An input of the form `lower:` or `:upper` sets just one of the limits. Any 0078 /// other input leads to an unbounded interval. 0079 /// 0080 /// @note The more common range notation uses `lower-upper` but the `-` 0081 /// separator complicates the parsing of negative values. 0082 std::istream& operator>>(std::istream& is, Interval& interval); 0083 0084 /// Print an interval as `lower:upper`. 0085 std::ostream& operator<<(std::ostream& os, const Interval& interval); 0086 0087 namespace detail { 0088 void parseDoublesFixed(std::istream& is, std::size_t size, double* values); 0089 void parseDoublesVariable(std::istream& is, std::vector<double>& values); 0090 void printDoubles(std::ostream& os, std::size_t size, const double* values); 0091 } // namespace detail 0092 0093 /// Extract a fixed number of doubles from an input of the form 'x:y:z'. 0094 /// 0095 /// @note If the values would be separated by whitespace, negative values 0096 /// and additional command line both start with `-` and would be 0097 /// undistinguishable. 0098 template <std::size_t kSize> 0099 inline std::istream& operator>>(std::istream& is, Reals<kSize>& values) { 0100 detail::parseDoublesFixed(is, kSize, values.data()); 0101 return is; 0102 } 0103 0104 /// Extract a variable number of doubles from an input of the form 'x:y:...'. 0105 /// 0106 /// @note If the values would be separated by whitespace, negative values 0107 /// and additional command line both start with `-` and would be 0108 /// undistinguishable. 0109 inline std::istream& operator>>(std::istream& is, VariableReals& values) { 0110 detail::parseDoublesVariable(is, values.values); 0111 return is; 0112 } 0113 0114 /// Print a fixed number of doubles as `x:y:z`. 0115 template <std::size_t kSize> 0116 inline std::ostream& operator<<(std::ostream& os, const Reals<kSize>& values) { 0117 detail::printDoubles(os, kSize, values.data()); 0118 return os; 0119 } 0120 0121 /// Print a variable number of doubles as `x:y:z:...`. 0122 inline std::ostream& operator<<(std::ostream& os, const VariableReals& values) { 0123 detail::printDoubles(os, values.values.size(), values.values.data()); 0124 return os; 0125 } 0126 0127 namespace detail { 0128 void parseIntegersFixed(std::istream& is, std::size_t size, int* values); 0129 void parseIntegersVariable(std::istream& is, std::vector<int>& values); 0130 void printIntegers(std::ostream& os, std::size_t size, const int* values); 0131 } // namespace detail 0132 0133 /// Extract a fixed number of integers from an input of the form 'x:y:z'. 0134 /// 0135 /// @note If the values would be separated by whitespace, negative values 0136 /// and additional command line both start with `-` and would be 0137 /// undistinguishable. 0138 template <std::size_t kSize> 0139 inline std::istream& operator>>(std::istream& is, Integers<kSize>& values) { 0140 detail::parseIntegersFixed(is, kSize, values.data()); 0141 return is; 0142 } 0143 0144 /// Extract a variable number of integers from an input of the form 'x:y:...'. 0145 /// 0146 /// @note If the values would be separated by whitespace, negative values 0147 /// and additional command line both start with `-` and would be 0148 /// undistinguishable. 0149 inline std::istream& operator>>(std::istream& is, VariableIntegers& values) { 0150 detail::parseIntegersVariable(is, values.values); 0151 return is; 0152 } 0153 0154 /// Print a fixed number of integers as `x:y:z`. 0155 template <std::size_t kSize> 0156 inline std::ostream& operator<<(std::ostream& os, 0157 const Integers<kSize>& values) { 0158 detail::printIntegers(os, kSize, values.data()); 0159 return os; 0160 } 0161 0162 /// Print a variable number of integers as `x:y:z:...`. 0163 inline std::ostream& operator<<(std::ostream& os, 0164 const VariableIntegers& values) { 0165 detail::printIntegers(os, values.values.size(), values.values.data()); 0166 return os; 0167 } 0168 0169 } // namespace ActsExamples::Options
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |