Line data Source code
1 : /*
2 : * StandardStream.cxx
3 : * ers
4 : *
5 : * Created by Serguei Kolos on 02.08.05.
6 : * Copyright 2004 CERN. All rights reserved.
7 : *
8 : */
9 :
10 : #include <iostream>
11 : #include <fstream>
12 : #include <mutex>
13 :
14 : #include <ers/SampleIssues.hpp>
15 :
16 : #include <ers/internal/StandardStream.hpp>
17 : #include <ers/internal/FormattedStandardStream.hpp>
18 :
19 : namespace
20 : {
21 : struct OutDevice
22 : {
23 1072 : explicit OutDevice( std::ostream & out )
24 1072 : : out_( out )
25 1072 : { ; }
26 :
27 2036 : std::ostream & stream() const
28 2036 : { return out_; }
29 :
30 0 : const OutDevice & device()
31 0 : { return *this; }
32 :
33 : private:
34 : OutDevice(const OutDevice &) = delete;
35 : OutDevice & operator=(const OutDevice &) = delete;
36 :
37 : private:
38 : std::ostream & out_;
39 : };
40 :
41 : struct ObjectLock
42 : {
43 : protected:
44 0 : ObjectLock() = default;
45 :
46 0 : std::mutex & mutex()
47 : {
48 0 : return mutex_;
49 : }
50 :
51 : private:
52 : ObjectLock(const ObjectLock &) = delete;
53 : ObjectLock & operator=(const ObjectLock &) = delete;
54 :
55 : private:
56 : std::mutex mutex_;
57 : };
58 :
59 : template <int LockDiscriminator>
60 : struct ClassLock
61 : {
62 : protected:
63 : ClassLock() = default;
64 :
65 1018 : std::mutex & mutex()
66 : {
67 1018 : static std::mutex * m = new std::mutex;
68 1018 : return *m;
69 : }
70 :
71 : private:
72 : ClassLock(const ClassLock &) = delete;
73 : ClassLock & operator=(const ClassLock &) = delete;
74 : };
75 :
76 : template <class L=ObjectLock>
77 : struct LockableDevice : public L,
78 : public OutDevice
79 : {
80 : using L::mutex;
81 :
82 : struct LockedDevice : public OutDevice
83 : {
84 1018 : LockedDevice( std::ostream & out, std::mutex & mutex )
85 : : OutDevice( out ),
86 1018 : m_lock(mutex)
87 1018 : { ; }
88 :
89 : private:
90 : LockedDevice( const LockedDevice & ) = delete;
91 : LockedDevice & operator=( const LockedDevice & ) = delete;
92 :
93 : private:
94 : std::unique_lock<std::mutex> m_lock;
95 : };
96 :
97 54 : LockableDevice( std::ostream & out )
98 54 : : OutDevice( out )
99 54 : { ; }
100 :
101 1018 : LockedDevice device()
102 : {
103 1018 : return LockedDevice( stream(), mutex() );
104 : }
105 : };
106 :
107 :
108 : template <class D>
109 : struct OutputDevice : public D
110 : {
111 38 : OutputDevice( const std::string & = "" )
112 38 : : D( std::cout )
113 38 : { ; }
114 : };
115 :
116 : template <class D>
117 : struct ErrorDevice : public D
118 : {
119 16 : ErrorDevice( const std::string & = "" )
120 16 : : D( std::cerr )
121 16 : { ; }
122 : };
123 :
124 : template <class D>
125 : struct FileDevice : public D
126 : {
127 0 : FileDevice( const std::string & file_name )
128 : : D( out_ ),
129 0 : out_( file_name.c_str() )
130 : {
131 0 : if ( !out_ )
132 : {
133 0 : throw ers::CantOpenFile( ERS_HERE, file_name.c_str() );
134 : }
135 0 : }
136 :
137 : private:
138 : std::ofstream out_;
139 : };
140 : }
141 :
142 41 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<FileDevice<OutDevice> >, "file", file_name )
143 41 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<OutputDevice<OutDevice> >, "stdout", ERS_EMPTY)
144 41 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<ErrorDevice<OutDevice> >, "stderr", ERS_EMPTY)
145 :
146 41 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<FileDevice<LockableDevice<> > >, "lfile", file_name )
147 79 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<OutputDevice<LockableDevice<ClassLock<1> > > >, "lstdout", ERS_EMPTY)
148 57 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<ErrorDevice<LockableDevice<ClassLock<2> > > >, "lstderr", ERS_EMPTY)
149 :
150 41 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<FileDevice<OutDevice> >, "ffile", format )
151 41 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<OutputDevice<OutDevice> >, "fstdout", format )
152 41 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<ErrorDevice<OutDevice> >, "fstderr", format )
153 :
154 41 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<FileDevice<LockableDevice<> > >, "lffile", format )
155 41 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<OutputDevice<LockableDevice<ClassLock<1> > > >, "lfstdout", format )
156 41 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<ErrorDevice<LockableDevice<ClassLock<2> > > >, "lfstderr", format )
|