Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
GUPI_ancestry.cc
Go to the documentation of this file.
1/*
2# <<BEGIN-copyright>>
3# Copyright 2019, Lawrence Livermore National Security, LLC.
4# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
5# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
6# SPDX-License-Identifier: MIT
7# <<END-copyright>>
8*/
9
10#include <fstream>
11
12#include "GUPI.hpp"
13
14namespace GUPI {
15
16/*! \class Ancestry
17 * This is a base class inherit by most other classes. It allows one to construct a node's *xlink* or get another
18 * node from its *xlink*.
19 */
20
21/* *********************************************************************************************************//**
22 * @param a_moniker [in] The **GNDS** node's name (i.e., moniker).
23 * @param a_attribute [in] Currently not used.
24 ***********************************************************************************************************/
25
26Ancestry::Ancestry( std::string const &a_moniker, std::string const &a_attribute ) :
27 m_moniker( a_moniker ),
28 m_ancestor( nullptr ),
29 m_attribute( a_attribute ) {
30
31}
32
33/* *********************************************************************************************************//**
34 ***********************************************************************************************************/
35
39
40/* *********************************************************************************************************//**
41 * The assignment operator. This method sets the member's of *this* to those of *a_ancestry* except for
42 * the member *m_ancestor* which is set to **nullptr**.
43 *
44 * @param a_ancestry [in] Instance whose member are used to set the members of *this*.
45 ***********************************************************************************************************/
46
47Ancestry &Ancestry::operator=( Ancestry const &a_ancestry ) {
48
49 if( this != &a_ancestry ) {
50 m_moniker = a_ancestry.moniker( );
51 m_ancestor = nullptr;
52 m_attribute = a_ancestry.attribute( );
53 }
54
55 return( *this );
56}
57
58/* *********************************************************************************************************//**
59 * Returns the root node, ascending all parent nodes until one is found without an ancester. That node is returned.
60 *
61 * @return Returns the root node (i.e., the top level node).
62 ***********************************************************************************************************/
63
65
66 Ancestry *_root = this;
67
68 while( _root->m_ancestor != nullptr ) _root = _root->m_ancestor;
69 return( _root );
70}
71
72/* *********************************************************************************************************//**
73 * Returns the root node, ascending all parent nodes until one is found without an ancester. That node is returned.
74 *
75 * @return Returns the root node (i.e., the top level node).
76 ***********************************************************************************************************/
77
78Ancestry const *Ancestry::root( ) const {
79
80 Ancestry const *_root = this;
81
82 while( _root->m_ancestor != nullptr ) _root = _root->m_ancestor;
83 return( _root );
84}
85
86/* *********************************************************************************************************//**
87 * Returns a pointer to the node whose *xlink* (i.e., *a_href*) is *a_href*.
88 *
89 * @param a_href [in] The *xlink* whose node is to be returned.
90 * @return Returns the root node (i.e., the top level node).
91 ***********************************************************************************************************/
92
93Ancestry *Ancestry::findInAncestry( std::string const &a_href ) {
94
95 std::vector<std::string> segments = LUPI::Misc::splitXLinkString( a_href );
96
97 return( findInAncestry2( 0, segments ) );
98}
99
100/* *********************************************************************************************************//**
101 * Returns a pointer to the node whose *xlink* (i.e., *a_href*) is *a_href*.
102 *
103 * @param a_href [in] The *xlink* whose node is to be returned.
104 * @return Returns the root node (i.e., the top level node).
105 ***********************************************************************************************************/
106
107Ancestry const *Ancestry::findInAncestry( std::string const &a_href ) const {
108
109 std::vector<std::string> segments = LUPI::Misc::splitXLinkString( a_href );
110
111 return( findInAncestry2( 0, segments ) );
112}
113
114/* *********************************************************************************************************//**
115 * Returns a pointer to the node whose *xlink* is defined by the *a_segments* argument. The *a_segments* is the *xlink*
116 * divided into segments separated by the '/' character.
117 *
118 * @param a_index [in] An index into the *a_segments* whose segment is to be found at this level.
119 * @param a_segments [in] The list of *xlink* segments.
120 * @return Returns the root node (i.e., the top level node).
121 ***********************************************************************************************************/
122
123Ancestry *Ancestry::findInAncestry2( std::size_t a_index, std::vector<std::string> const &a_segments ) {
124
125 Ancestry *item = this;
126
127 if( a_index == a_segments.size( ) ) return( item );
128
129 std::string segment( a_segments[a_index] );
130
131 if( segment == "" ) {
132 item = this->root( );
133 ++a_index;
134 if( a_segments[a_index] != item->moniker( ) ) return( nullptr ); }
135 else if( segment == "." ) {
136 }
137 else if( segment == ".." ) {
138 item = this->ancestor( ); }
139 else {
140 item = this->findInAncestry3( segment );
141 }
142
143 if( item == nullptr ) return( item );
144
145 ++a_index;
146 return( item->findInAncestry2( a_index, a_segments ) );
147}
148
149/* *********************************************************************************************************//**
150 * Returns a pointer to the node whose *xlink* is defined by the *a_segments* argument. The *a_segments* is the *xlink*
151 * divided into segments separated by the '/' character.
152 *
153 * @param a_index [in] An index into the *a_segments* whose segment is to be found at this level.
154 * @param a_segments [in] The list of *xlink* segments.
155 * @return Returns the root node (i.e., the top level node).
156 ***********************************************************************************************************/
157
158Ancestry const *Ancestry::findInAncestry2( std::size_t a_index, std::vector<std::string> const &a_segments ) const {
159
160 Ancestry const *item = this;
161
162 if( a_index == a_segments.size( ) ) return( item );
163
164 std::string segment( a_segments[a_index] );
165
166 if( segment == "" ) {
167 item = this->root( );
168 ++a_index;
169 if( a_segments[a_index] != item->moniker( ) ) return( nullptr ); }
170 else if( segment == "." ) {
171 }
172 else if( segment == ".." ) {
173 item = this->ancestor( ); }
174 else {
175 item = this->findInAncestry3( segment );
176 }
177
178 if( item == nullptr ) return( item );
179
180 ++a_index;
181 return( item->findInAncestry2( a_index, a_segments ) );
182}
183
184/* *********************************************************************************************************//**
185 * This method serializes *this* for broadcasting as needed for MPI and GPUs. The method can count the number of required
186 * bytes, pack *this* or unpack *this* depending on *a_mode*.
187 *
188 * @param a_buffer [in] The buffer to read or write data to depending on *a_mode*.
189 * @param a_mode [in] Specifies the action of this method.
190 ***********************************************************************************************************/
191
193
194 DATA_MEMBER_STD_STRING( m_moniker, a_buffer, a_mode );
195 DATA_MEMBER_STD_STRING( m_attribute, a_buffer, a_mode );
196 if( a_mode == LUPI::DataBuffer::Mode::Unpack ) m_ancestor = nullptr;
197}
198
199/* *********************************************************************************************************//**
200 * Constructs and returns the *xlink* for *this*.
201 *
202 * @return The constructed *xlink*.
203 ***********************************************************************************************************/
204
205std::string Ancestry::toXLink( ) const {
206
207 std::string xlink( "/" + m_moniker + xlinkItemKey( ) );
208
209 if( isRoot( ) ) return( xlink );
210 return( m_ancestor->toXLink( ) + xlink );
211}
212
213/* *********************************************************************************************************//**
214 * Fills the argument *a_writeInfo* with the XML lines that represent *this*. Recursively enters each sub-node.
215 *
216 * @param a_writeInfo [in/out] Instance containing incremental indentation and other information and stores the appended lines.
217 * @param a_indent [in] The amount to indent *this* node.
218 ***********************************************************************************************************/
219
220void Ancestry::toXMLList( LUPI_maybeUnused WriteInfo &a_writeInfo, LUPI_maybeUnused std::string const &a_indent ) const {
221
222 std::cout << "Node '" << moniker( ) << "' needs toXMLList methods." << std::endl;
223}
224
225/* *********************************************************************************************************//**
226 * Calls **toXMLList** and then writes the XML lines to the file "test.xml".
227 ***********************************************************************************************************/
228
229void Ancestry::printXML( ) const {
230
231 WriteInfo writeInfo;
232
233 toXMLList( writeInfo, "" );
234
235 std::ofstream fileio;
236 fileio.open( "test.xml" );
237 for( std::list<std::string>::iterator iter = writeInfo.m_lines.begin( ); iter != writeInfo.m_lines.end( ); ++iter ) {
238 fileio << *iter << std::endl;
239 }
240 fileio.close( );
241}
242
243/* *********************************************************************************************************//**
244 * @param a_incrementalIndent [in] The incremental amount of indentation a node adds to a sub-nodes indentation.
245 * @param a_valuesPerLine [in] The maximum number of integer or float values that are written per line before a new line is created.
246 * @param a_sep [in] The separation character to use between integer and float values in a list.
247 ***********************************************************************************************************/
248
249WriteInfo::WriteInfo( std::string const &a_incrementalIndent, int a_valuesPerLine, std::string const &a_sep ) :
250 m_incrementalIndent( a_incrementalIndent ),
251 m_valuesPerLine( a_valuesPerLine ),
252 m_sep( a_sep ) {
253
254}
255
256/* *********************************************************************************************************//**
257 * Prints to contents the *this* to std::cout.
258 ***********************************************************************************************************/
259
261
262 for( auto line = m_lines.begin( ); line != m_lines.end( ); ++line ) std::cout << *line << std::endl;
263}
264
265}
#define DATA_MEMBER_STD_STRING(member, buf, mode)
#define LUPI_HOST
#define LUPI_maybeUnused
virtual Ancestry * findInAncestry3(std::string const &a_item)=0
Ancestry * findInAncestry(std::string const &a_href)
Ancestry & operator=(Ancestry const &a_ancestry)
Ancestry * ancestor()
Definition GUPI.hpp:104
std::string const & moniker() const
Definition GUPI.hpp:102
virtual LUPI_HOST void serialize(LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode)
void printXML() const
Ancestry(std::string const &a_moniker, std::string const &a_attribute="")
bool isRoot() const
Definition GUPI.hpp:113
Ancestry * root()
std::string toXLink() const
virtual void toXMLList(WriteInfo &a_writeInfo, std::string const &a_indent="") const
std::string attribute() const
Definition GUPI.hpp:107
virtual ~Ancestry()
virtual std::string xlinkItemKey() const
Definition GUPI.hpp:128
std::string m_incrementalIndent
Definition GUPI.hpp:46
std::list< std::string > m_lines
Definition GUPI.hpp:45
int m_valuesPerLine
Definition GUPI.hpp:47
WriteInfo(std::string const &a_incrementalIndent=" ", int a_valuesPerLine=100, std::string const &a_sep=" ")
std::string m_sep
Definition GUPI.hpp:48
Definition GUPI.hpp:20
std::vector< std::string > splitXLinkString(std::string const &a_string)
Definition LUPI_misc.cc:206