From c09cd7512491cee1e82c1ad8128ce9fd4bc3f79b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 22 Sep 2017 23:32:28 +0200 Subject: Initial modularization with both Clang and VC hacks Note: gave up on VC about half way though. --- libbutl/diagnostics.hxx | 265 ------------------------------------------------ 1 file changed, 265 deletions(-) delete mode 100644 libbutl/diagnostics.hxx (limited to 'libbutl/diagnostics.hxx') diff --git a/libbutl/diagnostics.hxx b/libbutl/diagnostics.hxx deleted file mode 100644 index c1491d6..0000000 --- a/libbutl/diagnostics.hxx +++ /dev/null @@ -1,265 +0,0 @@ -// file : libbutl/diagnostics.hxx -*- C++ -*- -// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#ifndef LIBBUTL_DIAGNOSTICS_HXX -#define LIBBUTL_DIAGNOSTICS_HXX - -#include -#include -#include -#include // move(), forward() -#include // uncaught_exceptions -#include // uncaught_exception(s)() - -#include -#include - -namespace butl -{ - // Diagnostic facility base infrastructure. - // - - // Diagnostics destination stream (std::cerr by default). Note that its - // modification is not MT-safe. Also note that concurrent writing to the - // stream from multiple threads can result in interleaved characters. To - // prevent this an object of diag_stream_lock type (see below) must be - // created prior to write operation. - // - LIBBUTL_SYMEXPORT extern std::ostream* diag_stream; - - // Acquire the diagnostics exclusive access mutex in ctor, release in dtor. - // An object of the type must be created prior to writing to diag_stream (see - // above). - // - struct LIBBUTL_SYMEXPORT diag_stream_lock - { - diag_stream_lock (); - ~diag_stream_lock (); - - // Support for one-liners, for example: - // - // diag_stream_lock () << "Hello, World!" << endl; - // - template - std::ostream& - operator<< (const T& x) const - { - return *diag_stream << x; - } - }; - - // Progress line facility. - // - // The idea is to keep a progress line at the bottom of the terminal with - // other output scrolling above it. For a non-terminal STDERR the progress - // line is printed as a regular one terminated with the newline character. - // The printing of the progress line is integrated into diag_stream_lock and - // diag_progress_lock. To print or update the progress acquire - // diag_progress_lock and update the diag_progress string. To remove the - // progress line, set this string to empty. For better readability start the - // progress line with a space (which is where the cursor will be parked). - // Should only be used if diag_stream points to std::cerr. - // - // Note that child processes writing to the same stream may not completely - // overwrite the progress line so in this case it makes sense to keep the - // line as short as possible. - // - // To restore the progress line being overwritten by an independent writer - // (such as a child process), create and destroy the diag_progress_lock. - // - LIBBUTL_SYMEXPORT extern std::string diag_progress; - - struct LIBBUTL_SYMEXPORT diag_progress_lock - { - diag_progress_lock (); - ~diag_progress_lock (); - }; - - // - // - struct diag_record; - template struct diag_prologue; - template struct diag_mark; - - using diag_epilogue = void (const diag_record&); - - struct LIBBUTL_SYMEXPORT diag_record - { - template - const diag_record& - operator<< (const T& x) const - { - os << x; - return *this; - } - - diag_record () - : -#ifdef __cpp_lib_uncaught_exceptions - uncaught_ (std::uncaught_exceptions ()), -#endif - empty_ (true), - epilogue_ (nullptr) {} - - template - explicit - diag_record (const diag_prologue& p): diag_record () { *this << p;} - - template - explicit - diag_record (const diag_mark& m): diag_record () { *this << m;} - - ~diag_record () noexcept (false); - - bool - empty () const {return empty_;} - - bool - full () const {return !empty_;} - - void - flush () const; - - void - append (const char* indent, diag_epilogue* e) const - { - // Ignore subsequent epilogues (e.g., from nested marks, etc). - // - if (empty_) - { - epilogue_ = e; - empty_ = false; - } - else if (indent != nullptr) - os << indent; - } - - // Move constructible-only type. - // - // Older versions of libstdc++ don't have the ostringstream move support - // and accuratly detecting its version is non-trivial. So we always use - // the pessimized implementation with libstdc++. Luckily, GCC doesn't seem - // to be needing move due to copy/move elision. - // -#ifdef __GLIBCXX__ - diag_record (diag_record&&); -#else - diag_record (diag_record&& r) - : -#ifdef __cpp_lib_uncaught_exceptions - uncaught_ (r.uncaught_), -#endif - empty_ (r.empty_), - epilogue_ (r.epilogue_), - os (std::move (r.os)) - { - if (!empty_) - { - r.empty_ = true; - r.epilogue_ = nullptr; - } - } -#endif - - diag_record& operator= (diag_record&&) = delete; - - diag_record (const diag_record&) = delete; - diag_record& operator= (const diag_record&) = delete; - - protected: -#ifdef __cpp_lib_uncaught_exceptions - const int uncaught_; -#endif - mutable bool empty_; - mutable diag_epilogue* epilogue_; - - public: - mutable std::ostringstream os; - }; - - template - struct diag_prologue: B - { - const char* indent; - diag_epilogue* epilogue; - - diag_prologue (const char* i = "\n ", diag_epilogue* e = nullptr) - : B (), indent (i), epilogue (e) {} - - template - diag_prologue (A&&... a) - : B (std::forward (a)...), indent ("\n "), epilogue (nullptr) {} - - template - diag_prologue (diag_epilogue* e, A&&... a) - : B (std::forward (a)...), indent ("\n "), epilogue (e) {} - - template - diag_prologue (const char* i, diag_epilogue* e, A&&... a) - : B (std::forward (a)...), indent (i), epilogue (e) {} - - template - diag_record - operator<< (const T& x) const - { - diag_record r; - r.append (indent, epilogue); - B::operator() (r); - r << x; - return r; - } - - friend const diag_record& - operator<< (const diag_record& r, const diag_prologue& p) - { - r.append (p.indent, p.epilogue); - p (r); - return r; - } - }; - - template - struct diag_mark: B - { - diag_mark (): B () {} - - template - diag_mark (A&&... a): B (std::forward (a)...) {} - - template - diag_record - operator<< (const T& x) const - { - return B::operator() () << x; - } - - friend const diag_record& - operator<< (const diag_record& r, const diag_mark& m) - { - return r << m (); - } - }; - - template - struct diag_noreturn_end: B - { - diag_noreturn_end (): B () {} - - template - diag_noreturn_end (A&&... a): B (std::forward (a)...) {} - - [[noreturn]] friend void - operator<< (const diag_record& r, const diag_noreturn_end& e) - { - // We said that we never return which means this end mark cannot be used - // to "maybe not return". And not returning without any diagnostics is - // probably a mistake. - // - assert (r.full ()); - e.B::operator() (r); - } - }; -} - -#endif // LIBBUTL_DIAGNOSTICS_HXX -- cgit v1.1