mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 08:31:03 +08:00
[API BREAKING] Remove conversion from weekday to unsigned
* There has been a great deal of anguish over the encoding of weekdays: whether [0, 6] maps to [Sunday, Saturday] or [1, 7] maps to [Monday, Sunday]. This commit attempts to address that issue, but will break a small amount of code at compile-time. See below on how to fix that. * The weekday constructor used to accept [0, 6] to represent [Sunday, Saturday]. It now accepts [0, 7] to represent [Sunday, Saturday] with both 0 and 7 mapping to Sunday. * The conversion from weekday to unsigned has been removed. * To convert a weekday to unsigned replace: auto u = unsigned{wd}; with: auto u = (wd - Sunday).count(); This maps [Sunday, Saturday] to [0, 6], which is the C/POSIX mapping. If you prefer the ISO mapping ([Monday, Sunday] -> [1, 7]), then do: auto u = (wd - Monday).count() + 1;
This commit is contained in:
parent
6c4d333026
commit
40b83654b6
@ -431,7 +431,6 @@ public:
|
|||||||
CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT;
|
CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT;
|
||||||
CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT;
|
CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT;
|
||||||
|
|
||||||
CONSTCD11 explicit operator unsigned() const NOEXCEPT;
|
|
||||||
CONSTCD11 bool ok() const NOEXCEPT;
|
CONSTCD11 bool ok() const NOEXCEPT;
|
||||||
|
|
||||||
CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT;
|
CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT;
|
||||||
@ -439,6 +438,14 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static CONSTCD11 unsigned char weekday_from_days(int z) NOEXCEPT;
|
static CONSTCD11 unsigned char weekday_from_days(int z) NOEXCEPT;
|
||||||
|
|
||||||
|
friend CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT;
|
||||||
|
friend CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT;
|
||||||
|
friend CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT;
|
||||||
|
template<class CharT, class Traits>
|
||||||
|
friend std::basic_ostream<CharT, Traits>&
|
||||||
|
operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd);
|
||||||
|
friend class weekday_indexed;
|
||||||
};
|
};
|
||||||
|
|
||||||
CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT;
|
CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT;
|
||||||
@ -1765,7 +1772,7 @@ weekday::weekday_from_days(int z) NOEXCEPT
|
|||||||
CONSTCD11
|
CONSTCD11
|
||||||
inline
|
inline
|
||||||
weekday::weekday(unsigned wd) NOEXCEPT
|
weekday::weekday(unsigned wd) NOEXCEPT
|
||||||
: wd_(static_cast<decltype(wd_)>(wd))
|
: wd_(static_cast<decltype(wd_)>(wd != 7 ? wd : 0))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CONSTCD11
|
CONSTCD11
|
||||||
@ -1803,13 +1810,6 @@ weekday::operator-=(const days& d) NOEXCEPT
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSTCD11
|
|
||||||
inline
|
|
||||||
weekday::operator unsigned() const NOEXCEPT
|
|
||||||
{
|
|
||||||
return static_cast<unsigned>(wd_);
|
|
||||||
}
|
|
||||||
|
|
||||||
CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;}
|
CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;}
|
||||||
|
|
||||||
CONSTCD11
|
CONSTCD11
|
||||||
@ -1817,7 +1817,7 @@ inline
|
|||||||
bool
|
bool
|
||||||
operator==(const weekday& x, const weekday& y) NOEXCEPT
|
operator==(const weekday& x, const weekday& y) NOEXCEPT
|
||||||
{
|
{
|
||||||
return static_cast<unsigned>(x) == static_cast<unsigned>(y);
|
return x.wd_ == y.wd_;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSTCD11
|
CONSTCD11
|
||||||
@ -1833,8 +1833,9 @@ inline
|
|||||||
days
|
days
|
||||||
operator-(const weekday& x, const weekday& y) NOEXCEPT
|
operator-(const weekday& x, const weekday& y) NOEXCEPT
|
||||||
{
|
{
|
||||||
auto const diff = static_cast<unsigned>(x) - static_cast<unsigned>(y);
|
auto const wdu = x.wd_ - y.wd_;
|
||||||
return days{diff <= 6 ? diff : diff + 7};
|
auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7;
|
||||||
|
return days{wdu - wk * 7};
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSTCD14
|
CONSTCD14
|
||||||
@ -1842,7 +1843,7 @@ inline
|
|||||||
weekday
|
weekday
|
||||||
operator+(const weekday& x, const days& y) NOEXCEPT
|
operator+(const weekday& x, const days& y) NOEXCEPT
|
||||||
{
|
{
|
||||||
auto const wdu = static_cast<long long>(static_cast<unsigned>(x)) + y.count();
|
auto const wdu = static_cast<long long>(static_cast<unsigned>(x.wd_)) + y.count();
|
||||||
auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7;
|
auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7;
|
||||||
return weekday{static_cast<unsigned>(wdu - wk * 7)};
|
return weekday{static_cast<unsigned>(wdu - wk * 7)};
|
||||||
}
|
}
|
||||||
@ -1874,7 +1875,7 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd)
|
|||||||
os << format(fmt, wd);
|
os << format(fmt, wd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
os << static_cast<unsigned>(wd) << " is not a valid weekday";
|
os << static_cast<unsigned>(wd.wd_) << " is not a valid weekday";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1939,13 +1940,13 @@ CONSTDATA date::month October{10};
|
|||||||
CONSTDATA date::month November{11};
|
CONSTDATA date::month November{11};
|
||||||
CONSTDATA date::month December{12};
|
CONSTDATA date::month December{12};
|
||||||
|
|
||||||
CONSTDATA date::weekday Sunday{0u};
|
CONSTDATA date::weekday Monday{1};
|
||||||
CONSTDATA date::weekday Monday{1u};
|
CONSTDATA date::weekday Tuesday{2};
|
||||||
CONSTDATA date::weekday Tuesday{2u};
|
CONSTDATA date::weekday Wednesday{3};
|
||||||
CONSTDATA date::weekday Wednesday{3u};
|
CONSTDATA date::weekday Thursday{4};
|
||||||
CONSTDATA date::weekday Thursday{4u};
|
CONSTDATA date::weekday Friday{5};
|
||||||
CONSTDATA date::weekday Friday{5u};
|
CONSTDATA date::weekday Saturday{6};
|
||||||
CONSTDATA date::weekday Saturday{6u};
|
CONSTDATA date::weekday Sunday{7};
|
||||||
|
|
||||||
// weekday_indexed
|
// weekday_indexed
|
||||||
|
|
||||||
@ -1975,7 +1976,7 @@ weekday_indexed::ok() const NOEXCEPT
|
|||||||
CONSTCD11
|
CONSTCD11
|
||||||
inline
|
inline
|
||||||
weekday_indexed::weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT
|
weekday_indexed::weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT
|
||||||
: wd_(static_cast<decltype(wd_)>(static_cast<unsigned>(wd)))
|
: wd_(static_cast<decltype(wd_)>(static_cast<unsigned>(wd.wd_)))
|
||||||
, index_(static_cast<decltype(index_)>(index))
|
, index_(static_cast<decltype(index_)>(index))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -4337,11 +4338,11 @@ extract_weekday(std::basic_ostream<CharT, Traits>& os, const fields<Duration>& f
|
|||||||
os.setstate(std::ios::failbit);
|
os.setstate(std::ios::failbit);
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
unsigned wd;
|
weekday wd;
|
||||||
if (fds.ymd.ok())
|
if (fds.ymd.ok())
|
||||||
{
|
{
|
||||||
wd = static_cast<unsigned>(weekday{fds.ymd});
|
wd = weekday{fds.ymd};
|
||||||
if (fds.wd.ok() && wd != static_cast<unsigned>(fds.wd))
|
if (fds.wd.ok() && wd != fds.wd)
|
||||||
{
|
{
|
||||||
// fds.ymd and fds.wd are inconsistent
|
// fds.ymd and fds.wd are inconsistent
|
||||||
os.setstate(std::ios::failbit);
|
os.setstate(std::ios::failbit);
|
||||||
@ -4349,8 +4350,8 @@ extract_weekday(std::basic_ostream<CharT, Traits>& os, const fields<Duration>& f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wd = static_cast<unsigned>(fds.wd);
|
wd = fds.wd;
|
||||||
return wd;
|
return static_cast<unsigned>((wd - Sunday).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
template <class CharT, class Traits, class Duration>
|
||||||
@ -7216,8 +7217,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|||||||
if (ymd.ok())
|
if (ymd.ok())
|
||||||
{
|
{
|
||||||
if (wd == not_a_weekday)
|
if (wd == not_a_weekday)
|
||||||
wd = static_cast<int>(static_cast<unsigned>(weekday(ymd)));
|
wd = static_cast<int>((weekday(ymd) - Sunday).count());
|
||||||
else if (wd != static_cast<int>(static_cast<unsigned>(weekday(ymd))))
|
else if (wd != static_cast<int>((weekday(ymd) - Sunday).count()))
|
||||||
goto broken;
|
goto broken;
|
||||||
if (!computed)
|
if (!computed)
|
||||||
{
|
{
|
||||||
|
@ -451,7 +451,7 @@ weekday::weekday(unsigned wd) NOEXCEPT
|
|||||||
CONSTCD11
|
CONSTCD11
|
||||||
inline
|
inline
|
||||||
weekday::weekday(date::weekday wd) NOEXCEPT
|
weekday::weekday(date::weekday wd) NOEXCEPT
|
||||||
: wd_(to_iso_encoding(static_cast<unsigned>(wd)))
|
: wd_((wd-date::Monday).count() + 1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CONSTCD11
|
CONSTCD11
|
||||||
|
@ -77,11 +77,9 @@ static_assert( std::is_trivially_move_assignable<date::weekday>{}, "");
|
|||||||
|
|
||||||
static_assert( std::is_nothrow_constructible<date::weekday, unsigned>{}, "");
|
static_assert( std::is_nothrow_constructible<date::weekday, unsigned>{}, "");
|
||||||
static_assert( std::is_nothrow_constructible<date::weekday, date::sys_days>{}, "");
|
static_assert( std::is_nothrow_constructible<date::weekday, date::sys_days>{}, "");
|
||||||
static_assert( std::is_nothrow_constructible<unsigned, date::weekday>{}, "");
|
|
||||||
static_assert(!std::is_convertible<unsigned, date::weekday>{}, "");
|
static_assert(!std::is_convertible<unsigned, date::weekday>{}, "");
|
||||||
static_assert( std::is_convertible<date::sys_days, date::weekday>{}, "");
|
static_assert( std::is_convertible<date::sys_days, date::weekday>{}, "");
|
||||||
static_assert(!std::is_convertible<date::weekday, unsigned>{}, "");
|
static_assert(!std::is_convertible<date::weekday, unsigned>{}, "");
|
||||||
static_assert(static_cast<unsigned>(date::weekday{1u}) == 1, "");
|
|
||||||
|
|
||||||
static_assert( date::weekday{0u}.ok(), "");
|
static_assert( date::weekday{0u}.ok(), "");
|
||||||
static_assert( date::weekday{1u}.ok(), "");
|
static_assert( date::weekday{1u}.ok(), "");
|
||||||
@ -90,7 +88,8 @@ static_assert( date::weekday{3u}.ok(), "");
|
|||||||
static_assert( date::weekday{4u}.ok(), "");
|
static_assert( date::weekday{4u}.ok(), "");
|
||||||
static_assert( date::weekday{5u}.ok(), "");
|
static_assert( date::weekday{5u}.ok(), "");
|
||||||
static_assert( date::weekday{6u}.ok(), "");
|
static_assert( date::weekday{6u}.ok(), "");
|
||||||
static_assert(!date::weekday{7u}.ok(), "");
|
static_assert( date::weekday{7u}.ok(), "");
|
||||||
|
static_assert(!date::weekday{8u}.ok(), "");
|
||||||
|
|
||||||
void
|
void
|
||||||
test_weekday_arithmetic()
|
test_weekday_arithmetic()
|
||||||
|
@ -171,7 +171,7 @@ test_with_date_weekday()
|
|||||||
auto constexpr d1 = iso_week::sun;
|
auto constexpr d1 = iso_week::sun;
|
||||||
static_assert(unsigned{d1} == 7, "");
|
static_assert(unsigned{d1} == 7, "");
|
||||||
auto constexpr d2 = date::weekday{d1};
|
auto constexpr d2 = date::weekday{d1};
|
||||||
static_assert(unsigned{d2} == 0, "");
|
static_assert(d2 == date::Sunday, "");
|
||||||
auto constexpr d3 = iso_week::weekday{d2};
|
auto constexpr d3 = iso_week::weekday{d2};
|
||||||
static_assert(unsigned{d3} == 7, "");
|
static_assert(unsigned{d3} == 7, "");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user