Mountain  1.0.0
Simple C++ 2D Game Framework
time_span.hpp
1 #pragma once
2 
3 #include <format>
4 #include <sstream>
5 
6 #include "Mountain/core.hpp"
7 
8 namespace Mountain
9 {
13  struct MOUNTAIN_API TimeSpan
14  {
16  static constexpr int64_t NanosecondsPerTick = 100;
18  static constexpr int64_t TicksPerMicrosecond = 10;
20  static constexpr int64_t TicksPerMillisecond = TicksPerMicrosecond * 1000;
22  static constexpr int64_t TicksPerSecond = TicksPerMillisecond * 1000;
24  static constexpr int64_t TicksPerMinute = TicksPerSecond * 60;
26  static constexpr int64_t TicksPerHour = TicksPerMinute * 60;
28  static constexpr int64_t TicksPerDay = TicksPerHour * 24;
29 
30  [[nodiscard]]
31  static constexpr TimeSpan Zero();
32  [[nodiscard]]
33  static constexpr TimeSpan MaxValue();
34  [[nodiscard]]
35  static constexpr TimeSpan MinValue();
36 
37  [[nodiscard]]
38  static TimeSpan FromDays(double_t days);
39  [[nodiscard]]
40  static TimeSpan FromHours(double_t hours);
41  [[nodiscard]]
42  static TimeSpan FromMinutes(double_t minutes);
43  [[nodiscard]]
44  static TimeSpan FromSeconds(double_t seconds);
45  [[nodiscard]]
46  static TimeSpan FromMilliseconds(double_t milliseconds);
47  [[nodiscard]]
48  static TimeSpan FromMicroseconds(double_t microseconds);
49  [[nodiscard]]
50  static TimeSpan FromTicks(int64_t ticks);
51 
52  [[nodiscard]]
53  explicit constexpr TimeSpan(int64_t ticks);
54  [[nodiscard]]
55  constexpr TimeSpan(int32_t hours, int32_t minutes, int32_t seconds);
56  [[nodiscard]]
57  constexpr TimeSpan(int32_t days, int32_t hours, int32_t minutes, int32_t seconds, int32_t milliseconds = 0, int32_t microseconds = 0);
58 
59  GETTER(int64_t, Ticks, m_Ticks)
60 
61  [[nodiscard]]
62  int32_t GetDays() const;
63  [[nodiscard]]
64  int32_t GetHours() const;
65  [[nodiscard]]
66  int32_t GetMinutes() const;
67  [[nodiscard]]
68  int32_t GetSeconds() const;
69  [[nodiscard]]
70  int32_t GetMilliseconds() const;
71  [[nodiscard]]
72  int32_t GetMicroseconds() const;
73  [[nodiscard]]
74  int32_t GetNanoseconds() const;
75 
76  [[nodiscard]]
77  double_t GetTotalDays() const;
78  [[nodiscard]]
79  double_t GetTotalHours() const;
80  [[nodiscard]]
81  double_t GetTotalMinutes() const;
82  [[nodiscard]]
83  double_t GetTotalSeconds() const;
84  [[nodiscard]]
85  double_t GetTotalMilliseconds() const;
86  [[nodiscard]]
87  double_t GetTotalMicroseconds() const;
88  [[nodiscard]]
89  double_t GetTotalNanoseconds() const;
90 
91  [[nodiscard]]
92  TimeSpan Duration() const;
93 
94  [[nodiscard]]
95  friend auto operator<=>(TimeSpan, TimeSpan) = default;
96 
97  friend TimeSpan operator+(TimeSpan a, TimeSpan b);
98  friend TimeSpan operator-(TimeSpan v);
99  friend TimeSpan operator-(TimeSpan a, TimeSpan b);
100  friend TimeSpan operator*(TimeSpan v, double_t factor);
101  friend TimeSpan operator*(double_t factor, TimeSpan v);
102  friend TimeSpan operator/(TimeSpan v, double_t divisor);
103  friend double_t operator/(TimeSpan a, TimeSpan b);
104 
105  friend TimeSpan& operator+=(TimeSpan& a, TimeSpan b);
106  friend TimeSpan& operator-=(TimeSpan& a, TimeSpan b);
107  friend TimeSpan& operator*=(TimeSpan& v, double_t factor);
108  friend TimeSpan& operator/=(TimeSpan& v, double_t divisor);
109 
110  friend std::ostream& operator<<(std::ostream& out, const TimeSpan& timeSpan);
111 
112  private:
113  static constexpr int64_t MaxSeconds = std::numeric_limits<int64_t>::max() / TicksPerSecond;
114  static constexpr int64_t MinSeconds = std::numeric_limits<int64_t>::min() / TicksPerSecond;
115 
116  static constexpr int64_t MaxMilliSeconds = std::numeric_limits<int64_t>::max() / TicksPerMillisecond;
117  static constexpr int64_t MinMilliSeconds = std::numeric_limits<int64_t>::min() / TicksPerMillisecond;
118 
119  static constexpr int64_t MaxMicroSeconds = std::numeric_limits<int64_t>::max() / TicksPerMicrosecond;
120  static constexpr int64_t MinMicroSeconds = std::numeric_limits<int64_t>::min() / TicksPerMicrosecond;
121 
122  static constexpr int64_t TicksPerTenthSecond = TicksPerMillisecond * 100;
123 
124  [[nodiscard]]
125  static TimeSpan Interval(double_t ticks, double_t scale);
126  [[nodiscard]]
127  static TimeSpan IntervalFromDoubleTicks(double_t ticks);
128 
129  int64_t m_Ticks;
130  };
131 }
132 
134 template <>
135 struct std::hash<Mountain::TimeSpan>
136 {
137  size_t operator()(const Mountain::TimeSpan& timeSpan) const noexcept
138  {
139  return timeSpan.GetTicks() ^ (timeSpan.GetTicks() >> 32);
140  }
141 };
142 
144 template <>
145 struct std::formatter<Mountain::TimeSpan>
146 {
148  template <class ParseContext>
149  constexpr typename ParseContext::iterator parse(ParseContext& ctx)
150  {
151  auto it = ctx.begin();
152  if (it == ctx.end())
153  return it;
154 
155  if (*it != '}')
156  throw std::format_error("Invalid format args for Mountain::TimeSpan");
157 
158  return it;
159  }
160 
161  // ReSharper disable once CppMemberFunctionMayBeStatic
163  template <class FormatContext>
164  typename FormatContext::iterator format(const Mountain::TimeSpan& timeSpan, FormatContext& ctx) const
165  {
166  std::ostringstream out;
167 
168  const bool_t daysCheck = timeSpan.GetDays() > 0;
169  const bool_t hoursCheck = timeSpan.GetHours() > 0;
170  const bool_t minutesCheck = timeSpan.GetMinutes() > 0;
171 
172  if (daysCheck)
173  out << timeSpan.GetDays() << '.';
174 
175  if (daysCheck || hoursCheck)
176  out << std::format("{:2}:", timeSpan.GetHours());
177 
178  if (daysCheck || hoursCheck || minutesCheck)
179  out << std::format("{:2}:", timeSpan.GetMinutes());
180 
181  out << timeSpan.GetSeconds();
182 
183  const bool_t millisecondsCheck = timeSpan.GetMilliseconds() > 0;
184  const bool_t microsecondsCheck = timeSpan.GetMicroseconds() > 0;
185  const bool_t nanosecondsCheck = timeSpan.GetNanoseconds() > 0;
186 
187  if (nanosecondsCheck || microsecondsCheck)
188  out << std::format(".{:03}", timeSpan.GetMilliseconds());
189  else if (millisecondsCheck)
190  out << std::format(".{}", timeSpan.GetMilliseconds());
191 
192  if (nanosecondsCheck || microsecondsCheck)
193  out << std::format("{:03}", timeSpan.GetMicroseconds());
194  else if (microsecondsCheck)
195  out << std::format(".{}", timeSpan.GetMilliseconds());
196 
197  if (nanosecondsCheck)
198  out << std::format("{}", timeSpan.GetNanoseconds());
199 
200  return std::ranges::copy(std::move(out).str(), ctx.out()).out;
201  }
202 };
203 
204 #include "Mountain/utils/time_span.inl"
constexpr Matrix & operator*=(Matrix &m, const float_t scalar) noexcept
constexpr Color operator*(const Color &c1, const Color &c2)
Multiplies 2 Color.
constexpr Matrix operator-(const Matrix &matrix) noexcept
constexpr Color operator+(const Color &c1, const Color &c2)
Adds 2 Color, caps at 1.f.
constexpr Matrix & operator-=(Matrix &m1, const Matrix &m2) noexcept
constexpr ParseContext::iterator parse(ParseContext &ctx)
Parses the input formatting options.
Definition: time_span.hpp:149
C++ reimplementation of the .NET TimeSpan struct.
Definition: time_span.hpp:13
constexpr Quaternion operator/(const Quaternion &v, const float_t factor) noexcept
FormatContext::iterator format(const Mountain::TimeSpan &timeSpan, FormatContext &ctx) const
Formats a string using the given instance of Mountain::TimeSpan, according to the given options in th...
Definition: time_span.hpp:164
constexpr Quaternion & operator/=(Quaternion &q, const float_t factor) noexcept
constexpr Matrix & operator+=(Matrix &m1, const Matrix &m2) noexcept
constexpr float_t Zero
MATH_TOOLBOX std::ostream & operator<<(std::ostream &out, const Matrix &m)
Contains all declarations of the Mountain Framework.
Definition: audio.hpp:22