Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/openvic-simulation/InstanceManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "openvic-simulation/console/ConsoleInstance.hpp"
#include "openvic-simulation/core/memory/Vector.hpp"
#include "openvic-simulation/core/object/Date.hpp"
#include "openvic-simulation/country/CountryInstanceDeps.hpp"
#include "openvic-simulation/country/CountryInstanceManager.hpp"
#include "openvic-simulation/diplomacy/CountryRelation.hpp"
Expand All @@ -22,7 +23,6 @@
#include "openvic-simulation/politics/PoliticsInstanceManager.hpp"
#include "openvic-simulation/population/PopDeps.hpp"
#include "openvic-simulation/population/PopsAggregateDeps.hpp"
#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/types/FlagStrings.hpp"
#include "openvic-simulation/utility/ThreadPool.hpp"

Expand Down
2 changes: 1 addition & 1 deletion src/openvic-simulation/console/ConsoleInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "openvic-simulation/core/error/ErrorMacros.hpp"
#include "openvic-simulation/core/memory/String.hpp"
#include "openvic-simulation/core/memory/Vector.hpp"
#include "openvic-simulation/core/object/Date.hpp"
#include "openvic-simulation/country/CountryInstance.hpp"
#include "openvic-simulation/DefinitionManager.hpp"
#include "openvic-simulation/InstanceManager.hpp"
Expand All @@ -22,7 +23,6 @@
#include "openvic-simulation/research/Invention.hpp"
#include "openvic-simulation/research/Technology.hpp"
#include "openvic-simulation/types/Colour.hpp"
#include "openvic-simulation/types/Date.hpp"

using namespace OpenVic;
using namespace std::string_view_literals;
Expand Down
2 changes: 1 addition & 1 deletion src/openvic-simulation/console/ConsoleInstance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

#include "openvic-simulation/core/memory/Formatting.hpp"
#include "openvic-simulation/core/memory/String.hpp"
#include "openvic-simulation/core/object/Date.hpp"
#include "openvic-simulation/types/Colour.hpp"
#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/types/OrderedContainers.hpp"
#include "openvic-simulation/utility/Getters.hpp"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
#include "Date.hpp"

#include <cctype>
#include <array>
#include <charconv>
#include <cmath>
#include <cstdint>
#include <limits>
#include <ostream>
#include <string_view>

#include <fmt/base.h>
#include <fmt/format.h>

#include <range/v3/algorithm/max_element.hpp>

#include "openvic-simulation/core/memory/String.hpp"
#include "openvic-simulation/core/Typedefs.hpp"

using namespace OpenVic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
#include <array>
#include <cassert>
#include <charconv>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <limits>
#include <numeric>
#include <ostream>
#include <system_error>

Expand All @@ -19,121 +18,31 @@
#include "openvic-simulation/core/Hash.hpp"
#include "openvic-simulation/core/memory/Formatting.hpp"
#include "openvic-simulation/core/memory/String.hpp"
#include "openvic-simulation/core/object/Timespan.hpp"
#include "openvic-simulation/core/stl/containers/StackString.hpp"
#include "openvic-simulation/core/string/CharConv.hpp"
#include "openvic-simulation/core/Typedefs.hpp"
#include "openvic-simulation/utility/Getters.hpp"

namespace OpenVic {
// A relative period between points in time, measured in days
struct Timespan {
/* PROPERTY generated getter functions will return timespans by value, rather than const reference. */
using ov_return_by_value = void;

using day_t = int64_t;

private:
day_t days;

public:
OV_ALWAYS_INLINE constexpr Timespan(day_t value = 0) : days { value } {}

OV_ALWAYS_INLINE friend constexpr auto operator<=>(Timespan const&, Timespan const&) = default;
OV_ALWAYS_INLINE friend constexpr bool operator==(Timespan const&, Timespan const&) = default;
OV_SPEED_INLINE constexpr Timespan operator+(Timespan other) const {
return days + other.days;
}
OV_SPEED_INLINE constexpr Timespan operator-(Timespan other) const {
return days - other.days;
}
OV_SPEED_INLINE constexpr Timespan operator*(day_t factor) const {
return days * factor;
}
OV_SPEED_INLINE constexpr Timespan operator/(day_t factor) const {
return days / factor;
}
OV_SPEED_INLINE constexpr Timespan& operator+=(Timespan other) {
days += other.days;
return *this;
}
OV_SPEED_INLINE constexpr Timespan& operator-=(Timespan other) {
days -= other.days;
return *this;
}
OV_SPEED_INLINE constexpr Timespan& operator++() {
days++;
return *this;
}
OV_SPEED_INLINE constexpr Timespan operator++(int) {
Timespan old = *this;
++(*this);
return old;
}
OV_SPEED_INLINE constexpr Timespan& operator--() {
days--;
return *this;
}
OV_SPEED_INLINE constexpr Timespan operator--(int) {
Timespan old = *this;
--(*this);
return old;
}
OV_SPEED_INLINE constexpr Timespan operator-() const {
Timespan ret = *this;
ret.days = -ret.days;
return ret;
}

OV_ALWAYS_INLINE constexpr day_t to_int() const {
return days;
}
OV_ALWAYS_INLINE explicit constexpr operator day_t() const {
return days;
}

inline std::to_chars_result to_chars(char* first, char* last) const {
return std::to_chars(first, last, days);
}

memory::string to_string() const;
explicit operator memory::string() const;

OV_SPEED_INLINE static constexpr Timespan from_years(day_t num);
OV_SPEED_INLINE static constexpr Timespan from_months(day_t num);
OV_SPEED_INLINE static constexpr Timespan from_days(day_t num);
};
std::ostream& operator<<(std::ostream& out, Timespan const& timespan);

// Represents an in-game date
// Note: Current implementation does not account for leap-years
struct Date {
class Date {
public:
/* PROPERTY generated getter functions will return dates by value, rather than const reference. */
using ov_return_by_value = void;

using year_t = int16_t;
using month_t = uint8_t;
using day_t = uint8_t;

static constexpr std::array DAYS_IN_MONTH =
std::to_array<Timespan::day_t>({ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 });
static constexpr auto DAYS_IN_MONTH = Timespan::DAYS_IN_MONTH;

static constexpr Timespan::day_t MONTHS_IN_YEAR = DAYS_IN_MONTH.size();
static constexpr Timespan::day_t MAX_DAYS_IN_MONTH = *ranges::max_element(DAYS_IN_MONTH);
static constexpr auto MONTHS_IN_YEAR = Timespan::MONTHS_IN_YEAR;
static constexpr auto MAX_DAYS_IN_MONTH = *ranges::max_element(DAYS_IN_MONTH);

static constexpr Timespan::day_t DAYS_IN_YEAR = std::accumulate(
DAYS_IN_MONTH.begin(), DAYS_IN_MONTH.end(), Timespan::day_t { 0 }
);
static_assert(DAYS_IN_YEAR == 365);

static constexpr std::array<Timespan::day_t, MONTHS_IN_YEAR> DAYS_UP_TO_MONTH = [] {
std::array<Timespan::day_t, MONTHS_IN_YEAR> days_up_to_month {};
Timespan::day_t days = 0;
for (Timespan::day_t month = 0; month < MONTHS_IN_YEAR; month++) {
days_up_to_month[month] = days;
days += DAYS_IN_MONTH[month];
}
return days_up_to_month;
}();
static constexpr auto DAYS_IN_YEAR = Timespan::DAYS_IN_YEAR;
static constexpr auto DAYS_UP_TO_MONTH = Timespan::DAYS_UP_TO_MONTH;

static constexpr std::array<month_t, DAYS_IN_YEAR> MONTH_FROM_DAY_IN_YEAR = [] {
std::array<month_t, DAYS_IN_YEAR> month_from_day_in_year {};
Expand All @@ -149,8 +58,8 @@ namespace OpenVic {
static constexpr char SEPARATOR_CHARACTER = '.';

static constexpr std::array<std::string_view, MONTHS_IN_YEAR> MONTH_NAMES {
"January", "February", "March", "April", "May", "June", //
"July", "August", "September", "October", "November", "December" //
"January", "February", "March", "April", "May", "June", //
"July", "August", "September", "October", "November", "December" //
};
static constexpr std::string_view INVALID_MONTH_NAME = "Invalid Month";

Expand All @@ -163,22 +72,13 @@ namespace OpenVic {
INITIAL_WEEKDAY_NAME < WEEKDAY_NAMES.size(), "INITIAL_WEEKDAY_NAME must be less than WEEKDAY_NAMES.size()"
);

private:
// Number of days since Jan 1st, Year 0
Timespan PROPERTY(timespan);

OV_SPEED_INLINE static constexpr Timespan _date_to_timespan(year_t year, month_t month, day_t day) {
month = std::clamp<month_t>(month, 1, MONTHS_IN_YEAR);
day = std::clamp<day_t>(day, 1, DAYS_IN_MONTH[month - 1]);
return year * DAYS_IN_YEAR + DAYS_UP_TO_MONTH[month - 1] + day - 1;
}

public:
// The Timespan is considered to be the number of days since Jan 1st, Year 0.
// Negative Timespans indicate dates before Jan 1st, Year 0.
OV_ALWAYS_INLINE constexpr Date(Timespan new_timespan) : timespan { new_timespan } {}
// Year month day specification
OV_ALWAYS_INLINE constexpr Date(year_t year = 0, month_t month = 1, day_t day = 1) : timespan { _date_to_timespan(year, month, day) } {}
OV_ALWAYS_INLINE constexpr Date(year_t year = 0, month_t month = 1, day_t day = 1)
: timespan { _date_to_timespan(year, month, day) } {}

OV_SPEED_INLINE constexpr Timespan::day_t get_day_of_year() const {
Timespan::day_t day_in_year = static_cast<Timespan::day_t>(timespan) % DAYS_IN_YEAR;
Expand All @@ -189,10 +89,9 @@ namespace OpenVic {
}

OV_SPEED_INLINE constexpr year_t get_year() const {
return (timespan >= 0
? static_cast<Timespan::day_t>(timespan)
: static_cast<Timespan::day_t>(timespan) - DAYS_IN_YEAR + 1
) / DAYS_IN_YEAR;
return (timespan >= 0 ? static_cast<Timespan::day_t>(timespan)
: static_cast<Timespan::day_t>(timespan) - DAYS_IN_YEAR + 1) /
DAYS_IN_YEAR;
}
OV_SPEED_INLINE constexpr month_t get_month() const {
return MONTH_FROM_DAY_IN_YEAR[get_day_of_year()];
Expand Down Expand Up @@ -345,7 +244,9 @@ namespace OpenVic {
}

struct stack_string;
OV_SPEED_INLINE constexpr stack_string to_array(bool pad_year = false, bool pad_month = true, bool pad_day = true) const;
OV_SPEED_INLINE constexpr stack_string to_array(
bool pad_year = false, bool pad_month = true, bool pad_day = true //
) const;

struct stack_string final : StackString<
fmt::detail::count_digits(uint64_t(std::numeric_limits<year_t>::max())) +
Expand Down Expand Up @@ -405,8 +306,8 @@ namespace OpenVic {
}

if (OV_unlikely(
year_check > std::numeric_limits<year_t>::max() || year_check < std::numeric_limits<year_t>::min()
)) {
year_check > std::numeric_limits<year_t>::max() || year_check < std::numeric_limits<year_t>::min()
)) {
result.ec = std::errc::value_too_large;
result.ptr = first;
return result;
Expand Down Expand Up @@ -564,7 +465,9 @@ namespace OpenVic {
from_chars->ec == std::errc::value_too_large && from_chars->type == errc_type::day &&
from_chars->ptr == from_chars->type_first,
date,
memory::fmt::format("Day value cannot be larger than {} for {}.", DAYS_IN_MONTH[date.get_month() - 1], date.get_month())
memory::fmt::format(
"Day value cannot be larger than {} for {}.", DAYS_IN_MONTH[date.get_month() - 1], date.get_month()
)
);

return date;
Expand All @@ -586,18 +489,19 @@ namespace OpenVic {
Date date = handle_from_string_log(str, from_chars);
return date;
}

private:
// Number of days since Jan 1st, Year 0
Timespan PROPERTY(timespan);

OV_SPEED_INLINE static constexpr Timespan _date_to_timespan(year_t year, month_t month, day_t day) {
month = std::clamp<month_t>(month, 1, MONTHS_IN_YEAR);
day = std::clamp<day_t>(day, 1, DAYS_IN_MONTH[month - 1]);
return year * DAYS_IN_YEAR + DAYS_UP_TO_MONTH[month - 1] + day - 1;
}
};
std::ostream& operator<<(std::ostream& out, Date date);

OV_SPEED_INLINE constexpr Timespan Timespan::from_years(day_t num) {
return num * Date::DAYS_IN_YEAR;
}
OV_SPEED_INLINE constexpr Timespan Timespan::from_months(day_t num) {
return (num / Date::MONTHS_IN_YEAR) * Date::DAYS_IN_YEAR + Date::DAYS_UP_TO_MONTH[num % Date::MONTHS_IN_YEAR];
}
OV_SPEED_INLINE constexpr Timespan Timespan::from_days(day_t num) {
return num;
}
std::ostream& operator<<(std::ostream& out, Date date);

OV_SPEED_INLINE constexpr Date::stack_string Date::to_array(bool pad_year, bool pad_month, bool pad_day) const {
stack_string str {};
Expand Down
Loading