diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/openvic/Date.cpp | 32 | ||||
-rw-r--r-- | src/openvic/Date.hpp | 7 | ||||
-rw-r--r-- | src/openvic/utility/Logger.cpp | 6 | ||||
-rw-r--r-- | src/openvic/utility/Logger.hpp | 23 |
4 files changed, 52 insertions, 16 deletions
diff --git a/src/openvic/Date.cpp b/src/openvic/Date.cpp index f7bf9a3..109b82d 100644 --- a/src/openvic/Date.cpp +++ b/src/openvic/Date.cpp @@ -1,6 +1,7 @@ #include "Date.hpp" #include <algorithm> +#include <cassert> #include <cctype> #include "utility/Logger.hpp" @@ -67,6 +68,30 @@ Timespan Date::_dateToTimespan(year_t year, month_t month, day_t day) { return year * DAYS_IN_YEAR + DAYS_UP_TO_MONTH[month - 1] + day - 1; } +Timespan::day_t const* Date::DAYS_UP_TO_MONTH = generate_days_up_to_month(); + +Timespan::day_t const* Date::generate_days_up_to_month() { + static Timespan::day_t days_up_to_month[MONTHS_IN_YEAR]; + Timespan::day_t days = 0; + for (int month = 0; month < MONTHS_IN_YEAR; + days_up_to_month[month] = days, days += DAYS_IN_MONTH[month++]); + assert(days == DAYS_IN_YEAR); + return days_up_to_month; +} + +Date::month_t const* Date::MONTH_FROM_DAY_IN_YEAR = generate_month_from_day_in_year(); + +Date::month_t const* Date::generate_month_from_day_in_year() { + static month_t month_from_day_in_year[DAYS_IN_YEAR]; + Timespan::day_t days_left = 0; + for (int day = 0, month = 0; day < DAYS_IN_YEAR; + days_left = (days_left > 0 ? days_left : DAYS_IN_MONTH[month++]) - 1, + month_from_day_in_year[day++] = month); + assert(days_left == 0); + assert(month_from_day_in_year[DAYS_IN_YEAR - 1] == MONTHS_IN_YEAR); + return month_from_day_in_year; +} + Date::Date(Timespan total_days) : timespan { total_days } { if (timespan < 0) { Logger::error("Invalid timespan for date: ", timespan, " (cannot be negative)"); @@ -81,12 +106,11 @@ Date::year_t Date::getYear() const { } Date::month_t Date::getMonth() const { - return ((static_cast<Timespan::day_t>(timespan) % DAYS_IN_YEAR) / 32) + 1; + return MONTH_FROM_DAY_IN_YEAR[static_cast<Timespan::day_t>(timespan) % DAYS_IN_YEAR]; } Date::day_t Date::getDay() const { - const Timespan::day_t days_in_year = static_cast<Timespan::day_t>(timespan) % DAYS_IN_YEAR; - return days_in_year - DAYS_UP_TO_MONTH[days_in_year / 32] + 1; + return (static_cast<Timespan::day_t>(timespan) % DAYS_IN_YEAR) - DAYS_UP_TO_MONTH[getMonth() - 1] + 1; } bool Date::operator<(Date other) const { return timespan < other.timespan; }; @@ -128,7 +152,7 @@ Date::operator std::string() const { } std::ostream& OpenVic::operator<<(std::ostream& out, Date const& date) { - return out << (int)date.getYear() << '.' << (int)date.getMonth() << '.' << (int)date.getDay(); + return out << static_cast<int>(date.getYear()) << '.' << static_cast<int>(date.getMonth()) << '.' << static_cast<int>(date.getDay()); } // Parsed from string of the form YYYY.MM.DD diff --git a/src/openvic/Date.hpp b/src/openvic/Date.hpp index 151b4e5..f616e3b 100644 --- a/src/openvic/Date.hpp +++ b/src/openvic/Date.hpp @@ -46,14 +46,17 @@ namespace OpenVic { static constexpr Timespan::day_t MONTHS_IN_YEAR = 12; static constexpr Timespan::day_t DAYS_IN_YEAR = 365; - static constexpr Timespan::day_t DAYS_IN_MONTH[MONTHS_IN_YEAR] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - static constexpr Timespan::day_t DAYS_UP_TO_MONTH[MONTHS_IN_YEAR] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + static constexpr Timespan::day_t DAYS_IN_MONTH[MONTHS_IN_YEAR] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + static Timespan::day_t const* DAYS_UP_TO_MONTH; + static month_t const* MONTH_FROM_DAY_IN_YEAR; private: // Number of days since Jan 1st, Year 0 Timespan timespan; static Timespan _dateToTimespan(year_t year, month_t month, day_t day); + static Timespan::day_t const* generate_days_up_to_month(); + static month_t const* generate_month_from_day_in_year(); public: // The Timespan is considered to be the number of days since Jan 1st, Year 0 diff --git a/src/openvic/utility/Logger.cpp b/src/openvic/utility/Logger.cpp index fe97473..bf9a67c 100644 --- a/src/openvic/utility/Logger.cpp +++ b/src/openvic/utility/Logger.cpp @@ -4,8 +4,10 @@ using namespace OpenVic; -Logger::log_func_t Logger::info_func = [](std::string&& str) { std::cout << str; }; -Logger::log_func_t Logger::error_func = [](std::string&& str) { std::cerr << str; }; +Logger::log_func_t Logger::info_func {}; +Logger::log_queue_t Logger::info_queue {}; +Logger::log_func_t Logger::error_func {}; +Logger::log_queue_t Logger::error_queue {}; char const* Logger::get_filename(char const* filepath) { if (filepath == nullptr) return nullptr; diff --git a/src/openvic/utility/Logger.hpp b/src/openvic/utility/Logger.hpp index ac82445..417aba7 100644 --- a/src/openvic/utility/Logger.hpp +++ b/src/openvic/utility/Logger.hpp @@ -1,6 +1,7 @@ #pragma once #include <functional> +#include <queue> #include <sstream> #ifdef __cpp_lib_source_location #include <source_location> @@ -33,6 +34,7 @@ namespace OpenVic { class Logger { using log_func_t = std::function<void(std::string&&)>; + using log_queue_t = std::queue<std::string>; #ifdef __cpp_lib_source_location using source_location = std::source_location; @@ -44,14 +46,18 @@ namespace OpenVic { template<typename... Ts> struct log { - log(log_func_t log_func, Ts&&... ts, source_location const& location) { + log(log_func_t log_func, log_queue_t& log_queue, Ts&&... ts, source_location const& location) { + std::stringstream stream; + stream << "\n" << get_filename(location.file_name()) << "(" + << location.line() << ") `" << location.function_name() << "`: "; + ((stream << std::forward<Ts>(ts)), ...); + stream << std::endl; + log_queue.push(stream.str()); if (log_func) { - std::stringstream stream; - stream << "\n" << get_filename(location.file_name()) << "(" - << location.line() << ") `" << location.function_name() << "`: "; - ((stream << std::forward<Ts>(ts)), ...); - stream << std::endl; - log_func(stream.str()); + do { + log_func(std::move(log_queue.front())); + log_queue.pop(); + } while (!log_queue.empty()); } } }; @@ -59,6 +65,7 @@ namespace OpenVic { #define LOG_FUNC(name) \ private: \ static log_func_t name##_func; \ + static log_queue_t name##_queue; \ public: \ static void set_##name##_func(log_func_t log_func) { \ name##_func = log_func; \ @@ -66,7 +73,7 @@ namespace OpenVic { template <typename... Ts> \ struct name { \ name(Ts&&... ts, source_location const& location = source_location::current()) { \ - log<Ts...>{ name##_func, std::forward<Ts>(ts)..., location }; \ + log<Ts...>{ name##_func, name##_queue, std::forward<Ts>(ts)..., location }; \ } \ }; \ template <typename... Ts> \ |