Back to home page

EIC code displayed by LXR

 
 

    


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