Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:48

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