Library of Assembled Shared Sources
proxy_o_stream.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2018 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45/** @class lass::io::ProxyOStream
46 * @brief A proxy output stream can distribute output to multiple destination streams.
47 * @author BdG
48 * @date 2003
49 *
50 * You can add multiple destination streams to a proxy stream, and all output to the
51 * proxy stream will be redirected to all these destinations.
52 *
53 * You can also assign a filter to the proxy, and only messages with levels set in the
54 * filter will pass. e.g. if you set the filter of the proxy as
55 * proxy.setFilter() = 0, then only messages of warning or error levels will
56 * pass.
57 *
58 * How do you tell what level your message has? Simple, before you use the insertor,
59 * you call the function operator on the stream with the correct level. This returns
60 * a lock on the proxy, and now you send the message to the lock (by the insertor)
61 * Wheter this message will pass or not, is determined by the lock.
62 * At the end of the lifetime of the lock, the proxy is also flushed.
63 *
64 * proxy(Warning) << "This is a warning: " << theWarning;
65 *
66 * In the above example, the proxy is locked in warning level, and the string and
67 * theWarning is passed to the lock. At the end, the lock flushes te proxy.
68 *
69 * If you don't use the function operator to set the message level, the level is implicit
70 * set to ProxyOStream::Note.
71 *
72 * OK, seriously, i have no longer any idea why we need this ... get rid of it?
73 */
74
75
76
77#ifndef LASS_GUARDIAN_OF_INCLUSION_IO_PROXY_O_STREAM_H
78#define LASS_GUARDIAN_OF_INCLUSION_IO_PROXY_O_STREAM_H
79
80#include "io_common.h"
81#include "../util/bit_manip.h"
82#include <mutex>
83
84#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
85# pragma warning(push)
86# pragma warning(disable: 4267) // 'argument' : conversion from 'size_t' to 'unsigned int', possible loss of data
87#endif
88
89namespace lass
90{
91namespace io
92{
93
94class ProxyOStream;
95
96namespace impl
97{
98
99class LASS_DLL ProxyOStreamLock
100{
101public:
102 typedef unsigned TMask;
103
104 ProxyOStreamLock(ProxyOStream* proxy, TMask messageMask);
105 ProxyOStreamLock(const ProxyOStreamLock&) = delete;
106 ProxyOStreamLock(ProxyOStreamLock&& other);
107 ~ProxyOStreamLock();
108
109 ProxyOStreamLock & operator=(const ProxyOStreamLock&) = delete;
110 ProxyOStreamLock & operator=(ProxyOStreamLock&&) = delete;
111
112 template <typename T> ProxyOStreamLock& operator<< (const T& x);
113 ProxyOStreamLock& operator<<(std::ostream& (*x) (std::ostream&));
114
115private:
116 ProxyOStream* proxy_;
117 TMask messageMask_;
118};
119
120}
121
122
124{
125public:
126
127 typedef unsigned TMask;
128 static const TMask acceptAll = static_cast<TMask>(-1);
129
130 // structors & methods
131
132 //ProxyOStream();
133 ProxyOStream(std::ostream* destination = &std::cout, TMask filterMask = acceptAll);
134
135 void add(std::ostream* destination, TMask filterMask = acceptAll);
136 void remove(std::ostream* destination);
137
138 TMask filter(std::ostream* destination) const;
139 void setFilter(std::ostream* destination, TMask filterMask);
140
141 impl::ProxyOStreamLock operator()(TMask filterMask = acceptAll);
142
143 /** ProxyOStreamLock proxy stream for output on 'acceptAll' and distribute input.
144 * This command will give command to a lock, as if the message mask is acceptAll.
145 * This has the same effect as (*this)(acceptAll) << x;
146 */
147 template <typename T> impl::ProxyOStreamLock operator<< (const T& x)
148 {
149 impl::ProxyOStreamLock result(this, acceptAll);
150 result << x;
151 return result;
152 }
153
154 impl::ProxyOStreamLock operator<< (std::ostream& (*x) (std::ostream&));
155
156 void flush();
157
158private:
159 friend class impl::ProxyOStreamLock;
160
161 struct Destination
162 {
163 std::ostream* stream;
164 TMask mask;
165 };
166
167 typedef std::vector<Destination> TDestinations;
168
169 TDestinations::iterator findStream(std::ostream* stream);
170
171 TDestinations destinations_;
172 std::mutex lock_;
173};
174
175
176namespace impl
177{
178
179/** distribute input over all destination streams.
180 * Only distribute input if it's still locking a proxy (i.e. if proxy_ != Null).
181 */
182template <typename T>
183ProxyOStreamLock& ProxyOStreamLock::operator<< (const T& x)
184{
185 if (proxy_)
186 {
187 for (ProxyOStream::TDestinations::iterator i = proxy_->destinations_.begin(), end = proxy_->destinations_.end(); i != end; ++i)
188 {
189 if (util::checkMaskedSome(i->mask, messageMask_))
190 {
191 LASS_ENFORCE_STREAM(*(i->stream)) << x;
192 }
193 }
194 }
195 return *this;
196}
197
198}
199
200}
201
202}
203
204#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
205# pragma warning(pop)
206#endif
207
208#endif
A proxy output stream can distribute output to multiple destination streams.
void add(std::ostream *destination, TMask filterMask=acceptAll)
Add a std::ostream to the list of destination streams.
TMask filter(std::ostream *destination) const
Return accept mask on destination stream.
void setFilter(std::ostream *destination, TMask filterMask)
Set filter on destination stream.
ProxyOStream(std::ostream *destination=&std::cout, TMask filterMask=acceptAll)
Construct a proxy with a destination, and set a filter for it.
void remove(std::ostream *destination)
Remove a std::ostream from the list of destination streams.
bool checkMaskedSome(T a_bits, const T &a_mask)
Check the masked bits and return true if at least one is set.
#define LASS_DLL
DLL interface: import or export symbols?
streams, binary streams, vrmlstreams, ...
Library for Assembled Shared Sources.
Definition config.h:53