Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:05:55

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 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 orange/orangeinp/detail/InfixStringBuilder.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include <ostream>
0011 
0012 #include "corecel/cont/VariantUtils.hh"
0013 
0014 #include "../CsgTree.hh"
0015 
0016 namespace celeritas
0017 {
0018 namespace orangeinp
0019 {
0020 namespace detail
0021 {
0022 //---------------------------------------------------------------------------//
0023 /*!
0024  * Transform a CSG node into a string expression.
0025  *
0026  * The string will be a combination of:
0027  * - an \c any function for a union of all listed components
0028  * - an \c all function for an intersection of all listed components
0029  * - a \c ! negation operator applied to the left of an operation or other
0030  *   negation
0031  * - a surface ID preceded by a \c - or \c + indicating "inside" or "outside",
0032  *   respectively.
0033  *
0034  * Example of a cylindrical shell: \verbatim
0035    all(all(+0, -1, -3), !all(+0, -1, -2))
0036  * \endverbatim
0037  */
0038 class InfixStringBuilder
0039 {
0040   public:
0041     // Construct with tree and a stream to write to
0042     inline InfixStringBuilder(CsgTree const& tree, std::ostream* os);
0043 
0044     // Build from a node ID
0045     inline void operator()(NodeId const& n);
0046 
0047     //!@{
0048     //! \name Visit a node directly
0049     // Append 'true'
0050     inline void operator()(True const&);
0051     // False is never explicitly part of the node tree
0052     inline void operator()(False const&);
0053     // Append a surface ID
0054     inline void operator()(Surface const&);
0055     // Aliased nodes should never be reachable explicitly
0056     inline void operator()(Aliased const&);
0057     // Visit a negated node and append 'not'
0058     inline void operator()(Negated const&);
0059     // Visit daughter nodes and append the conjunction.
0060     inline void operator()(Joined const&);
0061     //!@}
0062 
0063   private:
0064     ContainerVisitor<CsgTree const&, NodeId> visit_node_;
0065     std::ostream* os_;
0066     bool negated_{false};
0067 };
0068 
0069 //---------------------------------------------------------------------------//
0070 // INLINE DEFINITIONS
0071 //---------------------------------------------------------------------------//
0072 /*!
0073  * Construct with a reference to an output stream.
0074  */
0075 InfixStringBuilder::InfixStringBuilder(CsgTree const& tree, std::ostream* os)
0076     : visit_node_{tree}, os_{os}
0077 {
0078     CELER_EXPECT(os_);
0079 }
0080 
0081 //---------------------------------------------------------------------------//
0082 /*!
0083  * Build from a node ID.
0084  */
0085 void InfixStringBuilder::operator()(NodeId const& n)
0086 {
0087     visit_node_(*this, n);
0088 }
0089 
0090 //---------------------------------------------------------------------------//
0091 /*!
0092  * Append the "true" token.
0093  */
0094 void InfixStringBuilder::operator()(True const&)
0095 {
0096     *os_ << (negated_ ? 'F' : 'T');
0097     negated_ = false;
0098 }
0099 
0100 //---------------------------------------------------------------------------//
0101 /*!
0102  * Explicit "False" should never be possible for a CSG cell.
0103  *
0104  * The 'false' standin is always aliased to "not true" in the CSG tree.
0105  */
0106 void InfixStringBuilder::operator()(False const&)
0107 {
0108     CELER_ASSERT_UNREACHABLE();
0109 }
0110 
0111 //---------------------------------------------------------------------------//
0112 /*!
0113  * Push a surface ID.
0114  */
0115 void InfixStringBuilder::operator()(Surface const& s)
0116 {
0117     CELER_EXPECT(s.id < logic::lbegin);
0118 
0119     static_assert(to_sense(true) == Sense::outside);
0120     *os_ << (negated_ ? '-' : '+') << s.id.unchecked_get();
0121     negated_ = false;
0122 }
0123 
0124 //---------------------------------------------------------------------------//
0125 /*!
0126  * Push an aliased node.
0127  *
0128  * Note: aliased node won't be reachable if a tree is fully simplified, *but* a
0129  * node can be printed for testing before it's simplified.
0130  */
0131 void InfixStringBuilder::operator()(Aliased const& n)
0132 {
0133     (*this)(n.node);
0134 }
0135 
0136 //---------------------------------------------------------------------------//
0137 /*!
0138  * Visit a negated node and append 'not'.
0139  */
0140 void InfixStringBuilder::operator()(Negated const& n)
0141 {
0142     if (negated_)
0143     {
0144         // Note: this won't happen for simplified expressions but can be for
0145         // testing unsimplified expressions.
0146         *os_ << '!';
0147     }
0148     negated_ = true;
0149     (*this)(n.node);
0150 }
0151 
0152 //---------------------------------------------------------------------------//
0153 /*!
0154  * Visit daughter nodes and append the conjunction.
0155  */
0156 void InfixStringBuilder::operator()(Joined const& n)
0157 {
0158     CELER_EXPECT(n.nodes.size() > 1);
0159 
0160     if (negated_)
0161     {
0162         *os_ << '!';
0163     }
0164     negated_ = false;
0165     *os_ << (n.op == op_and ? "all" : n.op == op_or ? "any" : "XXX") << '(';
0166 
0167     // Visit first node, then add conjunction for subsequent nodes
0168     auto iter = n.nodes.begin();
0169     (*this)(*iter++);
0170 
0171     while (iter != n.nodes.end())
0172     {
0173         *os_ << ", ";
0174         (*this)(*iter++);
0175     }
0176     *os_ << ')';
0177 }
0178 
0179 //---------------------------------------------------------------------------//
0180 }  // namespace detail
0181 }  // namespace orangeinp
0182 }  // namespace celeritas