ostream_handle.h
Go to the documentation of this file.
1 #ifndef cetlib_ostream_handle_h
2 #define cetlib_ostream_handle_h
3 
4 /*
5  ====================================================================
6 
7  ostream_handle
8 
9  This is a handle for dealing with owning/non-owning ostream
10  objects. There are use cases when one needs an externally provided
11  stream (e.g. std::cout or std::cerr), and cases when one needs an
12  owned stream (std::ofstream). This handle enables a consistent use
13  of both.
14 
15  For the 'std::ofstream' case, the destructor of ostream_handle
16  implicitly calls std::ofstream::close().
17 
18  Example:
19 
20  cet::ostream_handle os {std::cout};
21  cet::ostream_handle toFile {"myFile.txt"};
22 
23  os << 4 << "thirteen"; // write to STDOUT
24  toFile << 5 << "fourteen"; // write to "myFile.txt"
25  os = std::move(toFile); // Reset 'os' to stream to "myFile.txt"
26  os << 6 << "fifteen"; // write to "myFile.txt"
27 
28  ====================================================================
29 */
30 
32 
33 #include <memory>
34 
35 namespace cet {
36 
38  public:
39  ostream_handle() = default;
40 
41  // Writes to (e.g.) cout, which is owned by the standard library.
42  ostream_handle(std::ostream& os)
43  : osh_{std::make_unique<detail::ostream_observer>(os)}
44  {}
45 
46  // Writes to ofstream file.
48  std::ios_base::openmode const mode = std::ios_base::out)
49  : osh_{std::make_unique<detail::ostream_owner<std::ofstream>>(
50  std::ofstream(fn, mode))}
51  {}
52 
53  // Writes to provided arbitrary ostream (takes ownership).
54  template <
55  typename OSTREAM,
56  typename = std::enable_if_t<std::is_base_of_v<std::ostream, OSTREAM>>>
57  ostream_handle(OSTREAM&& os)
58  : osh_{std::make_unique<detail::ostream_owner<OSTREAM>>(std::move(os))}
59  {}
60 
62  operator<<(char const msg[])
63  {
64  osh_->stream() << msg;
65  return *this;
66  }
67 
68  template <typename T>
70  operator<<(T const& t)
71  {
72  osh_->stream() << t;
73  return *this;
74  }
75 
76  void
78  {
79  osh_->stream().flush();
80  }
81  explicit operator bool() const { return static_cast<bool>(osh_->stream()); }
82  operator std::ostream&() { return osh_->stream(); }
83 
84  private:
85  std::unique_ptr<detail::ostream_handle_base> osh_;
86  };
87 
88  inline ostream_handle
89  select_stream(std::string const& filename, std::ostream& default_os)
90  {
91  return empty(filename) ? ostream_handle{default_os} :
92  ostream_handle{filename};
93  }
94 }
95 
96 #endif /* cetlib_ostream_handle_h */
97 
98 // Local variables:
99 // mode: c++
100 // End:
ostream_handle select_stream(std::string const &filename, std::ostream &default_os)
std::unique_ptr< detail::ostream_handle_base > osh_
void msg(const char *fmt,...)
Definition: message.cpp:107
std::string string
Definition: nybbler.cc:12
ostream_handle(OSTREAM &&os)
ostream_handle()=default
ostream_handle & operator<<(char const msg[])
string filename
Definition: train.py:213
QAsciiDict< Entry > fn
def move(depos, offset)
Definition: depos.py:107
ostream_handle(std::string const &fn, std::ios_base::openmode const mode=std::ios_base::out)
int bool
Definition: qglobal.h:345
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
ostream_handle(std::ostream &os)