}
} // namespace detail
-std::ostream* ManagedErr::defaultValue() const { return &std::cerr; }
+ManagedErr::ManagedErr() : ManagedStream(&std::cerr, "stderr") {}
bool ManagedErr::specialCases(const std::string& value)
{
if (value == "stderr" || value == "--")
{
- d_stream.reset();
+ d_nonowned = &std::cerr;
+ d_owned.reset();
+ d_description = "stderr";
+ return true;
+ }
+ else if (value == "stdout")
+ {
+ d_nonowned = &std::cout;
+ d_owned.reset();
+ d_description = "stdout";
return true;
}
return false;
}
-std::istream* ManagedIn::defaultValue() const { return &std::cin; }
+ManagedIn::ManagedIn() : ManagedStream(&std::cin, "stdin") {}
bool ManagedIn::specialCases(const std::string& value)
{
if (value == "stdin" || value == "--")
{
- d_stream.reset();
+ d_nonowned = &std::cin;
+ d_owned.reset();
+ d_description = "stdin";
return true;
}
return false;
}
-std::ostream* ManagedOut::defaultValue() const { return &std::cout; }
+ManagedOut::ManagedOut() : ManagedStream(&std::cout, "stdout") {}
bool ManagedOut::specialCases(const std::string& value)
{
if (value == "stdout" || value == "--")
{
- d_stream.reset();
+ d_nonowned = &std::cout;
+ d_owned.reset();
+ d_description = "stdout";
+ return true;
+ }
+ else if (value == "stderr")
+ {
+ d_nonowned = &std::cerr;
+ d_owned.reset();
+ d_description = "stderr";
return true;
}
return false;
class ManagedStream
{
public:
- ManagedStream() {}
+ ManagedStream(Stream* nonowned, std::string description)
+ : d_nonowned(nonowned), d_description(std::move(description)) {}
virtual ~ManagedStream() {}
/**
if (specialCases(value)) return;
if constexpr (std::is_same<Stream, std::ostream>::value)
{
- d_stream.reset(detail::openOStream(value));
+ d_nonowned = nullptr;
+ d_owned.reset(detail::openOStream(value));
+ d_description = value;
}
else if constexpr (std::is_same<Stream, std::istream>::value)
{
- d_stream.reset(detail::openIStream(value));
+ d_nonowned = nullptr;
+ d_owned.reset(detail::openIStream(value));
+ d_description = value;
}
}
operator Stream&() const { return *getPtr(); }
operator Stream*() const { return getPtr(); }
+ const std::string& description() const { return d_description; }
+
protected:
- std::shared_ptr<Stream> d_stream;
+ Stream* d_nonowned;
+ std::shared_ptr<Stream> d_owned;
+ std::string d_description = "<null>";
private:
- /** Returns the value to be used if d_stream is not set. */
- virtual Stream* defaultValue() const = 0;
/**
* Check if there is a special case for this value. If so, the implementation
* should set d_stream appropriately and return true to skip the default
*/
virtual bool specialCases(const std::string& value) = 0;
- /** Return the pointer, either from d_stream of from defaultValue(). */
+ /** Return the pointer, either from d_nonowned or d_owned. */
Stream* getPtr() const
{
- if (d_stream) return d_stream.get();
- return defaultValue();
+ if (d_nonowned != nullptr) return d_nonowned;
+ return d_owned.get();
}
};
template <typename Stream>
std::ostream& operator<<(std::ostream& os, const ManagedStream<Stream>& ms)
{
- return os << "ManagedStream";
+ return os << ms.description();
}
/**
*/
class ManagedErr : public ManagedStream<std::ostream>
{
- std::ostream* defaultValue() const override final;
+ public:
+ ManagedErr();
+
+ private:
bool specialCases(const std::string& value) override final;
};
*/
class ManagedIn : public ManagedStream<std::istream>
{
- std::istream* defaultValue() const override final;
+ public:
+ ManagedIn();
+
+ private:
bool specialCases(const std::string& value) override final;
};
*/
class ManagedOut : public ManagedStream<std::ostream>
{
- std::ostream* defaultValue() const override final;
+ public:
+ ManagedOut();
+
+ private:
bool specialCases(const std::string& value) override final;
};