1#ifndef MSTL_CORE_TIME_DATETIME_HPP__
2#define MSTL_CORE_TIME_DATETIME_HPP__
3#include "../string/format.hpp"
4#include "../utility/packages.hpp"
8MSTL_INLINE17
static constexpr int32_t MONTH_DAYS[12] = {
9 31, 28, 31, 30, 31, 30,
10 31, 31, 30, 31, 30, 31
14class MSTL_API date :
public iobject<date>,
public icommon<date> {
19 date_type year_ = 1970;
24 constexpr date() noexcept = default;
26 constexpr explicit date(
27 const date_type year, const date_type month, const date_type day) noexcept {
28 if (is_valid(year, month, day)) {
35 constexpr date(
const date& d) noexcept : year_(d.year_), month_(d.month_), day_(d.day_) {}
37 constexpr date& operator =(
const date& d)
noexcept {
44 constexpr date(date&& d) noexcept : year_(d.year_), month_(d.month_), day_(d.day_) {
47 constexpr date& operator =(date&& d)
noexcept {
55 MSTL_CONSTEXPR20 ~date() =
default;
58 MSTL_NODISCARD
constexpr date_type year() const noexcept {
return year_; }
59 MSTL_NODISCARD
constexpr date_type month() const noexcept {
return month_; }
60 MSTL_NODISCARD
constexpr date_type day() const noexcept {
return day_; }
62 static constexpr bool is_valid(date_type y, date_type m, date_type d)
noexcept {
63 if (y < 1900 || y > 9999)
return false;
64 if (m < 1 || m > 12)
return false;
65 return d > 0 && d <= days_of_month(y, m);
69 static constexpr date epoch() noexcept {
73 static constexpr bool is_leap_year(
const date_type year)
noexcept {
74 return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
78 MSTL_NODISCARD
constexpr date_type days_of_week() const noexcept {
81 const date_type d = day_;
86 return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400 + 1) % 7;
89 static constexpr date_type days_of_month(
90 const date_type year,
const date_type month)
noexcept {
91 date_type day =
_CONSTANTS MONTH_DAYS[month - 1];
92 if (month == 2 && is_leap_year(year)) {
98 MSTL_NODISCARD
constexpr date_type days_of_year() const noexcept {
100 for (date_type i = 1; i < month_; ++i) {
101 days += days_of_month(year_, i);
107 constexpr void clear() noexcept {
114 constexpr bool operator ==(
const date& d)
const noexcept {
115 return year_ == d.year_ && month_ == d.month_ && day_ == d.day_;
118 constexpr bool operator <(
const date& d)
const noexcept {
119 if (year_ < d.year_)
return true;
120 if (year_ == d.year_ && month_ < d.month_)
return true;
121 if (year_ == d.year_ && month_ == d.month_ && day_ < d.day_)
return true;
125 constexpr date& operator +=(
const date_type day)
noexcept {
126 if (day == 0)
return *
this;
127 if (day < 0)
return *
this -= -day;
130 const int64_t jd = to_julian_day(year_, month_, day_) + day;
131 *
this = from_julian_day(jd);
135 date_type remaining = day;
136 while (remaining > 0) {
137 const date_type days_in_month = days_of_month(year_, month_);
138 const date_type available = days_in_month - day_ + 1;
140 if (remaining < available) {
145 remaining -= available;
155 constexpr date& operator -=(
const date_type day)
noexcept {
156 if (day < 0)
return *
this += -day;
164 day_ += days_of_month(year_, month_);
169 constexpr date
operator +(
const date_type day)
const noexcept {
175 constexpr date
operator -(
const date_type day)
const noexcept {
181 constexpr date& operator ++() {
185 constexpr date operator ++(
int) {
186 const date ret(*
this);
191 constexpr date_type
operator -(
const date& d)
const noexcept {
192 return static_cast<date_type
>(to_julian_day(year_, month_, day_) - to_julian_day(d.year_, d.month_, d.day_));
195 MSTL_NODISCARD
constexpr size_t to_hash() const noexcept {
196 constexpr hash<date_type> hasher;
197 return hasher(day()) ^ hasher(month()) ^ hasher(year());
200 MSTL_NODISCARD MSTL_CONSTEXPR20
string to_string()
const {
201 return _MSTL format(
"{:04d}-{:02d}-{:02d}", year(), month(), day());
204 MSTL_NODISCARD
constexpr static date parse(
const string_view str) {
205 if (str.size() != 10 || str[4] !=
'-' || str[7] !=
'-') {
206 throw_exception(value_exception(
"Wrong string formation."));
208 const date_type year = integer32::parse(str.substr(0, 4));
209 const date_type month = integer32::parse(str.substr(5, 2));
210 const date_type day = integer32::parse(str.substr(8, 2));
211 return date(year, month, day);
214 constexpr void swap(date& d)
noexcept {
220 static constexpr int64_t to_julian_day(
221 const date_type y,
const date_type m,
const date_type d)
noexcept {
222 const int64_t a = (14 - m) / 12;
223 const int64_t year = y + 4800 - a;
224 const int64_t month = m + 12 * a - 3;
225 return d + (153 * month + 2) / 5 + 365 * year + year / 4 - year / 100 + year / 400 - 32045;
228 static constexpr date from_julian_day(
const int64_t jd)
noexcept {
230 const int64_t b = (4 * a + 3) / 146097;
231 const int64_t c = a - (146097 * b) / 4;
232 const int64_t d = (4 * c + 3) / 1461;
233 const int64_t e = c - (1461 * d) / 4;
234 const int64_t m = (5 * e + 2) / 153;
236 const date_type day =
static_cast<date_type
>(e - (153 * m + 2) / 5 + 1);
237 const date_type month =
static_cast<date_type
>(m + 3 - 12 * (m / 10));
238 const date_type year =
static_cast<date_type
>(100 * b + d - 4800 + (m / 10));
240 return date(year, month, day);
245class MSTL_API time :
public iobject<time>,
public icommon<time> {
250 time_type hours_ = 0;
251 time_type minutes_ = 0;
252 time_type seconds_ = 0;
255 constexpr explicit time(
const time_type h = 0,
256 const time_type m = 0,
const time_type s = 0) noexcept {
257 if (is_valid(h, m, s)) {
264 constexpr time(
const time& t) noexcept : hours_(t.hours_), minutes_(t.minutes_), seconds_(t.seconds_) {}
265 constexpr time& operator =(
const time& t)
noexcept {
267 minutes_ = t.minutes_;
268 seconds_ = t.seconds_;
272 constexpr time(time&& t) noexcept : hours_(t.hours_), minutes_(t.minutes_), seconds_(t.seconds_) {
275 constexpr time& operator =(time&& t)
noexcept {
277 minutes_ = t.minutes_;
278 seconds_ = t.seconds_;
283 MSTL_CONSTEXPR20 ~time() =
default;
286 MSTL_NODISCARD
constexpr time_type
hours() const noexcept {
return hours_; }
287 MSTL_NODISCARD
constexpr time_type
minutes() const noexcept {
return minutes_; }
288 MSTL_NODISCARD
constexpr time_type
seconds() const noexcept {
return seconds_; }
290 static constexpr bool is_valid(time_type h, time_type m, time_type s)
noexcept {
291 return h >= 0 && h < 24 && m >= 0 && m < 60 && s >= 0 && s < 60;
294 constexpr void clear() noexcept {
301 constexpr bool operator ==(
const time& other)
const noexcept {
302 return hours_ == other.hours_ && minutes_ == other.minutes_ && seconds_ == other.seconds_;
305 constexpr bool operator <(
const time& other)
const noexcept {
306 if (hours_ < other.hours_)
return true;
307 if (hours_ == other.hours_) {
308 if (minutes_ < other.minutes_)
return true;
309 if (minutes_ == other.minutes_ && seconds_ < other.seconds_)
return true;
315 constexpr time& operator +=(
const time_type
seconds) {
319 const time_type extra_min = seconds_ / 60;
322 minutes_ += extra_min;
323 const time_type extra_hour = minutes_ / 60;
326 hours_ += extra_hour;
332 constexpr time& operator -=(
const time_type
seconds)
noexcept {
337 if (total_sec < 0) total_sec += 86400;
339 hours_ =
static_cast<time_type
>(total_sec / 3600);
340 minutes_ =
static_cast<time_type
>((total_sec % 3600) / 60);
341 seconds_ =
static_cast<time_type
>(total_sec % 60);
357 constexpr time& operator ++() {
return *
this += 1; }
358 constexpr time operator ++(
int) {
359 const time ret(*
this);
363 constexpr time& operator --() {
return *
this -= 1; }
364 constexpr time operator --(
int) {
365 const time ret(*
this);
370 constexpr time_type
operator -(
const time& other)
const noexcept {
371 time_type sec_diff = (hours_ - other.hours_) * 3600;
372 sec_diff += (minutes_ - other.minutes_) * 60;
373 sec_diff += (seconds_ - other.seconds_);
378 MSTL_NODISCARD
constexpr time_type to_seconds() const noexcept {
379 return hours_ * 3600 + minutes_ * 60 + seconds_;
382 MSTL_NODISCARD
constexpr size_t to_hash() const noexcept {
383 constexpr hash<time_type> hasher;
387 MSTL_NODISCARD MSTL_CONSTEXPR20
string to_string()
const {
391 MSTL_NODISCARD
static constexpr time parse(
const string_view str) {
392 if (str.size() != 8 || str[2] !=
':' || str[5] !=
':') {
393 throw_exception(value_exception(
"Wrong string formation."));
395 const time_type h = integer32::parse(str.substr(0, 2));
396 const time_type m = integer32::parse(str.substr(3, 2));
397 const time_type s = integer32::parse(str.substr(6, 2));
398 return time(h, m, s);
401 constexpr void swap(time& other)
noexcept {
411MSTL_INLINE17
constexpr const char*
const WEEKDAYS_STRING[] =
412 {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"};
414MSTL_INLINE17
constexpr const char*
const MONTHS_STRING[] =
415 {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"};
419constexpr int months_to_int(
const string_view sv) {
420 for (
int i = 0; i < 12; ++i) {
421 if (sv ==
_CONSTANTS MONTHS_STRING[i])
return i + 1;
427class MSTL_API datetime :
public iobject<datetime>,
public icommon<datetime> {
429 using date_type =
_MSTL date::date_type;
430 using time_type =
_MSTL time::time_type;
436 bool has_timezone_ =
false;
439 constexpr datetime() noexcept = default;
441 constexpr datetime(const datetime& dt) noexcept
442 : date_(dt.date_), time_(dt.time_),
443 offset_seconds_(dt.offset_seconds_), has_timezone_(dt.has_timezone_) {}
445 constexpr datetime& operator =(
const datetime& dt)
noexcept {
448 offset_seconds_ = dt.offset_seconds_;
449 has_timezone_ = dt.has_timezone_;
453 constexpr datetime(datetime&& dt) noexcept
454 : date_(dt.date_), time_(dt.time_), offset_seconds_(dt.offset_seconds_),
455 has_timezone_(dt.has_timezone_) {
459 constexpr datetime& operator =(datetime&& dt)
noexcept {
462 offset_seconds_ = dt.offset_seconds_;
463 has_timezone_ = dt.has_timezone_;
468 constexpr explicit datetime(
const date_type year,
const date_type month,
const date_type day,
469 const time_type hour,
const time_type minute,
const time_type second) noexcept
470 : date_(year, month, day), time_(hour, minute, second) {}
472 constexpr explicit datetime(
const date_type year,
const date_type month,
const date_type day,
473 const time_type hour,
const time_type minute,
const time_type second,
const int64_t offset) noexcept
474 : date_(year, month, day), time_(hour, minute, second), offset_seconds_(offset), has_timezone_(
true) {}
476 constexpr explicit datetime(
const _MSTL date& d,
const _MSTL time& t) noexcept
477 : date_(d), time_(t) {}
479 constexpr explicit datetime(
const _MSTL date& d,
const _MSTL time& t,
const int64_t offset) noexcept
480 : date_(d), time_(t), offset_seconds_(offset), has_timezone_(
true) {}
482 constexpr explicit datetime(
_MSTL date&& d,
_MSTL time&& t) noexcept
483 : date_(d), time_(t) {
488 constexpr explicit datetime(
_MSTL date&& d,
_MSTL time&& t,
const int64_t offset) noexcept
489 : date_(d), time_(t), offset_seconds_(offset), has_timezone_(
true) {
494 constexpr explicit datetime(
const _MSTL date& d) noexcept : date_(d) {}
496 constexpr datetime& operator =(
const _MSTL date& d)
noexcept {
501 constexpr explicit datetime(
_MSTL date&& d) noexcept : date_(d) {
505 constexpr datetime& operator =(
_MSTL date&& d)
noexcept {
511 constexpr explicit datetime(
const _MSTL time& t) noexcept : time_(t) {}
513 constexpr datetime& operator =(
const _MSTL time& t)
noexcept {
518 constexpr explicit datetime(
_MSTL time&& t) noexcept : time_(t) {
522 constexpr datetime& operator =(
_MSTL time&& t)
noexcept {
528 MSTL_CONSTEXPR20 ~datetime() =
default;
531 MSTL_NODISCARD
constexpr const _MSTL date& date() const noexcept {
return date_; }
532 MSTL_NODISCARD
constexpr const _MSTL time& time() const noexcept {
return time_; }
534 MSTL_NODISCARD
constexpr time_type
hours() const noexcept {
return time_.hours(); }
535 MSTL_NODISCARD
constexpr time_type
minutes() const noexcept {
return time_.minutes(); }
536 MSTL_NODISCARD
constexpr time_type
seconds() const noexcept {
return time_.seconds(); }
537 MSTL_NODISCARD
constexpr date_type year() const noexcept {
return date_.year(); }
538 MSTL_NODISCARD
constexpr date_type month() const noexcept {
return date_.month(); }
539 MSTL_NODISCARD
constexpr date_type day() const noexcept {
return date_.day(); }
541 MSTL_NODISCARD
constexpr bool has_timezone() const noexcept {
return has_timezone_; }
542 MSTL_NODISCARD
constexpr int64_t offset_seconds() const noexcept {
return offset_seconds_; }
544 MSTL_NODISCARD
static constexpr datetime epoch() noexcept {
return datetime{}; }
545 MSTL_NODISCARD
static datetime now() noexcept;
547 constexpr
void clear() noexcept {
551 has_timezone_ =
false;
555 constexpr bool operator ==(
const datetime& other)
const noexcept {
556 return date_ == other.date_ && time_ == other.time_
557 && has_timezone_ == other.has_timezone_
558 && offset_seconds_ == other.offset_seconds_;
561 constexpr bool operator <(
const datetime& other)
const noexcept {
562 if (date_ < other.date_) {
564 }
else if (date_ == other.date_) {
565 if (time_ < other.time_) {
567 }
else if (time_ == other.time_) {
568 if (has_timezone_ && other.has_timezone_ &&
569 offset_seconds_ < other.offset_seconds_) {
581 const int64_t current_total_sec =
582 static_cast<int64_t>(time_.hours()) * 3600 +
583 static_cast<int64_t>(time_.minutes()) * 60 +
584 static_cast<int64_t>(time_.seconds());
587 int64_t days_to_add = new_total_sec / 86400;
588 new_total_sec %= 86400;
590 if (new_total_sec < 0) {
591 new_total_sec += 86400;
595 date_ +=
static_cast<date_type
>(days_to_add);
597 static_cast<time_type
>(new_total_sec / 3600),
598 static_cast<time_type
>((new_total_sec % 3600) / 60),
599 static_cast<time_type
>(new_total_sec % 60)
607 const int64_t current_total_sec =
608 static_cast<int64_t>(time_.hours()) * 3600 +
609 static_cast<int64_t>(time_.minutes()) * 60 +
610 static_cast<int64_t>(time_.seconds());
615 if (new_total_sec < 0) {
616 days_to_subtract = (-new_total_sec + 86399) / 86400;
617 new_total_sec += days_to_subtract * 86400;
620 date_ -=
static_cast<date_type
>(days_to_subtract);
622 static_cast<time_type
>(new_total_sec / 3600),
623 static_cast<time_type
>((new_total_sec % 3600) / 60),
624 static_cast<time_type
>(new_total_sec % 60)
641 constexpr datetime& operator ++() {
return *
this += 1; }
642 constexpr datetime operator ++(
int) {
643 const datetime ret(*
this);
647 constexpr datetime& operator --() {
return *
this -= 1; }
648 constexpr datetime operator --(
int) {
649 const datetime ret(*
this);
654 constexpr time_type
operator -(
const datetime& other)
const noexcept {
655 const time_type day_diff = date_ - other.date_;
656 time_type sec_diff = day_diff * 86400;
657 sec_diff += (time_ - other.time_);
662 MSTL_NODISCARD MSTL_CONSTEXPR20
string to_offset_string()
const {
663 if (!has_timezone_)
return {};
664 if (offset_seconds_ == 0)
return "Z";
665 int64_t total_sec = offset_seconds_;
666 const char sign = total_sec >= 0 ?
'+' :
'-';
667 total_sec = total_sec >= 0 ? total_sec : -total_sec;
674 static constexpr datetime from_UTC(
const datetime& utc_dt,
const int32_t offset_sec = 0) noexcept {
675 datetime utc_time = utc_dt;
676 if (utc_dt.has_timezone_ && utc_dt.offset_seconds_ != 0) {
677 utc_time = utc_dt.to_UTC();
679 datetime local = utc_time + offset_sec;
680 local.offset_seconds_ = offset_sec;
681 local.has_timezone_ =
true;
685 MSTL_NODISCARD
constexpr datetime to_UTC() const noexcept {
686 if (!has_timezone_) {
689 datetime utc = *
this;
690 utc -= offset_seconds_;
691 utc.offset_seconds_ = 0;
692 utc.has_timezone_ =
true;
697 MSTL_NODISCARD MSTL_CONSTEXPR20
string to_string_ISO_UTC()
const {
699 return date_.to_string() +
"T" + time_.to_string() + to_offset_string();
701 return date_.to_string() +
"T" + time_.to_string();
705 MSTL_NODISCARD
static constexpr datetime parse_ISO_UTC(
const string_view str) {
706 if (str.size() < 20 || str[10] !=
'T') {
707 throw_exception(value_exception(
"Invalid ISO UTC datetime format."));
710 const _MSTL date d = date::parse(str.substr(0, 10));
711 const _MSTL time t = time::parse(str.substr(11, 8));
713 if (str.size() > 19 && str[19] ==
'Z') {
714 return datetime(d, t, 0);
715 }
else if (str.size() > 19 && (str[19] ==
'+' || str[19] ==
'-')) {
716 const char sign = str[19];
719 if (str.size() >= pos + 2) {
720 hours = integer32::parse(str.substr(pos, 2));
722 if (str.size() >= pos + 3 && str[pos] ==
':') {
724 if (str.size() >= pos + 2) {
725 minutes = integer32::parse(str.substr(pos, 2));
731 if (
sign ==
'-') total_offset = -total_offset;
732 return datetime(d, t, total_offset);
734 return datetime(d, t);
737 MSTL_CONSTEXPR20
bool try_parse_ISO_UTC(string_view str)
noexcept {
739 datetime tmp = datetime::parse_ISO_UTC(str);
748 MSTL_NODISCARD MSTL_CONSTEXPR20
string to_string_GMT() const noexcept {
749 const _MSTL date utc_date = date();
750 const _MSTL time utc_time = time();
752 int wday = utc_date.days_of_week();
753 if (wday < 0 || wday >= 7) wday = 0;
755 int mon_idx = utc_date.month() - 1;
756 if (mon_idx < 0 || mon_idx >= 12) mon_idx = 0;
758 return _MSTL format(
"{}, {:02d} {} {} {} GMT",
767 MSTL_NODISCARD
static constexpr datetime parse_GMT(string_view str) {
768 if (str.size() < 29) {
769 throw_exception(value_exception(
"Invalid date length."));
771 if (str.substr(3, 2) !=
", ") {
772 throw_exception(value_exception(
"Invalid date format"));
775 str.remove_prefix(5);
776 const int day = integer32::parse(str.substr(0, 2));
777 str.remove_prefix(3);
778 const int mon = months_to_int(str.substr(0, 3));
779 if (mon == 0) throw_exception(value_exception(
"Invalid month in date"));
780 str.remove_prefix(4);
781 const int year = integer32::parse(str.substr(0, 4));
782 str.remove_prefix(5);
783 const int hour = integer32::parse(str.substr(0, 2));
784 str.remove_prefix(3);
785 const int minute = integer32::parse(str.substr(0, 2));
786 str.remove_prefix(3);
787 const int second = integer32::parse(str.substr(0, 2));
788 str.remove_prefix(3);
791 throw_exception(value_exception(
"Invalid timezone in date"));
793 return datetime(year, mon, day, hour, minute, second);
796 MSTL_CONSTEXPR20
bool try_parse_GMT(
const string_view str)
noexcept {
798 datetime tmp = datetime::parse_GMT(str);
807 MSTL_NODISCARD MSTL_CONSTEXPR20
string to_string_ISO()
const {
808 return date_.to_string() +
"T" + time_.to_string();
811 MSTL_NODISCARD
static constexpr datetime parse_ISO(
const string_view str) {
812 if (str.size() < 19 || str[10] !=
'T') {
813 throw_exception(value_exception(
"Invalid ISO datetime format."));
815 const _MSTL date d =
_MSTL date::parse(str.substr(0, 10));
817 if (str.size() >= 19) {
820 const _MSTL time t =
_MSTL time::parse(str.substr(11, time_len));
821 return datetime(d, t);
824 MSTL_CONSTEXPR20
bool try_parse_ISO(
const string_view str)
noexcept {
826 datetime tmp = datetime::parse_ISO(str);
835 MSTL_NODISCARD MSTL_CONSTEXPR20
string to_string()
const {
836 return date_.to_string() +
" " + time_.to_string();
839 MSTL_NODISCARD
static constexpr datetime parse(
const string_view str) {
840 if (str.size() != 19 || str[10] !=
' ') {
841 throw_exception(value_exception(
"Wrong string formation."));
843 const _MSTL date d = date::parse(str.substr(0, 10));
844 const _MSTL time t = time::parse(str.substr(11, 8));
845 return datetime(d, t);
848 MSTL_NODISCARD
constexpr size_t to_hash() const noexcept {
849 return date_.to_hash() ^ time_.to_hash() ^
850 hash<bool>()(has_timezone_) ^ hash<int64_t>()(offset_seconds_);
853 constexpr void swap(datetime& other)
noexcept {
856 _MSTL swap(offset_seconds_, other.offset_seconds_);
857 _MSTL swap(has_timezone_, other.has_timezone_);
862class MSTL_API timestamp :
public iobject<timestamp>,
public ipackage<timestamp, int64_t> {
866 constexpr timestamp() noexcept = default;
868 constexpr timestamp(const timestamp ×tamp) noexcept
869 : ipackage(timestamp.value_) {}
871 constexpr timestamp& operator =(
const timestamp ×tamp)
noexcept {
872 value_ = timestamp.value_;
876 constexpr timestamp(timestamp&& timestamp) noexcept
877 : ipackage(timestamp.value_) {
881 constexpr timestamp& operator =(timestamp&& timestamp)
noexcept {
882 value_ = timestamp.value_;
887 constexpr explicit timestamp(
const value_type sec) noexcept
890 constexpr explicit timestamp(
const datetime& dt)
noexcept {
891 value_ = dt - datetime::epoch();
894 MSTL_CONSTEXPR20 ~timestamp() =
default;
897 MSTL_NODISCARD
static timestamp now() noexcept {
898 return timestamp(datetime::now());
901 MSTL_NODISCARD
constexpr datetime to_datetime() const noexcept {
902 return datetime::epoch() + value_;
905 MSTL_NODISCARD MSTL_CONSTEXPR20
string to_string()
const {
906 return integer64(value_).to_string();
909 MSTL_NODISCARD
static constexpr timestamp parse(
const string_view str) {
910 return timestamp{integer64::parse(str)};
913 constexpr void clear() noexcept {
long long int64_t
64位有符号整数类型
duration< int64_t, ratio< 86400 > > days
天持续时间
duration< int64_t, ratio< 3600 > > hours
小时持续时间
duration< int64_t, ratio< 60 > > minutes
分钟持续时间
duration< int64_t > seconds
秒持续时间
bool operator==(const function< Res(Args...)> &f, nullptr_t null) noexcept
等于空指针比较
MSTL_CONSTEXPR14 int sign(const T &value) noexcept
获取数值的符号
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_CONSTANTS__
结束constants命名空间
#define _CONSTANTS
constants命名空间前缀
#define MSTL_BEGIN_CONSTANTS__
开始constants命名空间
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
MSTL_NODISCARD constexpr normal_iterator< Iterator > operator+(iter_difference_t< normal_iterator< Iterator > > n, const normal_iterator< Iterator > &iter) noexcept
加法运算符
MSTL_NODISCARD constexpr auto operator-(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept -> decltype(lhs.base() - rhs.base())
减法运算符
MSTL_NODISCARD constexpr bool operator<(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
小于比较运算符
void swap()=delete
删除无参数的swap重载
MSTL_NODISCARD constexpr size_t to_hash() const noexcept(noexcept(derived().to_hash()))
获取对象的哈希值