diff --git a/src/stdutils/include/stdutils/chrono.h b/src/stdutils/include/stdutils/chrono.h index 18e95c8..be1f85d 100644 --- a/src/stdutils/include/stdutils/chrono.h +++ b/src/stdutils/include/stdutils/chrono.h @@ -7,6 +7,15 @@ namespace stdutils { namespace chrono { +// For example to measure a duration in milliseconds: +// +// std::chrono::duration duration; +// { +// stdutils::chrono::DurationMeas meas(duration); +// // Do something +// } +// float duration_ms = time.count(); +// template class DurationMeas { diff --git a/src/stdutils/include/stdutils/io.h b/src/stdutils/include/stdutils/io.h index d39651b..c6f97c5 100644 --- a/src/stdutils/include/stdutils/io.h +++ b/src/stdutils/include/stdutils/io.h @@ -31,6 +31,7 @@ struct Severity static constexpr SeverityCode EXCPT = -1; static constexpr SeverityCode ERR = 1; static constexpr SeverityCode WARN = 2; + static constexpr SeverityCode INFO = 3; }; std::string_view str_severity_code(SeverityCode code); @@ -48,6 +49,15 @@ using StreamParser = std::function Ret open_and_parse_file(const std::filesystem::path& filepath, const StreamParser& stream_parser, const stdutils::io::ErrorHandler& err_handler) noexcept; +/** + * Save a file with a writer to std::basic_ostream + */ +template +using StreamWriter = std::function>&, const Obj&, const stdutils::io::ErrorHandler&)>; + +template +void save_file(const std::filesystem::path& filepath, const StreamWriter& stream_writer, const Obj& obj, const stdutils::io::ErrorHandler& err_handler) noexcept; + /** * LineStream: A wrapper around std::getline to count line nb */ @@ -114,12 +124,14 @@ using SkipLineStream = Basic_SkipLineStream; template std::size_t countlines(std::basic_istream>& istream); + // // -// IMPLEMENTATION +// Implementation // // + template Ret open_and_parse_file(const std::filesystem::path& filepath, const StreamParser& stream_parser, const stdutils::io::ErrorHandler& err_handler) noexcept { @@ -141,12 +153,37 @@ Ret open_and_parse_file(const std::filesystem::path& filepath, const StreamParse catch(const std::exception& e) { std::stringstream oss; - oss << "Exception: " << e.what(); + oss << "stdutils::io::open_and_parse_file(): " << e.what(); err_handler(stdutils::io::Severity::EXCPT, oss.str()); } return Ret(); } +template +void save_file(const std::filesystem::path& filepath, const StreamWriter& stream_writer, const Obj& obj, const stdutils::io::ErrorHandler& err_handler) noexcept +{ + try + { + std::basic_ofstream outputstream(filepath); + if (outputstream.is_open()) + { + stream_writer(outputstream, obj, err_handler); + } + else + { + std::stringstream oss; + oss << "Cannot open file " << filepath; + err_handler(stdutils::io::Severity::FATAL, oss.str()); + } + } + catch(const std::exception& e) + { + std::stringstream oss; + oss << "stdutils::io::save_file(): " << e.what(); + err_handler(stdutils::io::Severity::EXCPT, oss.str()); + } +} + template Basic_LineStream::Basic_LineStream(stream_type& source) : m_stream(source) diff --git a/src/stdutils/include/stdutils/span.h b/src/stdutils/include/stdutils/span.h index a1ca3e8..539b28a 100644 --- a/src/stdutils/include/stdutils/span.h +++ b/src/stdutils/include/stdutils/span.h @@ -19,6 +19,12 @@ class span {}; template class span { +public: + using element_type = T; + using value_type = std::remove_cv_t; + using pointer = T*; + using const_pointer = const T*; + public: span(T* ptr, std::size_t size) noexcept : m_ptr(ptr), m_size(size) { assert(m_ptr); } span(const span&) noexcept = default; @@ -51,6 +57,13 @@ template class span> { using this_type = span>; + +public: + using element_type = T; + using value_type = std::remove_cv_t; + using pointer = T*; + using const_pointer = const T*; + public: explicit span(T* ptr) noexcept : m_ptr(ptr) { assert(m_ptr); } span(const this_type&) noexcept = default; diff --git a/src/stdutils/include/stdutils/string.h b/src/stdutils/include/stdutils/string.h index 44911a8..ca2e1d9 100644 --- a/src/stdutils/include/stdutils/string.h +++ b/src/stdutils/include/stdutils/string.h @@ -26,19 +26,22 @@ std::string capitalize(const std::string& in); * out << indent(2); // Output 2 indentations */ template -class BasicIndent : private std::basic_string +class BasicIndent { public: class Multi; - BasicIndent(std::size_t count, CharT ch = ' ') : std::basic_string(count, ch) {} + BasicIndent(std::size_t count, CharT ch = ' ') : m_str(count, ch) {} Multi operator()(std::size_t factor) const { return Multi(*this, factor); } friend std::basic_ostream& operator<<(std::basic_ostream& out, const BasicIndent& indent) { - return out << static_cast&>(indent); + return out << indent.m_str; } + +private: + std::basic_string m_str; }; template diff --git a/src/stdutils/src/io.cpp b/src/stdutils/src/io.cpp index 437bf0f..ee7ac70 100644 --- a/src/stdutils/src/io.cpp +++ b/src/stdutils/src/io.cpp @@ -17,13 +17,17 @@ std::string_view str_severity_code(SeverityCode code) { return "EXCPT"; } + else if (code == Severity::ERR) + { + return "ERROR"; + } else if (code == Severity::WARN) { return "WARNING"; } - else if (code == Severity::ERR) + else if (code == Severity::INFO) { - return "ERROR"; + return "INFO"; } else { diff --git a/src/tests/stdutils/src/test_io.cpp b/src/tests/stdutils/src/test_io.cpp index 324c53f..260889e 100644 --- a/src/tests/stdutils/src/test_io.cpp +++ b/src/tests/stdutils/src/test_io.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2023 Pierre DEJOUE +// This code is distributed under the terms of the MIT License #include #include diff --git a/src/tests/stdutils/src/test_span.cpp b/src/tests/stdutils/src/test_span.cpp index b8e68d9..e3da259 100644 --- a/src/tests/stdutils/src/test_span.cpp +++ b/src/tests/stdutils/src/test_span.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2023 Pierre DEJOUE +// This code is distributed under the terms of the MIT License #include #include