Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ios.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4ios implementation
27//
28// Authors: H.Yoshida, M.Nagamatu - November 1998
29// --------------------------------------------------------------------
30
31#include "G4ios.hh"
32
33#include "G4coutDestination.hh"
34
35#include <iostream>
36
37namespace
38{
39// Concrete streambuf redirecting output to G4coutDestination via G4cout etc
40// Templated on two policy types to determine:
41// - DestinationPolicy: which member member function of G4coutDestination to redirect to
42// - DefaultPolicy: what to do if G4coutDestination is default (nullptr)
43template <typename DestinationPolicy, typename DefaultPolicy>
44class G4strstreambuf : public std::basic_streambuf<char>
45{
46 public:
47 G4strstreambuf()
48 {
49 size = 4095;
50 buffer = new char[size + 1];
51 }
52
53 ~G4strstreambuf() override
54 {
55 // flushing buffer...
56 // std::cout is used because destination object may not be alive.
57 if (count != 0) {
58 buffer[count] = '\0';
59 std::cout << buffer;
60 }
61 delete[] buffer;
62 }
63
64 G4strstreambuf(const G4strstreambuf&) = delete;
65 G4strstreambuf& operator=(const G4strstreambuf&) = delete;
66
67 G4int overflow(G4int c = EOF) override
68 {
69 G4int result = 0;
70 if (count >= size) result = sync();
71
72 buffer[count] = (char)c;
73 count++;
74
75 return result;
76 }
77
78 G4int sync() override
79 {
80 buffer[count] = '\0';
81 count = 0;
82 return ReceiveString();
83 }
84
85#ifdef WIN32
86 virtual G4int underflow() { return 0; }
87#endif
88
89 void SetDestination(G4coutDestination* dest) { destination = dest; }
90
91 inline G4int ReceiveString()
92 {
93 G4String stringToSend(buffer);
94 if (destination != nullptr) {
95 return DestinationPolicy::PostMessage(destination, stringToSend);
96 }
97 return DefaultPolicy::PostMessage(stringToSend);
98 }
99
100 private:
101 char* buffer = nullptr;
102 G4int count = 0;
103 G4int size = 0;
104 G4coutDestination* destination = nullptr;
105};
106
107// Policies
108struct PostToG4debug
109{
110 static inline G4int PostMessage(G4coutDestination* d, const G4String& s)
111 {
112 return d->ReceiveG4debug_(s);
113 }
114};
115
116struct PostToG4cout
117{
118 static inline G4int PostMessage(G4coutDestination* d, const G4String& s)
119 {
120 return d->ReceiveG4cout_(s);
121 }
122};
123
124struct PostToG4cerr
125{
126 static inline G4int PostMessage(G4coutDestination* d, const G4String& s)
127 {
128 return d->ReceiveG4cerr_(s);
129 }
130};
131
132struct DefaultToCout
133{
134 static inline G4int PostMessage(const G4String& s)
135 {
136 std::cout << s << std::flush;
137 return 0;
138 }
139};
140
141struct DefaultToCerr
142{
143 static inline G4int PostMessage(const G4String& s)
144 {
145 std::cerr << s << std::flush;
146 return 0;
147 }
148};
149
150using G4debugstreambuf = G4strstreambuf<PostToG4debug, DefaultToCout>;
151using G4coutstreambuf = G4strstreambuf<PostToG4cout, DefaultToCout>;
152using G4cerrstreambuf = G4strstreambuf<PostToG4cerr, DefaultToCerr>;
153} // namespace
154
155#ifdef G4MULTITHREADED
156// --- StreamBuffers
157G4debugstreambuf*& _G4debugbuf_p()
158{
159 G4ThreadLocalStatic auto* _instance = new G4debugstreambuf;
160 return _instance;
161}
162
163G4coutstreambuf*& _G4coutbuf_p()
164{
165 G4ThreadLocalStatic auto* _instance = new G4coutstreambuf;
166 return _instance;
167}
168
169G4cerrstreambuf*& _G4cerrbuf_p()
170{
171 G4ThreadLocalStatic auto* _instance = new G4cerrstreambuf;
172 return _instance;
173}
174
175// --- Streams
176std::ostream*& _G4debug_p()
177{
178 G4ThreadLocalStatic auto* _instance = new std::ostream(_G4debugbuf_p());
179 return _instance;
180}
181
182std::ostream*& _G4cout_p()
183{
184 G4ThreadLocalStatic auto* _instance = new std::ostream(_G4coutbuf_p());
185 return _instance;
186}
187
188std::ostream*& _G4cerr_p()
189{
190 G4ThreadLocalStatic auto* _instance = new std::ostream(_G4cerrbuf_p());
191 return _instance;
192}
193
195{
196 // --- Stream Buffers
197 if (_G4debugbuf_p() == nullptr) {
198 _G4debugbuf_p() = new G4debugstreambuf;
199 }
200 if (_G4coutbuf_p() == nullptr) {
201 _G4coutbuf_p() = new G4coutstreambuf;
202 }
203 if (_G4cerrbuf_p() == nullptr) {
204 _G4cerrbuf_p() = new G4cerrstreambuf;
205 }
206
207 // --- Streams
208 if (_G4debug_p() == &std::cout || _G4debug_p() == nullptr) {
209 _G4debug_p() = new std::ostream(_G4debugbuf_p());
210 }
211 if (_G4cout_p() == &std::cout || _G4cout_p() == nullptr) {
212 _G4cout_p() = new std::ostream(_G4coutbuf_p());
213 }
214 if (_G4cerr_p() == &std::cerr || _G4cerr_p() == nullptr) {
215 _G4cerr_p() = new std::ostream(_G4cerrbuf_p());
216 }
217}
218
220{
221 // Reverse order
222 // --- Streams
223 delete _G4debug_p();
224 _G4debug_p() = &std::cout;
225 delete _G4cout_p();
226 _G4cout_p() = &std::cout;
227 delete _G4cerr_p();
228 _G4cerr_p() = &std::cerr;
229
230 // --- Stream Buffers
231 delete _G4debugbuf_p();
232 _G4debugbuf_p() = nullptr;
233 delete _G4coutbuf_p();
234 _G4coutbuf_p() = nullptr;
235 delete _G4cerrbuf_p();
236 _G4cerrbuf_p() = nullptr;
237}
238
239# define G4debugbuf (*_G4debugbuf_p())
240# define G4coutbuf (*_G4coutbuf_p())
241# define G4cerrbuf (*_G4cerrbuf_p())
242
243// These two functions are guaranteed to be called at load and
244// unload of the library containing this code.
245namespace
246{
247# ifndef WIN32
248void setupG4ioSystem() __attribute__((constructor));
249void cleanupG4ioSystem() __attribute__((destructor));
250# endif
251void setupG4ioSystem() { G4iosInitialization(); }
252void cleanupG4ioSystem() { G4iosFinalization(); }
253} // namespace
254
255#else // Sequential
256
257G4debugstreambuf G4debugbuf;
258G4coutstreambuf G4coutbuf;
259G4cerrstreambuf G4cerrbuf;
260
261std::ostream G4debug(&G4debugbuf);
262std::ostream G4cout(&G4coutbuf);
263std::ostream G4cerr(&G4cerrbuf);
264
267
268#endif
269
271{
272 G4debugbuf.SetDestination(sink);
273 G4coutbuf.SetDestination(sink);
274 G4cerrbuf.SetDestination(sink);
275}
int G4int
Definition G4Types.hh:85
G4debugstreambuf G4debugbuf
Definition G4ios.cc:257
void G4iosFinalization()
Definition G4ios.cc:266
void G4iosSetDestination(G4coutDestination *sink)
Definition G4ios.cc:270
G4coutstreambuf G4coutbuf
Definition G4ios.cc:258
G4cerrstreambuf G4cerrbuf
Definition G4ios.cc:259
void G4iosInitialization()
Definition G4ios.cc:265
G4GLOB_DLL std::ostream G4debug
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
G4int ReceiveG4cout_(const G4String &msg)
G4int ReceiveG4debug_(const G4String &msg)
G4int ReceiveG4cerr_(const G4String &msg)
#define G4ThreadLocalStatic
Definition tls.hh:76