55 #ifndef OPENMESH_MOSTREAM_HH
56 #define OPENMESH_MOSTREAM_HH
63 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
64 # include <streambuf.h>
73 #if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
81 #ifndef DOXY_IGNORE_THIS
87 class basic_multiplex_target
90 virtual ~basic_multiplex_target() {}
91 virtual void operator<<(
const std::string& _s) = 0;
96 class multiplex_target :
public basic_multiplex_target
99 multiplex_target(T& _t) : target_(_t) {}
100 virtual void operator<<(
const std::string& _s) { target_ << _s; }
110 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
111 # define STREAMBUF streambuf
112 # define INT_TYPE int
115 # define STREAMBUF std::basic_streambuf<char>
118 class multiplex_streambuf :
public STREAMBUF
122 typedef STREAMBUF base_type;
123 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
124 typedef int int_type;
127 static int_type eof() {
return -1; }
128 static char to_char_type(int_type c) {
return char(c); }
131 typedef base_type::int_type int_type;
132 typedef base_type::traits_type traits_type;
136 multiplex_streambuf() : enabled_(true) { buffer_.reserve(100); }
139 ~multiplex_streambuf()
141 tmap_iter t_it(target_map_.begin()), t_end(target_map_.end());
142 for (; t_it!=t_end; ++t_it)
148 bool is_enabled()
const {
return enabled_; }
149 void enable() { enabled_ =
true; }
150 void disable() { enabled_ =
false; }
154 template <
class T>
bool connect(T& _target)
156 void* key = (
void*) &_target;
158 if (target_map_.find(key) != target_map_.end())
161 target_type* mtarget =
new multiplex_target<T>(_target);
162 target_map_[key] = mtarget;
170 template <
class T>
bool disconnect(T& _target)
172 void* key = (
void*) &_target;
173 tmap_iter t_it = target_map_.find(key);
175 if (t_it != target_map_.end())
177 __disconnect(t_it->second);
178 target_map_.erase(t_it);
192 #if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
193 std::lock_guard<std::mutex> lck (serializer_);
196 if (!buffer_.empty())
198 if (enabled_) multiplex();
199 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
205 return base_type::sync();
212 int_type overflow(int_type _c = multiplex_streambuf::traits_type::eof())
214 char c = traits_type::to_char_type(_c);
217 #if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
219 std::lock_guard<std::mutex> lck (serializer_);
220 buffer_.push_back(c);
223 buffer_.push_back(c);
226 if (c ==
'\n') sync();
233 typedef basic_multiplex_target target_type;
234 typedef std::vector<target_type*> target_list;
235 typedef target_list::iterator tlist_iter;
236 typedef std::map<void*, target_type*> target_map;
237 typedef target_map::iterator tmap_iter;
241 void __connect(target_type* _target) { targets_.push_back(_target); }
245 void __disconnect(target_type* _target) {
246 targets_.erase(std::find(targets_.begin(), targets_.end(), _target));
253 tlist_iter t_it(targets_.begin()), t_end(targets_.end());
254 for (; t_it!=t_end; ++t_it)
261 target_list targets_;
262 target_map target_map_;
267 #if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
268 std::mutex serializer_;
288 class mostream :
public std::ostream
293 explicit mostream() :
std::ostream(NULL) { init(&streambuffer_); }
297 template <
class T>
bool connect(T& _target)
299 return streambuffer_.connect(_target);
304 template <
class T>
bool disconnect(T& _target)
306 return streambuffer_.disconnect(_target);
311 bool is_enabled()
const {
return streambuffer_.is_enabled(); }
314 void enable() { streambuffer_.enable(); }
317 void disable() { streambuffer_.disable(); }
321 multiplex_streambuf streambuffer_;
329 #endif // OPENMESH_MOSTREAM_HH defined
auto operator<<(std::ostream &os, const VectorT< Scalar, DIM > &_vec) -> typename std::enable_if< sizeof(decltype(os<< _vec[0])) >=0
output a vector by printing its space-separated compontens