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++03, c++11, c++14, c++17
9 // <chrono>
10 // class year_month_day_last;
11 
12 // constexpr year_month_day_last
13 //   operator/(const year_month& ym, last_spec) noexcept;
14 // Returns: {ym.year(), month_day_last{ym.month()}}.
15 
16 
17 // constexpr year_month_day_last
18 //   operator/(const year& y, const month_day_last& mdl) noexcept;
19 // Returns: {y, mdl}.
20 //
21 // constexpr year_month_day_last
22 //   operator/(int y, const month_day_last& mdl) noexcept;
23 // Returns: year(y) / mdl.
24 //
25 // constexpr year_month_day_last
26 //   operator/(const month_day_last& mdl, const year& y) noexcept;
27 // Returns: y / mdl.
28 //
29 // constexpr year_month_day_last
30 //   operator/(const month_day_last& mdl, int y) noexcept;
31 // Returns: year(y) / mdl.
32 
33 
34 #include <chrono>
35 #include <type_traits>
36 #include <cassert>
37 
38 #include "test_macros.h"
39 
main(int,char **)40 int main(int, char**)
41 {
42     using day                 = std::chrono::day;
43     using month               = std::chrono::month;
44     using year_month          = std::chrono::year_month;
45     using year                = std::chrono::year;
46     using month_day_last      = std::chrono::month_day_last;
47     using year_month_day_last = std::chrono::year_month_day_last;
48 
49     constexpr month February = std::chrono::February;
50     constexpr std::chrono::last_spec last = std::chrono::last;
51 
52     { // operator/(const year_month& ym, last_spec)
53         constexpr year_month Feb2018{year{2018}, February};
54 
55         ASSERT_NOEXCEPT (                              Feb2018/last);
56         ASSERT_SAME_TYPE(year_month_day_last, decltype(Feb2018/last));
57 
58         static_assert((Feb2018/last).year()  == year{2018}, "");
59         static_assert((Feb2018/last).month() == February,   "");
60 
61         for (int i = 1000; i < 1010; ++i)
62             for (unsigned j = 1; j <= 12; ++j)
63             {
64                 year y{i};
65                 month m{j};
66                 year_month_day_last ymdl = year_month{y,m}/last;
67                 assert(ymdl.year()  == y);
68                 assert(ymdl.month() == m);
69             }
70     }
71 
72 
73     { // operator/(const year& y, const month_day_last& mdl) (and switched)
74         ASSERT_NOEXCEPT (                              year{2018}/month_day_last{February});
75         ASSERT_SAME_TYPE(year_month_day_last, decltype(year{2018}/month_day_last{February}));
76         ASSERT_NOEXCEPT (                              month_day_last{February}/year{2018});
77         ASSERT_SAME_TYPE(year_month_day_last, decltype(month_day_last{February}/year{2018}));
78 
79         static_assert((year{2018}/month_day_last{February}).month() == February,   "");
80         static_assert((year{2018}/month_day_last{February}).year()  == year{2018}, "");
81         static_assert((month_day_last{February}/year{2018}).month() == February,   "");
82         static_assert((month_day_last{February}/year{2018}).year()  == year{2018}, "");
83 
84         for (int i = 1000; i < 1010; ++i)
85             for (unsigned j = 1; j <= 12; ++j)
86             {
87                 year y{i};
88                 month m{j};
89                 year_month_day_last ymdl1 = y/month_day_last{m};
90                 year_month_day_last ymdl2 = month_day_last{m}/y;
91                 assert(ymdl1.month() == m);
92                 assert(ymdl2.month() == m);
93                 assert(ymdl2.year()  == y);
94                 assert(ymdl1.year()  == y);
95                 assert(ymdl1 == ymdl2);
96             }
97     }
98 
99     { // operator/(int y, const month_day_last& mdl) (and switched)
100         ASSERT_NOEXCEPT (                              2018/month_day_last{February});
101         ASSERT_SAME_TYPE(year_month_day_last, decltype(2018/month_day_last{February}));
102         ASSERT_NOEXCEPT (                              month_day_last{February}/2018);
103         ASSERT_SAME_TYPE(year_month_day_last, decltype(month_day_last{February}/2018));
104 
105         static_assert((2018/month_day_last{February}).month() == February,   "");
106         static_assert((2018/month_day_last{February}).year()  == year{2018}, "");
107         static_assert((month_day_last{February}/2018).month() == February,   "");
108         static_assert((month_day_last{February}/2018).year()  == year{2018}, "");
109 
110         for (int i = 1000; i < 1010; ++i)
111             for (unsigned j = 1; j <= 12; ++j)
112             {
113                 year y{i};
114                 month m{j};
115                 year_month_day_last ymdl1 = i/month_day_last{m};
116                 year_month_day_last ymdl2 = month_day_last{m}/i;
117                 assert(ymdl1.month() == m);
118                 assert(ymdl2.month() == m);
119                 assert(ymdl2.year()  == y);
120                 assert(ymdl1.year()  == y);
121                 assert(ymdl1 == ymdl2);
122             }
123     }
124 
125     // the result of year_month_day_last::day() is unspecified when !ok(),
126     // but it shouldn't crash.
127     {
128         year_month_day_last ymdl = year{2020}/month{13}/last;
129         assert(!ymdl.ok());
130         day d = ymdl.day(); (void)d; // doesn't crash
131     }
132 
133     return 0;
134 }
135