10#ifndef HISTORY_FUNC_HPP
11#define HISTORY_FUNC_HPP
13#include "../core/bitmath_func.hpp"
14#include "../core/math_func.hpp"
15#include "../timer/timer_game_economy.h"
43 if (hr.hr !=
nullptr)
RotateHistory(history, valid_history, *hr.hr, cur_month);
46 std::move_backward(std::next(std::begin(history), hr.
first), std::next(std::begin(history), hr.
last - 1), std::next(std::begin(history), hr.
last));
52 auto first = std::next(std::begin(history), hr.
first - hr.
division);
53 auto last = std::next(first, hr.
division);
54 history[hr.
first] = SumHistory<T>(std::span{first, last});
63template <
typename T,
typename Taccrued>
85 if (hr.hr ==
nullptr) {
87 uint slot = hr.
first + age;
88 result = history[slot];
89 return HasBit(valid_history, slot);
93 bool is_valid =
false;
94 std::array<T, HISTORY_MAX_DIVISION> tmp_result;
96 for (
auto i = start; i != start + hr.
division; ++i) {
97 is_valid |=
GetHistory(history, valid_history, *hr.hr, i, tmp_result[i - start]);
99 result = SumHistory<T>(std::span{std::begin(tmp_result), hr.
division});
104 result = history[slot];
105 return HasBit(valid_history, slot);
118template <uint N,
typename T,
typename... Tfillers>
122 for (uint i = 0; i != N; ++i) {
123 if (
GetHistory(history, valid_history, hr, N - i - 1, result)) {
124 (fillers.Fill(i, result), ...);
126 (fillers.MakeInvalid(i), ...);
138template <uint N,
typename T,
typename... Tfillers>
141 if (history !=
nullptr) {
142 FillFromHistory<N>(*history, valid_history, hr, std::forward<Tfillers &&>(fillers)...);
147 for (uint i = 0; i != N; ++i) {
149 (fillers.MakeZero(i), ...);
151 (fillers.MakeInvalid(i), ...);
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
static Month month
Current month (0..11).
static uint days_since_last_month
Number of days that have elapsed since the last month.
void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month)
Update mask of valid records for a historical data.
T GetAndResetAccumulatedAverage(Taccrued &total)
Get an average value for the previous month, as reset for the next month.
bool GetHistory(const HistoryData< T > &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint age, T &result)
Get historical data.
void RotateHistory(HistoryData< T > &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint cur_month)
Rotate historical data.
T SumHistory(typename std::span< const T > history)
Sum history data elements.
bool IsValidHistory(ValidHistoryMask valid_history, const HistoryRange &hr, uint age)
Test if history data is valid, without extracting data.
void FillFromHistory(const HistoryData< T > &history, ValidHistoryMask valid_history, const HistoryRange &hr, Tfillers &&... fillers)
Fill some data with historical data.
Types for storing historical data.
std::array< T, HISTORY_RECORDS > HistoryData
Container type for storing history data.
uint64_t ValidHistoryMask
Mask of valid history records.
const uint8_t last
Index of last element in history data.
const uint8_t total_division
Number of divisions of the initial history range.
const uint8_t division
Number of divisions of the previous history range.
const uint8_t first
Index of first element in history data.
const uint8_t periods
Number of periods for this range.