Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-22 08:01:26

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include <array>
0012 #include <ostream>
0013 #include <stdexcept>
0014 #include <string_view>
0015 
0016 namespace ActsPlugins {
0017 
0018 /// @addtogroup root_plugin
0019 /// @{
0020 
0021 /// Type-safe representation of TGeo surface axes.
0022 ///
0023 /// The axes string encodes which TGeo coordinate axes map to the local X and Y
0024 /// directions of an Acts surface, with case controlling the sign:
0025 ///   - Uppercase (X, Y, Z): positive direction
0026 ///   - Lowercase (x, y, z): negative direction
0027 ///
0028 /// Valid values are all 3-character permutations of {X,x}, {Y,y}, {Z,z} with
0029 /// no axis letter repeated (e.g. "XYZ", "XZY", "xYz").
0030 ///
0031 /// String literals are validated at compile time via the @c consteval
0032 /// constructor — invalid characters or repeated axes are a compile error.
0033 /// Runtime construction is available via @c parse().
0034 class TGeoAxes {
0035  public:
0036   /// Construct from a 3-character string literal.
0037   ///
0038   /// The parameter type @c const char (&)[4] only binds to exactly 3-character
0039   /// string literals; wrong lengths are a type error. Invalid characters or
0040   /// repeated axis letters cause a compile error.
0041   ///
0042   /// @param s A 3-character axes string literal, e.g. @c "XYZ"
0043   consteval TGeoAxes(const char (&s)[4])  // NOLINT(google-explicit-constructor)
0044       : TGeoAxes(makeChecked(s[0], s[1], s[2])) {}
0045 
0046   /// Construct from a runtime string. Throws on invalid input.
0047   ///
0048   /// @param s A string of exactly 3 characters from [XxYyZz] with no repeated
0049   ///          axis letter.
0050   /// @throws std::invalid_argument if the string is not a valid axes encoding.
0051   /// @return The parsed axes as a TGeoAxes object.
0052   static TGeoAxes parse(std::string_view s) {
0053     if (s.size() != 3 || !isValid(s[0], s[1], s[2])) {
0054       throw std::invalid_argument(
0055           "TGeoAxes: expected exactly 3 characters from [XxYyZz] "
0056           "with each axis (X, Y, Z) appearing exactly once");
0057     }
0058     return TGeoAxes{Checked{s[0], s[1], s[2]}};
0059   }
0060 
0061   /// Return the axes string as a 3-character string view.
0062   /// @return The axes string as a 3-character string view.
0063   std::string_view value() const { return {m_axes.data(), 3}; }
0064 
0065   friend std::ostream& operator<<(std::ostream& os, const TGeoAxes& axes) {
0066     return os << axes.value();
0067   }
0068 
0069  private:
0070   struct Checked {
0071     char a;
0072     char b;
0073     char c;
0074   };
0075 
0076   static constexpr bool isAxisChar(char c) {
0077     return c == 'X' || c == 'x' || c == 'Y' || c == 'y' || c == 'Z' || c == 'z';
0078   }
0079 
0080   static constexpr char baseAxis(char c) {
0081     if (c == 'x') {
0082       return 'X';
0083     }
0084     if (c == 'y') {
0085       return 'Y';
0086     }
0087     if (c == 'z') {
0088       return 'Z';
0089     }
0090     return c;
0091   }
0092 
0093   // Shared predicate — constexpr so usable at both compile and runtime.
0094   static constexpr bool isValid(char a, char b, char c) {
0095     return isAxisChar(a) && isAxisChar(b) && isAxisChar(c) &&
0096            baseAxis(a) != baseAxis(b) && baseAxis(b) != baseAxis(c) &&
0097            baseAxis(a) != baseAxis(c);
0098   }
0099 
0100   // consteval: a throw reached during evaluation makes the call ill-formed,
0101   // which manifests as a compile error at the call site.
0102   static consteval Checked makeChecked(char a, char b, char c) {
0103     if (!isAxisChar(a) || !isAxisChar(b) || !isAxisChar(c)) {
0104       throw std::invalid_argument(
0105           "TGeoAxes: each character must be one of X x Y y Z z");
0106     }
0107     if (baseAxis(a) == baseAxis(b) || baseAxis(b) == baseAxis(c) ||
0108         baseAxis(a) == baseAxis(c)) {
0109       throw std::invalid_argument(
0110           "TGeoAxes: each axis (X, Y, Z) must appear exactly once");
0111     }
0112     return {a, b, c};
0113   }
0114 
0115   explicit constexpr TGeoAxes(Checked v) : m_axes{v.a, v.b, v.c} {}
0116 
0117   std::array<char, 3> m_axes;
0118 };
0119 
0120 /// @}
0121 
0122 }  // namespace ActsPlugins