Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-14 08:31:33

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 orange/orangeinp/CsgTypes.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <functional>
0010 #include <iosfwd>
0011 #include <string>
0012 #include <variant>
0013 #include <vector>
0014 
0015 #include "corecel/Config.hh"
0016 
0017 #include "corecel/OpaqueId.hh"
0018 #include "corecel/cont/EnumArray.hh"
0019 #include "corecel/grid/GridTypes.hh"
0020 #include "corecel/math/HashUtils.hh"
0021 #include "orange/OrangeTypes.hh"
0022 
0023 namespace celeritas
0024 {
0025 namespace orangeinp
0026 {
0027 //---------------------------------------------------------------------------//
0028 //! Operator token
0029 using OperatorToken = logic::OperatorToken;
0030 
0031 //! Unique identifier for a node
0032 using NodeId = OpaqueId<struct Node_>;
0033 
0034 inline constexpr OperatorToken op_and = OperatorToken::land;
0035 inline constexpr OperatorToken op_or = OperatorToken::lor;
0036 
0037 //! Node that represents "always true" for simplification
0038 struct True
0039 {
0040 };
0041 
0042 //! Node that represents "always false" for simplification
0043 struct False
0044 {
0045 };
0046 
0047 //! (Internal) stand-in node for a replacement for another node ID
0048 struct Aliased
0049 {
0050     NodeId node;
0051 };
0052 
0053 //! Node that negates the next ID
0054 struct Negated
0055 {
0056     NodeId node;
0057 };
0058 
0059 //! Node that is a single surface
0060 struct Surface
0061 {
0062     LocalSurfaceId id;
0063 };
0064 
0065 //! Internal node applying an operation to multiple leaf nodes
0066 struct Joined
0067 {
0068     OperatorToken op;
0069     std::vector<NodeId> nodes;
0070 };
0071 
0072 //! Generic node
0073 using Node = std::variant<True, False, Aliased, Negated, Surface, Joined>;
0074 
0075 /*!
0076  * Optional transformations to apply when building a CsgUnit.
0077  */
0078 enum class UnitSimplification : size_type
0079 {
0080     none = 0,  //!< No simplification
0081     infix_logic,  //!< CsgTree suitable for infix logic evaluation
0082     size_
0083 };
0084 
0085 //---------------------------------------------------------------------------//
0086 // Equality operators
0087 //---------------------------------------------------------------------------//
0088 inline constexpr bool operator==(True const&, True const&)
0089 {
0090     return true;
0091 }
0092 inline constexpr bool operator==(False const&, False const&)
0093 {
0094     return true;
0095 }
0096 inline constexpr bool operator==(Aliased const& a, Aliased const& b)
0097 {
0098     return a.node == b.node;
0099 }
0100 inline constexpr bool operator==(Negated const& a, Negated const& b)
0101 {
0102     return a.node == b.node;
0103 }
0104 inline constexpr bool operator==(Surface const& a, Surface const& b)
0105 {
0106     return a.id == b.id;
0107 }
0108 inline constexpr bool operator==(Joined const& a, Joined const& b)
0109 {
0110     return a.op == b.op && a.nodes == b.nodes;
0111 }
0112 
0113 #define CELER_DEFINE_CSG_NE(CLS)                                 \
0114     inline constexpr bool operator!=(CLS const& a, CLS const& b) \
0115     {                                                            \
0116         return !(a == b);                                        \
0117     }
0118 
0119 CELER_DEFINE_CSG_NE(True)
0120 CELER_DEFINE_CSG_NE(False)
0121 CELER_DEFINE_CSG_NE(Aliased)
0122 CELER_DEFINE_CSG_NE(Negated)
0123 CELER_DEFINE_CSG_NE(Surface)
0124 CELER_DEFINE_CSG_NE(Joined)
0125 
0126 //---------------------------------------------------------------------------//
0127 // Stream output
0128 //---------------------------------------------------------------------------//
0129 std::ostream& operator<<(std::ostream& os, True const&);
0130 std::ostream& operator<<(std::ostream& os, False const&);
0131 std::ostream& operator<<(std::ostream& os, Aliased const&);
0132 std::ostream& operator<<(std::ostream& os, Negated const&);
0133 std::ostream& operator<<(std::ostream& os, Surface const&);
0134 std::ostream& operator<<(std::ostream& os, Joined const&);
0135 
0136 // Write a variant node to a stream
0137 std::ostream& operator<<(std::ostream& os, Node const&);
0138 
0139 // Get a string representation of a variant node
0140 std::string to_string(Node const&);
0141 
0142 //---------------------------------------------------------------------------//
0143 // Helper functions
0144 //---------------------------------------------------------------------------//
0145 //! Whether a node is a boolean (True or False instances)
0146 inline constexpr bool is_boolean_node(Node const& n)
0147 {
0148     return std::holds_alternative<True>(n) || std::holds_alternative<False>(n);
0149 }
0150 
0151 //---------------------------------------------------------------------------//
0152 }  // namespace orangeinp
0153 }  // namespace celeritas
0154 
0155 namespace std
0156 {
0157 //---------------------------------------------------------------------------//
0158 // HASH SPECIALIZATIONS
0159 //---------------------------------------------------------------------------//
0160 //! \cond
0161 template<>
0162 struct hash<celeritas::orangeinp::True>
0163 {
0164     using argument_type = celeritas::orangeinp::True;
0165     using result_type = std::size_t;
0166     result_type operator()(argument_type const&) const noexcept
0167     {
0168         return result_type{0};
0169     }
0170 };
0171 
0172 template<>
0173 struct hash<celeritas::orangeinp::False>
0174 {
0175     using argument_type = celeritas::orangeinp::False;
0176     using result_type = std::size_t;
0177     result_type operator()(argument_type const&) const noexcept
0178     {
0179         return result_type{0};
0180     }
0181 };
0182 
0183 template<>
0184 struct hash<celeritas::orangeinp::Aliased>
0185 {
0186     using argument_type = celeritas::orangeinp::Aliased;
0187     using result_type = std::size_t;
0188     result_type operator()(argument_type const& val) const noexcept
0189     {
0190         return std::hash<celeritas::orangeinp::NodeId>{}(val.node);
0191     }
0192 };
0193 
0194 template<>
0195 struct hash<celeritas::orangeinp::Negated>
0196 {
0197     using argument_type = celeritas::orangeinp::Negated;
0198     using result_type = std::size_t;
0199     result_type operator()(argument_type const& val) const noexcept
0200     {
0201         return std::hash<celeritas::orangeinp::NodeId>{}(val.node);
0202     }
0203 };
0204 
0205 template<>
0206 struct hash<celeritas::orangeinp::Surface>
0207 {
0208     using argument_type = celeritas::orangeinp::Surface;
0209     using result_type = std::size_t;
0210     result_type operator()(argument_type const& val) const noexcept
0211     {
0212         return std::hash<celeritas::LocalSurfaceId>{}(val.id);
0213     }
0214 };
0215 
0216 template<>
0217 struct hash<celeritas::orangeinp::Joined>
0218 {
0219     using argument_type = celeritas::orangeinp::Joined;
0220     using result_type = std::size_t;
0221     result_type operator()(argument_type const& val) const
0222         noexcept(!CELERITAS_DEBUG)
0223     {
0224         result_type result;
0225         celeritas::Hasher hash{&result};
0226         hash(static_cast<std::size_t>(val.op));
0227         hash(val.nodes.size());
0228         for (auto& v : val.nodes)
0229         {
0230             hash(std::hash<celeritas::orangeinp::NodeId>{}(v));
0231         }
0232         return result;
0233     }
0234 };
0235 //! \endcond
0236 //---------------------------------------------------------------------------//
0237 }  // namespace std