Import Geant4 11.2.0.beta source tree
This commit is contained in:
@@ -28,16 +28,68 @@
|
||||
// Author: A.Dotti (SLAC), 14 April 2017
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include <iostream>
|
||||
#include "G4BuffercoutDestination.hh"
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
#include "G4BuffercoutDestination.hh"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// Private class to implement buffering of logging via an ostringstream
|
||||
class G4BuffercoutDestination::BufferImpl
|
||||
{
|
||||
public:
|
||||
using FlushFn_t = std::function<void(const std::string&)>;
|
||||
|
||||
public:
|
||||
explicit BufferImpl(std::size_t maxSize) : m_maxSize(maxSize) {}
|
||||
explicit BufferImpl(std::size_t maxSize, FlushFn_t&& f) : m_maxSize(maxSize), m_flushFn(f) {}
|
||||
|
||||
~BufferImpl() = default;
|
||||
|
||||
// Set number of characters to hold before Flush() will be called
|
||||
// If buffer exceeds new maximum, Flush() will not be called until next call to Receive()
|
||||
void SetMaxSize(std::size_t n) { m_maxSize = n; }
|
||||
|
||||
// Reset buffer without flushing
|
||||
void Reset()
|
||||
{
|
||||
m_buffer.str("");
|
||||
m_buffer.clear();
|
||||
m_currentSize = 0;
|
||||
}
|
||||
|
||||
G4int Receive(const G4String& msg)
|
||||
{
|
||||
m_currentSize += msg.size();
|
||||
m_buffer << msg;
|
||||
|
||||
if (m_maxSize > 0 && m_currentSize > m_maxSize) {
|
||||
return Flush();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Flush buffer to destination and reset it
|
||||
G4int Flush()
|
||||
{
|
||||
m_flushFn(m_buffer.str());
|
||||
Reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t m_maxSize = 0;
|
||||
std::ostringstream m_buffer;
|
||||
std::size_t m_currentSize = 0;
|
||||
FlushFn_t m_flushFn = [](auto& s) { std::cout << s << std::flush; };
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4BuffercoutDestination::G4BuffercoutDestination(std::size_t max)
|
||||
: m_buffer_out("")
|
||||
, m_buffer_err("")
|
||||
, m_maxSize(max)
|
||||
: m_maxSize(max),
|
||||
m_buffer_dbg(std::make_unique<BufferImpl>(max)),
|
||||
m_buffer_out(std::make_unique<BufferImpl>(max)),
|
||||
m_buffer_err(std::make_unique<BufferImpl>(max, [](auto& s) { std::cerr << s << std::flush; }))
|
||||
{}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -48,62 +100,50 @@ void G4BuffercoutDestination::Finalize()
|
||||
{
|
||||
FlushG4cerr();
|
||||
FlushG4cout();
|
||||
FlushG4debug();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4BuffercoutDestination::ReceiveG4debug(const G4String& msg)
|
||||
{
|
||||
return m_buffer_dbg->Receive(msg);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4BuffercoutDestination::ReceiveG4cout(const G4String& msg)
|
||||
{
|
||||
m_currentSize_out += msg.size();
|
||||
m_buffer_out << msg;
|
||||
// If there is a max size and it has been reached, flush
|
||||
if(m_maxSize > 0 && m_currentSize_out >= m_maxSize)
|
||||
{
|
||||
FlushG4cout();
|
||||
}
|
||||
return 0;
|
||||
return m_buffer_out->Receive(msg);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4BuffercoutDestination::ReceiveG4cerr(const G4String& msg)
|
||||
{
|
||||
m_currentSize_err += msg.size();
|
||||
m_buffer_err << msg;
|
||||
// If there is a max size and it has been reached, flush
|
||||
if(m_maxSize > 0 && m_currentSize_err >= m_maxSize)
|
||||
{
|
||||
FlushG4cerr();
|
||||
}
|
||||
return 0;
|
||||
return m_buffer_err->Receive(msg);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4BuffercoutDestination::FlushG4debug()
|
||||
{
|
||||
return m_buffer_dbg->Flush();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4BuffercoutDestination::FlushG4cout()
|
||||
{
|
||||
std::cout << m_buffer_out.str() << std::flush;
|
||||
ResetCout();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4BuffercoutDestination::ResetCout()
|
||||
{
|
||||
m_buffer_out.str("");
|
||||
m_buffer_out.clear();
|
||||
m_currentSize_out = 0;
|
||||
return m_buffer_out->Flush();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4BuffercoutDestination::FlushG4cerr()
|
||||
{
|
||||
std::cerr << m_buffer_err.str() << std::flush;
|
||||
ResetCerr();
|
||||
return 0;
|
||||
return m_buffer_err->Flush();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void G4BuffercoutDestination::ResetCerr()
|
||||
void G4BuffercoutDestination::SetMaxSize(std::size_t max)
|
||||
{
|
||||
m_buffer_err.str("");
|
||||
m_buffer_err.clear();
|
||||
m_currentSize_err = 0;
|
||||
m_maxSize = max;
|
||||
m_buffer_dbg->SetMaxSize(m_maxSize);
|
||||
m_buffer_out->SetMaxSize(m_maxSize);
|
||||
m_buffer_err->SetMaxSize(m_maxSize);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,17 @@ void G4FilecoutDestination::Close()
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4FilecoutDestination::ReceiveG4debug(const G4String& msg)
|
||||
{
|
||||
if(m_output == nullptr || !m_output->is_open())
|
||||
{
|
||||
Open(m_mode);
|
||||
}
|
||||
*m_output << msg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4FilecoutDestination::ReceiveG4cout(const G4String& msg)
|
||||
{
|
||||
|
||||
@@ -36,6 +36,14 @@ namespace
|
||||
G4Mutex out_mutex = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4LockcoutDestination::ReceiveG4debug(const G4String& msg)
|
||||
{
|
||||
G4AutoLock l(&out_mutex);
|
||||
// Forward call to base class
|
||||
return G4coutDestination::ReceiveG4debug(msg);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4LockcoutDestination::ReceiveG4cout(const G4String& msg)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "G4FilecoutDestination.hh"
|
||||
#include "G4LockcoutDestination.hh"
|
||||
#include "G4MasterForwardcoutDestination.hh"
|
||||
#include "G4strstreambuf.hh"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
@@ -49,9 +48,8 @@ namespace
|
||||
G4MTcoutDestination::G4MTcoutDestination(const G4int& threadId)
|
||||
: id(threadId)
|
||||
{
|
||||
// TODO: Move these two out of here and in the caller
|
||||
G4coutbuf.SetDestination(this);
|
||||
G4cerrbuf.SetDestination(this);
|
||||
// TODO: Move this out of here and in the caller
|
||||
G4iosSetDestination(this);
|
||||
|
||||
stateMgr = G4StateManager::GetStateManager();
|
||||
SetDefaultOutput(masterDestinationFlag, masterDestinationFmtFlag);
|
||||
@@ -85,6 +83,8 @@ void G4MTcoutDestination::SetDefaultOutput(G4bool addmasterDestination,
|
||||
// Default behavior, add a destination that uses cout and uses a mutex
|
||||
auto output = G4coutDestinationUPtr(new G4LockcoutDestination);
|
||||
ref_defaultOut = output.get();
|
||||
output->AddDebugTransformer(filter_out);
|
||||
output->AddDebugTransformer(f);
|
||||
output->AddCoutTransformer(filter_out);
|
||||
output->AddCoutTransformer(f);
|
||||
output->AddCerrTransformer(f);
|
||||
@@ -106,6 +106,7 @@ void G4MTcoutDestination::AddMasterOutput(G4bool formatAlsoMaster)
|
||||
this->ignoreCout ||
|
||||
(this->ignoreInit && this->stateMgr->GetCurrentState() == G4State_Idle));
|
||||
};
|
||||
forwarder->AddDebugTransformer(filter_out);
|
||||
forwarder->AddCoutTransformer(filter_out);
|
||||
if(formatAlsoMaster)
|
||||
{
|
||||
@@ -121,6 +122,7 @@ void G4MTcoutDestination::AddMasterOutput(G4bool formatAlsoMaster)
|
||||
msg = str.str();
|
||||
return true;
|
||||
};
|
||||
forwarder->AddDebugTransformer(f);
|
||||
forwarder->AddCoutTransformer(f);
|
||||
forwarder->AddCerrTransformer(f);
|
||||
}
|
||||
@@ -155,8 +157,8 @@ void G4MTcoutDestination::HandleFileCout(const G4String& fileN, G4bool ifAppend,
|
||||
(ifAppend ? std::ios_base::app : std::ios_base::trunc);
|
||||
auto output = G4coutDestinationUPtr(new G4FilecoutDestination(fileN, mode));
|
||||
|
||||
// This reacts only to G4cout, so let's make a filter that removes everything
|
||||
// from G4cerr
|
||||
// This reacts only to G4cout, so let's make a filter that ignores all other streams
|
||||
output->AddDebugTransformer([](G4String&) { return false; });
|
||||
output->AddCerrTransformer([](G4String&) { return false; });
|
||||
push_back(std::move(output));
|
||||
// Silence G4cout from default formatter
|
||||
@@ -179,6 +181,7 @@ void G4MTcoutDestination::HandleFileCerr(const G4String& fileN, G4bool ifAppend,
|
||||
std::ios_base::openmode mode =
|
||||
(ifAppend ? std::ios_base::app : std::ios_base::trunc);
|
||||
auto output = G4coutDestinationUPtr(new G4FilecoutDestination(fileN, mode));
|
||||
output->AddDebugTransformer([](G4String&) { return false; });
|
||||
output->AddCoutTransformer([](G4String&) { return false; });
|
||||
push_back(std::move(output));
|
||||
if(suppressDefault)
|
||||
@@ -285,10 +288,36 @@ void G4MTcoutDestination::DumpBuffer()
|
||||
{
|
||||
G4AutoLock l(&coutm);
|
||||
std::ostringstream msg;
|
||||
G4bool sep = false;
|
||||
|
||||
sep = false;
|
||||
msg.str("");
|
||||
msg.clear();
|
||||
msg << "=======================\n";
|
||||
msg << "debug buffer(s) for worker with ID:" << id << std::endl;
|
||||
G4coutDestination::ReceiveG4cout(msg.str());
|
||||
std::for_each(begin(), end(), [this, &sep](G4coutDestinationUPtr& el) {
|
||||
auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
|
||||
if(cout != nullptr)
|
||||
{
|
||||
cout->FlushG4debug();
|
||||
if(sep)
|
||||
{
|
||||
G4coutDestination::ReceiveG4cout("==========\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sep = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sep = false;
|
||||
msg.str("");
|
||||
msg.clear();
|
||||
msg << "=======================\n";
|
||||
msg << "cout buffer(s) for worker with ID:" << id << std::endl;
|
||||
G4coutDestination::ReceiveG4cout(msg.str());
|
||||
G4bool sep = false;
|
||||
std::for_each(begin(), end(), [this, &sep](G4coutDestinationUPtr& el) {
|
||||
auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
|
||||
if(cout != nullptr)
|
||||
@@ -304,6 +333,7 @@ void G4MTcoutDestination::DumpBuffer()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sep = false;
|
||||
msg.str("");
|
||||
msg.clear();
|
||||
@@ -326,5 +356,6 @@ void G4MTcoutDestination::DumpBuffer()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
G4coutDestination::ReceiveG4cout("=======================\n");
|
||||
}
|
||||
|
||||
@@ -36,6 +36,21 @@ namespace
|
||||
G4Mutex out_mutex = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4MasterForwardcoutDestination::ReceiveG4debug(const G4String& msg)
|
||||
{
|
||||
// If a master destination is set check that we are not in a recursive
|
||||
// situation, send the message to the master, using a lock to serialize calls
|
||||
// Master is probably a (G)UI that is not thread-safe
|
||||
|
||||
if((masterG4coutDestination != nullptr) && this != masterG4coutDestination)
|
||||
{
|
||||
G4AutoLock l(&out_mutex);
|
||||
return masterG4coutDestination->ReceiveG4debug_(msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4MasterForwardcoutDestination::ReceiveG4cout(const G4String& msg)
|
||||
{
|
||||
|
||||
@@ -591,6 +591,11 @@ void G4PhysicsModelCatalog::Initialize() {
|
||||
// IF YOU ARE NOT SURE, PLEASE CONTACT ONE OF THE COORDINATORS OF THE
|
||||
// GEANT4 PHYSICS WORKING GROUPS.
|
||||
|
||||
// Class: G4HadronicAbsorptionINCLXX
|
||||
InsertModel( 26040, "model_hINCLXXCaptureAtRest_EMCascade" );
|
||||
InsertModel( 26041, "model_hINCLXXCaptureAtRest_NuclearCapture" );
|
||||
InsertModel( 26042, "model_hINCLXXCaptureAtRest_DIO" );
|
||||
|
||||
// ...
|
||||
|
||||
SanityCheck();
|
||||
|
||||
@@ -37,10 +37,18 @@ G4coutDestination* G4coutDestination::masterG4coutDestination = nullptr;
|
||||
// --------------------------------------------------------------------
|
||||
void G4coutDestination::ResetTransformers()
|
||||
{
|
||||
transformersDebug.clear();
|
||||
transformersCout.clear();
|
||||
transformersCerr.clear();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4coutDestination::ReceiveG4debug(const G4String& msg)
|
||||
{
|
||||
std::cout << msg << std::flush;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4coutDestination::ReceiveG4cout(const G4String& msg)
|
||||
{
|
||||
@@ -55,6 +63,28 @@ G4int G4coutDestination::ReceiveG4cerr(const G4String& msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4coutDestination::ReceiveG4debug_(const G4String& msg)
|
||||
{
|
||||
// Avoid copy of string if not necessary
|
||||
if(!transformersDebug.empty())
|
||||
{
|
||||
G4String m = msg;
|
||||
G4bool result = true;
|
||||
for(const auto& el : transformersDebug)
|
||||
{
|
||||
result &= el(m);
|
||||
if(!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (result ? ReceiveG4debug(m) : 0);
|
||||
}
|
||||
|
||||
return ReceiveG4debug(msg);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int G4coutDestination::ReceiveG4cout_(const G4String& msg)
|
||||
{
|
||||
|
||||
@@ -122,8 +122,7 @@ namespace G4coutFormatters
|
||||
void SetupStyleGlobally(const G4String& news)
|
||||
{
|
||||
static G4coutDestination ss;
|
||||
G4coutbuf.SetDestination(&ss);
|
||||
G4cerrbuf.SetDestination(&ss);
|
||||
G4iosSetDestination(&ss);
|
||||
G4coutFormatters::HandleStyle(&ss, news);
|
||||
G4coutFormatters::SetMasterStyle(news);
|
||||
}
|
||||
|
||||
@@ -29,20 +29,153 @@
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "G4strstreambuf.hh"
|
||||
|
||||
#include "G4coutDestination.hh"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
|
||||
G4strstreambuf*& _G4coutbuf_p()
|
||||
namespace
|
||||
{
|
||||
G4ThreadLocalStatic auto* _instance = new G4strstreambuf();
|
||||
// Concrete streambuf redirecting output to G4coutDestination via G4cout etc
|
||||
// Templated on two policy types to determine:
|
||||
// - DestinationPolicy: which member member function of G4coutDestination to redirect to
|
||||
// - DefaultPolicy: what to do if G4coutDestination is default (nullptr)
|
||||
template <typename DestinationPolicy, typename DefaultPolicy>
|
||||
class G4strstreambuf : public std::basic_streambuf<char>
|
||||
{
|
||||
public:
|
||||
G4strstreambuf()
|
||||
{
|
||||
size = 4095;
|
||||
buffer = new char[size + 1];
|
||||
}
|
||||
|
||||
~G4strstreambuf() override
|
||||
{
|
||||
// flushing buffer...
|
||||
// std::cout is used because destination object may not be alive.
|
||||
if (count != 0) {
|
||||
buffer[count] = '\0';
|
||||
std::cout << buffer;
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
G4strstreambuf(const G4strstreambuf&) = delete;
|
||||
G4strstreambuf& operator=(const G4strstreambuf&) = delete;
|
||||
|
||||
G4int overflow(G4int c = EOF) override
|
||||
{
|
||||
G4int result = 0;
|
||||
if (count >= size) result = sync();
|
||||
|
||||
buffer[count] = (char)c;
|
||||
count++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
G4int sync() override
|
||||
{
|
||||
buffer[count] = '\0';
|
||||
count = 0;
|
||||
return ReceiveString();
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
virtual G4int underflow() { return 0; }
|
||||
#endif
|
||||
|
||||
void SetDestination(G4coutDestination* dest) { destination = dest; }
|
||||
|
||||
inline G4int ReceiveString()
|
||||
{
|
||||
G4String stringToSend(buffer);
|
||||
if (destination != nullptr) {
|
||||
return DestinationPolicy::PostMessage(destination, stringToSend);
|
||||
}
|
||||
return DefaultPolicy::PostMessage(stringToSend);
|
||||
}
|
||||
|
||||
private:
|
||||
char* buffer = nullptr;
|
||||
G4int count = 0;
|
||||
G4int size = 0;
|
||||
G4coutDestination* destination = nullptr;
|
||||
};
|
||||
|
||||
// Policies
|
||||
struct PostToG4debug
|
||||
{
|
||||
static inline G4int PostMessage(G4coutDestination* d, const G4String& s)
|
||||
{
|
||||
return d->ReceiveG4debug_(s);
|
||||
}
|
||||
};
|
||||
|
||||
struct PostToG4cout
|
||||
{
|
||||
static inline G4int PostMessage(G4coutDestination* d, const G4String& s)
|
||||
{
|
||||
return d->ReceiveG4cout_(s);
|
||||
}
|
||||
};
|
||||
|
||||
struct PostToG4cerr
|
||||
{
|
||||
static inline G4int PostMessage(G4coutDestination* d, const G4String& s)
|
||||
{
|
||||
return d->ReceiveG4cerr_(s);
|
||||
}
|
||||
};
|
||||
|
||||
struct DefaultToCout
|
||||
{
|
||||
static inline G4int PostMessage(const G4String& s)
|
||||
{
|
||||
std::cout << s << std::flush;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct DefaultToCerr
|
||||
{
|
||||
static inline G4int PostMessage(const G4String& s)
|
||||
{
|
||||
std::cerr << s << std::flush;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
using G4debugstreambuf = G4strstreambuf<PostToG4debug, DefaultToCout>;
|
||||
using G4coutstreambuf = G4strstreambuf<PostToG4cout, DefaultToCout>;
|
||||
using G4cerrstreambuf = G4strstreambuf<PostToG4cerr, DefaultToCerr>;
|
||||
} // namespace
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
// --- StreamBuffers
|
||||
G4debugstreambuf*& _G4debugbuf_p()
|
||||
{
|
||||
G4ThreadLocalStatic auto* _instance = new G4debugstreambuf;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
G4strstreambuf*& _G4cerrbuf_p()
|
||||
G4coutstreambuf*& _G4coutbuf_p()
|
||||
{
|
||||
G4ThreadLocalStatic auto* _instance = new G4strstreambuf();
|
||||
G4ThreadLocalStatic auto* _instance = new G4coutstreambuf;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
G4cerrstreambuf*& _G4cerrbuf_p()
|
||||
{
|
||||
G4ThreadLocalStatic auto* _instance = new G4cerrstreambuf;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
// --- Streams
|
||||
std::ostream*& _G4debug_p()
|
||||
{
|
||||
G4ThreadLocalStatic auto* _instance = new std::ostream(_G4debugbuf_p());
|
||||
return _instance;
|
||||
}
|
||||
|
||||
@@ -58,59 +191,74 @@ std::ostream*& _G4cerr_p()
|
||||
return _instance;
|
||||
}
|
||||
|
||||
# define G4coutbuf (*_G4coutbuf_p())
|
||||
# define G4cerrbuf (*_G4cerrbuf_p())
|
||||
# define G4cout (*_G4cout_p())
|
||||
# define G4cerr (*_G4cerr_p())
|
||||
|
||||
void G4iosInitialization()
|
||||
{
|
||||
if(_G4coutbuf_p() == nullptr)
|
||||
{
|
||||
_G4coutbuf_p() = new G4strstreambuf;
|
||||
// --- Stream Buffers
|
||||
if (_G4debugbuf_p() == nullptr) {
|
||||
_G4debugbuf_p() = new G4debugstreambuf;
|
||||
}
|
||||
if(_G4cerrbuf_p() == nullptr)
|
||||
{
|
||||
_G4cerrbuf_p() = new G4strstreambuf;
|
||||
if (_G4coutbuf_p() == nullptr) {
|
||||
_G4coutbuf_p() = new G4coutstreambuf;
|
||||
}
|
||||
if(_G4cout_p() == &std::cout || _G4cout_p() == nullptr)
|
||||
{
|
||||
if (_G4cerrbuf_p() == nullptr) {
|
||||
_G4cerrbuf_p() = new G4cerrstreambuf;
|
||||
}
|
||||
|
||||
// --- Streams
|
||||
if (_G4debug_p() == &std::cout || _G4debug_p() == nullptr) {
|
||||
_G4debug_p() = new std::ostream(_G4debugbuf_p());
|
||||
}
|
||||
if (_G4cout_p() == &std::cout || _G4cout_p() == nullptr) {
|
||||
_G4cout_p() = new std::ostream(_G4coutbuf_p());
|
||||
}
|
||||
if(_G4cerr_p() == &std::cerr || _G4cerr_p() == nullptr)
|
||||
{
|
||||
if (_G4cerr_p() == &std::cerr || _G4cerr_p() == nullptr) {
|
||||
_G4cerr_p() = new std::ostream(_G4cerrbuf_p());
|
||||
}
|
||||
}
|
||||
|
||||
void G4iosFinalization()
|
||||
{
|
||||
// Reverse order
|
||||
// --- Streams
|
||||
delete _G4debug_p();
|
||||
_G4debug_p() = &std::cout;
|
||||
delete _G4cout_p();
|
||||
_G4cout_p() = &std::cout;
|
||||
delete _G4cerr_p();
|
||||
_G4cerr_p() = &std::cerr;
|
||||
|
||||
// --- Stream Buffers
|
||||
delete _G4debugbuf_p();
|
||||
_G4debugbuf_p() = nullptr;
|
||||
delete _G4coutbuf_p();
|
||||
_G4coutbuf_p() = nullptr;
|
||||
delete _G4cerrbuf_p();
|
||||
_G4cerrbuf_p() = nullptr;
|
||||
}
|
||||
|
||||
# define G4debugbuf (*_G4debugbuf_p())
|
||||
# define G4coutbuf (*_G4coutbuf_p())
|
||||
# define G4cerrbuf (*_G4cerrbuf_p())
|
||||
|
||||
// These two functions are guaranteed to be called at load and
|
||||
// unload of the library containing this code.
|
||||
namespace
|
||||
{
|
||||
# ifndef WIN32
|
||||
void setupG4ioSystem() __attribute__((constructor));
|
||||
void cleanupG4ioSystem() __attribute__((destructor));
|
||||
void setupG4ioSystem() __attribute__((constructor));
|
||||
void cleanupG4ioSystem() __attribute__((destructor));
|
||||
# endif
|
||||
void setupG4ioSystem() { G4iosInitialization(); }
|
||||
void cleanupG4ioSystem() { G4iosFinalization(); }
|
||||
void setupG4ioSystem() { G4iosInitialization(); }
|
||||
void cleanupG4ioSystem() { G4iosFinalization(); }
|
||||
} // namespace
|
||||
|
||||
#else // Sequential
|
||||
|
||||
G4strstreambuf G4coutbuf;
|
||||
G4strstreambuf G4cerrbuf;
|
||||
G4debugstreambuf G4debugbuf;
|
||||
G4coutstreambuf G4coutbuf;
|
||||
G4cerrstreambuf G4cerrbuf;
|
||||
|
||||
std::ostream G4debug(&G4debugbuf);
|
||||
std::ostream G4cout(&G4coutbuf);
|
||||
std::ostream G4cerr(&G4cerrbuf);
|
||||
|
||||
@@ -118,3 +266,10 @@ void G4iosInitialization() {}
|
||||
void G4iosFinalization() {}
|
||||
|
||||
#endif
|
||||
|
||||
void G4iosSetDestination(G4coutDestination* sink)
|
||||
{
|
||||
G4debugbuf.SetDestination(sink);
|
||||
G4coutbuf.SetDestination(sink);
|
||||
G4cerrbuf.SetDestination(sink);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user