Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:24:50

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