diff --git a/src/shogun/base/progress.h b/src/shogun/base/progress.h new file mode 100644 index 00000000000..b8261d34d0f --- /dev/null +++ b/src/shogun/base/progress.h @@ -0,0 +1,231 @@ +/* +* Written (W) 2017 Giovanni De Toni +*/ + +#ifndef __SG_PROGRESS_H__ +#define __SG_PROGRESS_H__ + +#include +#include +#include + +#include +#include +#include + +namespace shogun +{ + + /** Possible print modes */ + enum SG_PRG_MODE + { + ASCII, + UTF8 + }; + + /** @class Printer that display the progress bar + * + */ + class ProgressPrinter + { + public: + /** Creates a ProgressPrinter instance given an SGIO object + * + * @param io SGIO object + */ + ProgressPrinter(const SGIO& io) + : m_io(io), m_prefix("PROGRESS: "), m_mode(UTF8) + { + } + ProgressPrinter(const SGIO& io, const std::string& prefix) + : m_io(io), m_prefix(prefix), m_mode(UTF8) + { + } + ProgressPrinter(const SGIO& io, const SG_PRG_MODE mode) + : m_io(io), m_prefix("PROGRESS: "), m_mode(mode) + { + } + ProgressPrinter( + const SGIO& io, const std::string& prefix, const SG_PRG_MODE mode) + : m_io(io), m_prefix(prefix), m_mode(mode) + { + } + ~ProgressPrinter() + { + } + + /** Print the progress bar */ + void print_progress() const + { + m_io.message(MSG_MESSAGEONLY, "", "", -1, "TEST\n"); + } + + /** Print the progress bar end */ + void print_end() const + { + m_io.message(MSG_MESSAGEONLY, "", "", -1, "100\n"); + } + + private: + /** IO object */ + SGIO m_io; + /** Prefix which will be printed before the progress bar */ + std::string m_prefix; + /** Progres bar's char mode */ + SG_PRG_MODE m_mode; + /** Maxmimum value */ + float64_t m_max_value; + /** Minimum value */ + float64_t m_min_value; + /** Last progress time */ + float64_t m_last_progress_time; + /** Progress start time */ + float64_t m_progress_start_time; + /** Last progress */ + float64_t m_last_progress; + }; + + /** @class Helper class to show a progress bar given a range. + * + * @code + * for (auto i : PRange(Range(1, 10), io)) { ... } + * @endcode + */ + template + class PRange + { + public: + /** Create a progress range given an actual range and an io manager + * + * @param range range object + * @param io io manager + */ + PRange(Range range, const SGIO& io) : m_range(range) + { + m_printer = std::make_shared(io); + } + PRange(Range range, const SGIO& io, const SG_PRG_MODE mode) + : m_range(range) + { + m_printer = std::make_shared(io, mode); + } + PRange(Range range, const SGIO& io, const std::string prefix) + : m_range(range) + { + m_printer = std::make_shared(io, prefix); + } + PRange( + Range range, const SGIO& io, const std::string prefix, + const SG_PRG_MODE mode) + : m_range(range) + { + m_printer = std::make_shared(io, prefix, mode); + } + + /** @class Wrapper for Range::Iterator spawned by @ref PRange. */ + class PIterator : public std::iterator + { + public: + PIterator( + typename Range::Iterator value, + std::shared_ptr shrd_ptr) + : m_value(value), m_printer(shrd_ptr) + { + } + PIterator(const PIterator& other) + : m_value(other.m_value), m_printer(other.m_printer) + { + } + PIterator(PIterator&& other) + : m_value(other.m_value), m_printer(other.m_printer) + { + } + PIterator& operator=(const PIterator&) = delete; + PIterator& operator++() + { + // Every time we update the iterator we print + // also the updated progress bar + m_printer->print_progress(); + m_value++; + return *this; + } + PIterator& operator++(int) + { + PIterator tmp(*this, this->m_printer); + ++*this; + return tmp; + } + T operator*() + { + // Since PIterator is a wrapper we have + // to return the actual value of the + // wrapped iterator + return *m_value; + } + bool operator!=(const PIterator& other) + { + if (!(this->m_value != other.m_value)) + m_printer->print_end(); + return this->m_value != other.m_value; + } + bool operator==(const PIterator& other) + { + return this->m_value == other.m_value; + } + + private: + /* The ProgressPrinter object which will be used to show the progress bar*/ + std::shared_ptr m_printer; + /* The wrapped range */ + typename Range::Iterator m_value; + }; + + /** Create the iterator that corresponds to the start of the range*/ + PIterator begin() const + { + return PIterator(m_range.begin(), m_printer); + } + + /** Create the iterator that corresponds to the end of the iterator*/ + PIterator end() const + { + return PIterator(m_range.end(), m_printer); + } + + private: + /** Range we iterate over */ + Range m_range; + /** Observer that will print the actual progress bar */ + std::shared_ptr m_printer; + }; + + /** Creates @ref PRange given a range. + * + * @code + * for (auto i : progress(range(0, 100), io)) { ... } + * @endcode + * + * @param range range used + * @param io SGIO object + */ + template + inline PRange progress(Range range, const SGIO& io) + { + return PRange(range, io); + } + + /** Creates @ref PRange given a range that uses the global SGIO + * + * @code + * for (auto i : progress( range(0, 100) ) ) { ... } + * @endcode + * + * @param range range used + */ + template + inline PRange progress(Range range) + { + return PRange(range, *sg_io); + } +}; +#endif /* __SG_PROGRESS_H__ */ \ No newline at end of file diff --git a/src/shogun/base/range.h b/src/shogun/base/range.h index dfb1e213257..1591dad6330 100644 --- a/src/shogun/base/range.h +++ b/src/shogun/base/range.h @@ -4,7 +4,6 @@ #include #include -#ifdef HAVE_CXX11 namespace shogun { @@ -52,8 +51,8 @@ namespace shogun Iterator& operator++(int) { Iterator tmp(*this); - tmp++; - return tmp; + ++*this; + return tmp; } T operator*() { @@ -124,5 +123,4 @@ namespace shogun } -#endif /* HAVE_CXX */ #endif /* __SG_RANGE_H__ */