Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:55:05

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file corecel/io/Label.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cstddef>
0010 #include <functional>
0011 #include <iosfwd>
0012 #include <string>
0013 #include <string_view>
0014 #include <tuple>
0015 #include <utility>
0016 
0017 #include "corecel/Config.hh"
0018 
0019 #include "corecel/math/HashUtils.hh"
0020 
0021 namespace celeritas
0022 {
0023 //---------------------------------------------------------------------------//
0024 /*!
0025  * Helper class for managing volume and material labels.
0026  *
0027  * This class is needed because names in Geant4/VecGeom can be non-unique. The
0028  * only way to map between duplicate volume names between VecGeom and Geant4 is
0029  * to ensure that uniquifying, consistent extensions are written on output (and
0030  * not cleared on input), and to use those to differentiate the duplicate
0031  * volumes.
0032  *
0033  * Materials likewise can have duplicate names (perhaps because some have
0034  * different range cutoffs, etc.), so this class can be used to return a range
0035  * of IDs that match a single material name.
0036  *
0037  * \sa corecel/cont/LabelIdMultiMap.hh
0038  */
0039 struct Label
0040 {
0041     std::string name;  //!< Primary readable label component
0042     std::string ext;  //!< Uniquifying component: pointer address or ID
0043 
0044     //// STATIC DATA ////
0045 
0046     //! Default separator for output and splitting
0047     static constexpr char default_sep = '@';
0048 
0049     //// CLASS METHODS ////
0050 
0051     //! Create an empty label
0052     Label() = default;
0053 
0054     //! Create *implicitly* from a captured string name
0055     Label(std::string&& n) : name{std::move(n)} {}
0056 
0057     // Create *implicitly* from a string name
0058     Label(std::string_view n);
0059     Label(char const* n) : Label{std::string_view{n}} {}
0060     Label(std::string const& n) : Label{std::string_view{n}} {}
0061 
0062     //! Create from a name and label
0063     Label(std::string n, std::string e) : name{std::move(n)}, ext{std::move(e)}
0064     {
0065     }
0066 
0067     //! Whether both the label and extension are empty
0068     bool empty() const { return name.empty() && ext.empty(); }
0069 
0070     //// STATIC METHODS ////
0071 
0072     // Construct a label from by splitting on a separator
0073     static Label from_separator(std::string_view name, char sep = default_sep);
0074 };
0075 
0076 //---------------------------------------------------------------------------//
0077 //! Test equality
0078 inline bool operator==(Label const& lhs, Label const& rhs)
0079 {
0080     return lhs.name == rhs.name && lhs.ext == rhs.ext;
0081 }
0082 
0083 //! Test inequality
0084 inline bool operator!=(Label const& lhs, Label const& rhs)
0085 {
0086     return !(lhs == rhs);
0087 }
0088 
0089 //! Less-than comparison for sorting
0090 inline bool operator<(Label const& lhs, Label const& rhs)
0091 {
0092     return std::tie(lhs.name, lhs.ext) < std::tie(rhs.name, rhs.ext);
0093 }
0094 
0095 //---------------------------------------------------------------------------//
0096 // Write a label to a stream
0097 std::ostream& operator<<(std::ostream&, Label const&);
0098 
0099 //---------------------------------------------------------------------------//
0100 // Get the label as a string
0101 std::string to_string(Label const&);
0102 
0103 //---------------------------------------------------------------------------//
0104 }  // namespace celeritas
0105 
0106 //---------------------------------------------------------------------------//
0107 //! \cond
0108 namespace std
0109 {
0110 //! Specialization for std::hash for unordered storage.
0111 template<>
0112 struct hash<celeritas::Label>
0113 {
0114     using argument_type = celeritas::Label;
0115     using result_type = std::size_t;
0116     result_type operator()(argument_type const& label) const
0117         noexcept(!CELERITAS_DEBUG)
0118     {
0119         return celeritas::hash_combine(label.name, label.ext);
0120     }
0121 };
0122 }  // namespace std
0123 //! \endcond