diff --git a/STL_Extension/include/CGAL/Exception_ostream.h b/STL_Extension/include/CGAL/Exception_ostream.h index f9784941378..9ac492a1263 100644 --- a/STL_Extension/include/CGAL/Exception_ostream.h +++ b/STL_Extension/include/CGAL/Exception_ostream.h @@ -12,48 +12,71 @@ #ifndef CGAL_EXCEPTION_OSTREAM_H #define CGAL_EXCEPTION_OSTREAM_H +#include #include #include -#include #include +#include + namespace CGAL { /** * \class Exception_basic_ostream - * \brief A std::basic_ostream that throws an exception with its buffer content when flushed. + * \brief A stream-like object that throws an exception with its buffer content when destroyed. * * Usage: * \code - * CGAL::Exception_basic_ostream os; - * os << "Error: " << value << std::endl; // throws std::runtime_error with the message + * { + * CGAL::Exception_basic_ostream os; + * os << "Error: " << value; + * } // throws std::runtime_error with the message when os goes out of scope * \endcode * - * \tparam CharT Character type (default: char) - * \tparam Traits Character traits (default: std::char_traits) + * \note This class is move-only. + * + * \tparam CharT Character type (default: `char`) + * \tparam Traits Character traits (default: `std::char_traits`) */ template > -class Exception_basic_ostream : public std::basic_ostream { - class buffer_type : public std::basic_stringbuf { - public: - using int_type = typename Traits::int_type; - buffer_type() = default; - // When the buffer is flushed, throw an exception with the buffer content - int sync() override { - std::basic_string msg = this->str(); - this->str({}); // clear buffer - throw std::runtime_error(std::string(msg.begin(), msg.end())); - } - }; - buffer_type buffer_; +class Exception_basic_ostream { + std::basic_ostringstream stream_; public: - Exception_basic_ostream() : std::basic_ostream(&buffer_) {} - // Disallow copy and move - Exception_basic_ostream(const Exception_basic_ostream&) = delete; - Exception_basic_ostream& operator=(const Exception_basic_ostream&) = delete; - Exception_basic_ostream(Exception_basic_ostream&&) = delete; - Exception_basic_ostream& operator=(Exception_basic_ostream&&) = delete; - ~Exception_basic_ostream() override = default; + Exception_basic_ostream() = default; + + // move-only + Exception_basic_ostream(Exception_basic_ostream&&) = default; + Exception_basic_ostream& operator=(Exception_basic_ostream&&) = default; + + ~Exception_basic_ostream() noexcept(false) { + std::basic_string msg = stream_.str(); + if(!msg.empty()) { + throw CGAL::Failure_exception("CGAL", "", __FILE__, __LINE__, std::string(msg.begin(), msg.end())); + } + } + + template + Exception_basic_ostream& operator<<(T&& value) { + stream_ << std::forward(value); + return *this; + } + + // Support for stream manipulators + Exception_basic_ostream& operator<<(std::basic_ostream& (*manip)(std::basic_ostream&)) { + stream_ << manip; + return *this; + } + + Exception_basic_ostream& operator<<(std::basic_ios& (*manip)(std::basic_ios&)) { + stream_ << manip; + return *this; + } + + Exception_basic_ostream& operator<<(std::ios_base& (*manip)(std::ios_base&)) { + stream_ << manip; + return *this; + } + }; /// /relates Exception_basic_ostream @@ -62,8 +85,8 @@ using Exception_ostream = Exception_basic_ostream; /// /relates Exception_basic_ostream using Exception_wostream = Exception_basic_ostream; -inline Exception_ostream& exception_ostream() { - static Exception_ostream os; +inline Exception_ostream exception_ostream() { + Exception_ostream os; return os; } diff --git a/STL_Extension/include/CGAL/bisect_failures.h b/STL_Extension/include/CGAL/bisect_failures.h index 7a9ce1aa835..1d5fb307ff9 100644 --- a/STL_Extension/include/CGAL/bisect_failures.h +++ b/STL_Extension/include/CGAL/bisect_failures.h @@ -21,10 +21,13 @@ #include #include +#include +#include #include #include #include #include +#include namespace CGAL { @@ -170,8 +173,8 @@ int bisect_failures(const InputData& data, if(cgal_exception) { if(initial_cgal_exception && - cgal_exception->message() == initial_cgal_exception->message() && - cgal_exception->expression() == initial_cgal_exception->expression() && + // cgal_exception->message() == initial_cgal_exception->message() && + // cgal_exception->expression() == initial_cgal_exception->expression() && cgal_exception->library() == initial_cgal_exception->library() && cgal_exception->filename() == initial_cgal_exception->filename() && cgal_exception->line_number() == initial_cgal_exception->line_number())