Skip to content

Commit db99d3a

Browse files
committed
Implement change #4 of P1466: Change weekday to accept both 0 and 7 as Sunday. Add accessors 'c_encoding' and 'iso_encoding' to provide different interpretations of the weekday. Remove 'operator unsigned'
llvm-svn: 366981
1 parent 272a9db commit db99d3a

File tree

20 files changed

+162
-66
lines changed

20 files changed

+162
-66
lines changed

Diff for: libcxx/include/chrono

+7-6
Original file line numberDiff line numberDiff line change
@@ -1810,7 +1810,7 @@ private:
18101810
unsigned char __wd;
18111811
public:
18121812
weekday() = default;
1813-
inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val)) {}
1813+
inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {}
18141814
inline constexpr weekday(const sys_days& __sysd) noexcept
18151815
: __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {}
18161816
inline explicit constexpr weekday(const local_days& __locd) noexcept
@@ -1822,7 +1822,8 @@ public:
18221822
inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; }
18231823
constexpr weekday& operator+=(const days& __dd) noexcept;
18241824
constexpr weekday& operator-=(const days& __dd) noexcept;
1825-
inline explicit constexpr operator unsigned() const noexcept { return __wd; }
1825+
inline constexpr unsigned c_encoding() const noexcept { return __wd; }
1826+
inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; }
18261827
inline constexpr bool ok() const noexcept { return __wd <= 6; }
18271828
constexpr weekday_indexed operator[](unsigned __index) const noexcept;
18281829
constexpr weekday_last operator[](last_spec) const noexcept;
@@ -1842,15 +1843,15 @@ unsigned char weekday::__weekday_from_days(int __days) noexcept
18421843

18431844
inline constexpr
18441845
bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept
1845-
{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
1846+
{ return __lhs.c_encoding() == __rhs.c_encoding(); }
18461847

18471848
inline constexpr
18481849
bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept
18491850
{ return !(__lhs == __rhs); }
18501851

18511852
inline constexpr
18521853
bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept
1853-
{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
1854+
{ return __lhs.c_encoding() < __rhs.c_encoding(); }
18541855

18551856
inline constexpr
18561857
bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept
@@ -1866,7 +1867,7 @@ bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept
18661867

18671868
constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept
18681869
{
1869-
auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + __rhs.count();
1870+
auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count();
18701871
auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7;
18711872
return weekday{static_cast<unsigned>(__mu - __yr * 7)};
18721873
}
@@ -1879,7 +1880,7 @@ constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept
18791880

18801881
constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept
18811882
{
1882-
const int __wdu = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs);
1883+
const int __wdu = __lhs.c_encoding() - __rhs.c_encoding();
18831884
const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7;
18841885
return days{__wdu - __wk * 7};
18851886
}

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/weekday_last.pass.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int main(int, char**)
3838
for (unsigned i = 1; i <= 50; ++i)
3939
{
4040
month_weekday_last mdl(January, weekday_last{weekday{i}});
41-
assert( static_cast<unsigned>(mdl.weekday_last().weekday()) == i);
41+
assert( mdl.weekday_last().weekday().c_encoding() == (i == 7 ? 0 : i));
4242
}
4343

4444
return 0;

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/weekday.pass.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ int main(int, char**)
3333
for (unsigned i = 0; i <= 6; ++i)
3434
{
3535
weekday_indexed wdi(weekday{i}, 2);
36-
assert( static_cast<unsigned>(wdi.weekday()) == i);
36+
assert( wdi.weekday().c_encoding() == i);
3737
}
3838

3939
return 0;

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ok.pass.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ int main(int, char**)
2929

3030
static_assert( weekday_last{weekday{0}}.ok(), "");
3131
static_assert( weekday_last{weekday{1}}.ok(), "");
32-
static_assert(!weekday_last{weekday{7}}.ok(), "");
32+
static_assert(!weekday_last{weekday{8}}.ok(), "");
3333

3434
for (unsigned i = 0; i <= 255; ++i)
3535
assert(weekday_last{weekday{i}}.ok() == weekday{i}.ok());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
9+
10+
// <chrono>
11+
// class weekday;
12+
13+
// constexpr unsigned c_encoding() const noexcept;
14+
15+
16+
#include <chrono>
17+
#include <type_traits>
18+
#include <cassert>
19+
20+
#include "test_macros.h"
21+
22+
template <typename WD>
23+
constexpr bool testConstexpr()
24+
{
25+
WD wd{5};
26+
return wd.c_encoding() == 5;
27+
}
28+
29+
int main(int, char**)
30+
{
31+
using weekday = std::chrono::weekday;
32+
33+
ASSERT_NOEXCEPT( std::declval<weekday&>().c_encoding());
34+
ASSERT_SAME_TYPE(unsigned, decltype(std::declval<weekday&>().c_encoding()));
35+
36+
static_assert(testConstexpr<weekday>(), "");
37+
38+
for (unsigned i = 0; i <= 10; ++i)
39+
{
40+
weekday wd(i);
41+
assert(wd.c_encoding() == (i == 7 ? 0 : i));
42+
}
43+
44+
return 0;
45+
}

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.local_days.pass.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ int main(int, char**)
4242
constexpr weekday wd{sd};
4343

4444
static_assert( wd.ok(), "");
45-
static_assert(static_cast<unsigned>(wd) == 4, "");
45+
static_assert( wd.c_encoding() == 4, "");
4646
}
4747

4848
{
4949
constexpr local_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday
5050
constexpr weekday wd{sd};
5151

5252
static_assert( wd.ok(), "");
53-
static_assert(static_cast<unsigned>(wd) == 3, "");
53+
static_assert( wd.c_encoding() == 3, "");
5454
}
5555

5656

@@ -59,15 +59,15 @@ int main(int, char**)
5959
constexpr weekday wd{sd};
6060

6161
static_assert( wd.ok(), "");
62-
static_assert(static_cast<unsigned>(wd) == 2, "");
62+
static_assert( wd.c_encoding() == 2, "");
6363
}
6464

6565
{
6666
local_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday
6767
weekday wd{sd};
6868

6969
assert( wd.ok());
70-
assert(static_cast<unsigned>(wd) == 3);
70+
assert( wd.c_encoding() == 3);
7171
}
7272

7373
return 0;

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.pass.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
// constexpr weekday(const sys_days& dp) noexcept;
1616
// explicit constexpr weekday(const local_days& dp) noexcept;
1717
//
18-
// explicit constexpr operator unsigned() const noexcept;
18+
// unsigned c_encoding() const noexcept;
1919

20-
// Effects: Constructs an object of type weekday by initializing m_ with m.
21-
// The value held is unspecified if d is not in the range [0, 255].
20+
// Effects: Constructs an object of type weekday by initializing wd_ with wd == 7 ? 0 : wd
21+
// The value held is unspecified if wd is not in the range [0, 255].
2222

2323
#include <chrono>
2424
#include <type_traits>
@@ -32,18 +32,18 @@ int main(int, char**)
3232

3333
ASSERT_NOEXCEPT(weekday{});
3434
ASSERT_NOEXCEPT(weekday(1));
35-
ASSERT_NOEXCEPT(static_cast<unsigned>(weekday(1)));
35+
ASSERT_NOEXCEPT(weekday(1).c_encoding());
3636

3737
constexpr weekday m0{};
38-
static_assert(static_cast<unsigned>(m0) == 0, "");
38+
static_assert(m0.c_encoding() == 0, "");
3939

4040
constexpr weekday m1{1};
41-
static_assert(static_cast<unsigned>(m1) == 1, "");
41+
static_assert(m1.c_encoding() == 1, "");
4242

4343
for (unsigned i = 0; i <= 255; ++i)
4444
{
4545
weekday m(i);
46-
assert(static_cast<unsigned>(m) == i);
46+
assert(m.c_encoding() == (i == 7 ? 0 : i));
4747
}
4848

4949
// TODO - sys_days and local_days ctor tests

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.sys_days.pass.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ int main(int, char**)
4242
constexpr weekday wd{sd};
4343

4444
static_assert( wd.ok(), "");
45-
static_assert(static_cast<unsigned>(wd) == 4, "");
45+
static_assert( wd.c_encoding() == 4, "");
4646
}
4747

4848
{
4949
constexpr sys_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday
5050
constexpr weekday wd{sd};
5151

5252
static_assert( wd.ok(), "");
53-
static_assert(static_cast<unsigned>(wd) == 3, "");
53+
static_assert( wd.c_encoding() == 3, "");
5454
}
5555

5656

@@ -59,15 +59,15 @@ int main(int, char**)
5959
constexpr weekday wd{sd};
6060

6161
static_assert( wd.ok(), "");
62-
static_assert(static_cast<unsigned>(wd) == 2, "");
62+
static_assert( wd.c_encoding() == 2, "");
6363
}
6464

6565
{
6666
sys_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday
6767
weekday wd{sd};
6868

6969
assert( wd.ok());
70-
assert(static_cast<unsigned>(wd) == 3);
70+
assert( wd.c_encoding() == 3);
7171
}
7272

7373
return 0;

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/decrement.pass.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ template <typename WD>
2525
constexpr bool testConstexpr()
2626
{
2727
WD wd{1};
28-
if (static_cast<unsigned>(--wd) != 0) return false;
29-
if (static_cast<unsigned>(wd--) != 0) return false;
30-
if (static_cast<unsigned>(wd) != 6) return false;
28+
if ((--wd).c_encoding() != 0) return false;
29+
if ((wd--).c_encoding() != 0) return false;
30+
if ((wd).c_encoding() != 6) return false;
3131
return true;
3232
}
3333

@@ -45,9 +45,9 @@ int main(int, char**)
4545
for (unsigned i = 0; i <= 6; ++i)
4646
{
4747
weekday wd(i);
48-
assert((static_cast<unsigned>(--wd) == euclidian_subtraction<unsigned, 0, 6>(i, 1)));
49-
assert((static_cast<unsigned>(wd--) == euclidian_subtraction<unsigned, 0, 6>(i, 1)));
50-
assert((static_cast<unsigned>(wd) == euclidian_subtraction<unsigned, 0, 6>(i, 2)));
48+
assert(((--wd).c_encoding() == euclidian_subtraction<unsigned, 0, 6>(i, 1)));
49+
assert(((wd--).c_encoding() == euclidian_subtraction<unsigned, 0, 6>(i, 1)));
50+
assert(((wd) .c_encoding() == euclidian_subtraction<unsigned, 0, 6>(i, 2)));
5151
}
5252

5353
return 0;

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/increment.pass.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ template <typename WD>
2525
constexpr bool testConstexpr()
2626
{
2727
WD wd{5};
28-
if (static_cast<unsigned>(++wd) != 6) return false;
29-
if (static_cast<unsigned>(wd++) != 6) return false;
30-
if (static_cast<unsigned>(wd) != 0) return false;
28+
if ((++wd).c_encoding() != 6) return false;
29+
if ((wd++).c_encoding() != 6) return false;
30+
if ((wd) .c_encoding() != 0) return false;
3131
return true;
3232
}
3333

@@ -45,9 +45,9 @@ int main(int, char**)
4545
for (unsigned i = 0; i <= 6; ++i)
4646
{
4747
weekday wd(i);
48-
assert((static_cast<unsigned>(++wd) == euclidian_addition<unsigned, 0, 6>(i, 1)));
49-
assert((static_cast<unsigned>(wd++) == euclidian_addition<unsigned, 0, 6>(i, 1)));
50-
assert((static_cast<unsigned>(wd) == euclidian_addition<unsigned, 0, 6>(i, 2)));
48+
assert(((++wd).c_encoding() == euclidian_addition<unsigned, 0, 6>(i, 1)));
49+
assert(((wd++).c_encoding() == euclidian_addition<unsigned, 0, 6>(i, 1)));
50+
assert(((wd) .c_encoding() == euclidian_addition<unsigned, 0, 6>(i, 2)));
5151
}
5252

5353
return 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
9+
10+
// <chrono>
11+
// class weekday;
12+
13+
// constexpr unsigned iso_encoding() const noexcept;
14+
// Returns the underlying weekday, _except_ that returns '7' for Sunday (zero)
15+
// See [time.cal.wd.members]
16+
17+
#include <chrono>
18+
#include <type_traits>
19+
#include <cassert>
20+
21+
#include "test_macros.h"
22+
23+
template <typename WD>
24+
constexpr bool testConstexpr()
25+
{
26+
WD wd{5};
27+
return wd.c_encoding() == 5;
28+
}
29+
30+
int main(int, char**)
31+
{
32+
using weekday = std::chrono::weekday;
33+
34+
ASSERT_NOEXCEPT( std::declval<weekday&>().iso_encoding());
35+
ASSERT_SAME_TYPE(unsigned, decltype(std::declval<weekday&>().iso_encoding()));
36+
37+
static_assert(testConstexpr<weekday>(), "");
38+
39+
// This is different than all the other tests, because the '7' gets converted to
40+
// a zero in the constructor, but then back to '7' by iso_encoding().
41+
for (unsigned i = 0; i <= 10; ++i)
42+
{
43+
weekday wd(i);
44+
assert(wd.iso_encoding() == (i == 0 ? 7 : i));
45+
}
46+
47+
return 0;
48+
}

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ok.pass.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ int main(int, char**)
2828

2929
static_assert( weekday{0}.ok(), "");
3030
static_assert( weekday{1}.ok(), "");
31-
static_assert(!weekday{7}.ok(), "");
31+
static_assert( weekday{7}.ok(), ""); // 7 is transmorgified into 0 in the ctor
32+
static_assert(!weekday{8}.ok(), "");
3233

33-
for (unsigned i = 0; i <= 6; ++i)
34+
for (unsigned i = 0; i <= 7; ++i)
3435
assert(weekday{i}.ok());
35-
for (unsigned i = 7; i <= 255; ++i)
36+
for (unsigned i = 8; i <= 255; ++i)
3637
assert(!weekday{i}.ok());
3738

3839
return 0;

Diff for: libcxx/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/plus_minus_equal.pass.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ template <typename M, typename Ms>
2424
constexpr bool testConstexpr()
2525
{
2626
M m1{1};
27-
if (static_cast<unsigned>(m1 += Ms{ 1}) != 2) return false;
28-
if (static_cast<unsigned>(m1 += Ms{ 2}) != 4) return false;
29-
if (static_cast<unsigned>(m1 += Ms{ 4}) != 1) return false;
30-
if (static_cast<unsigned>(m1 -= Ms{ 1}) != 0) return false;
31-
if (static_cast<unsigned>(m1 -= Ms{ 2}) != 5) return false;
32-
if (static_cast<unsigned>(m1 -= Ms{ 4}) != 1) return false;
27+
if ((m1 += Ms{ 1}).c_encoding() != 2) return false;
28+
if ((m1 += Ms{ 2}).c_encoding() != 4) return false;
29+
if ((m1 += Ms{ 4}).c_encoding() != 1) return false;
30+
if ((m1 -= Ms{ 1}).c_encoding() != 0) return false;
31+
if ((m1 -= Ms{ 2}).c_encoding() != 5) return false;
32+
if ((m1 -= Ms{ 4}).c_encoding() != 1) return false;
3333
return true;
3434
}
3535

@@ -49,15 +49,15 @@ int main(int, char**)
4949
for (unsigned i = 0; i <= 6; ++i)
5050
{
5151
weekday wd(i);
52-
assert((static_cast<unsigned>(wd += days{3}) == euclidian_addition<unsigned, 0, 6>(i, 3)));
53-
assert((static_cast<unsigned>(wd) == euclidian_addition<unsigned, 0, 6>(i, 3)));
52+
assert(((wd += days{3}).c_encoding() == euclidian_addition<unsigned, 0, 6>(i, 3)));
53+
assert(((wd) .c_encoding() == euclidian_addition<unsigned, 0, 6>(i, 3)));
5454
}
5555

5656
for (unsigned i = 0; i <= 6; ++i)
5757
{
5858
weekday wd(i);
59-
assert((static_cast<unsigned>(wd -= days{4}) == euclidian_subtraction<unsigned, 0, 6>(i, 4)));
60-
assert((static_cast<unsigned>(wd) == euclidian_subtraction<unsigned, 0, 6>(i, 4)));
59+
assert(((wd -= days{4}).c_encoding() == euclidian_subtraction<unsigned, 0, 6>(i, 4)));
60+
assert(((wd) .c_encoding() == euclidian_subtraction<unsigned, 0, 6>(i, 4)));
6161
}
6262

6363
return 0;

0 commit comments

Comments
 (0)