aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/std/time/weekday/1.cc
blob: ac05f728a559eabc03bd1d0f0203d6bc85e2d09e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// { dg-do compile { target c++20 } }

// Copyright (C) 2020-2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.

// Class template day [time.cal.weekday]

#include <chrono>
#include <limits>

constexpr void
constexpr_weekday()
{
  using namespace std::chrono;

  weekday dwd{};
  ++dwd;
  dwd++;
  --dwd;
  dwd--;
  dwd += days{3};
  dwd -= days{3};

  static_assert(weekday{3}[2].weekday() == weekday{3});
  static_assert(weekday{3}[last].weekday() == weekday{3});

  // Test for UB (overflow).
  {
    using rep = days::rep;
    using std::numeric_limits;

    auto constexpr days_min = days{numeric_limits<rep>::min()};
    auto constexpr weekday_from_sysdays_min   = weekday{sys_days{days_min}};
    auto constexpr weekday_000_plus_days_min  = weekday{ 0 } + days_min;
    auto constexpr weekday_255_plus_days_min  = weekday{255} + days_min;
    auto constexpr weekday_000_minus_days_min = weekday{ 0 } - days_min;
    auto constexpr weekday_255_minus_days_min = weekday{255} - days_min;

    auto constexpr days_max = days{numeric_limits<rep>::max()};
    auto constexpr weekday_from_sysdays_max   = weekday{sys_days{days_max}};
    auto constexpr weekday_000_plus_days_max  = weekday{ 0 } + days_max;
    auto constexpr weekday_255_plus_days_max  = weekday{255} + days_max;
    auto constexpr weekday_000_minus_days_max = weekday{ 0 } - days_max;
    auto constexpr weekday_255_minus_days_max = weekday{255} - days_max;
  }

  static_assert(weekday{sys_days{1900y/January/1}} == Monday);
  static_assert(weekday{sys_days{1970y/January/1}} == Thursday);
  static_assert(weekday{sys_days{2020y/August/21}} == Friday);

  static_assert(weekday{local_days{1900y/January/1}} == Monday);
  static_assert(weekday{local_days{1970y/January/1}} == Thursday);
  static_assert(weekday{local_days{2020y/August/21}} == Friday);

  static_assert(++weekday{3} == weekday{4});
  static_assert(weekday{3}++ == weekday{3});
  static_assert(--weekday{3} == weekday{2});
  static_assert(weekday{3}-- == weekday{3});
  static_assert((weekday{3} += days{3}) == weekday{6});
  static_assert((weekday{3} -= days{3}) == weekday{0});

  static_assert(Monday + days{7000} == Monday);
  static_assert(Monday + days{-7000} == Monday);
  static_assert(days{7001} + Monday == Tuesday);
  static_assert(days{-7001} + Monday == Sunday);
  static_assert(Monday - days{7000} == Monday);
  static_assert(Monday - days{-7000} == Monday);
  static_assert(Monday - days{7001} == Sunday);

  static_assert([] {
    constexpr unsigned diff_tbl[7][7]
      = { { 0, 6, 5, 4, 3, 2, 1},
	  { 1, 0, 6, 5, 4, 3, 2},
	  { 2, 1, 0, 6, 5, 4, 3},
	  { 3, 2, 1, 0, 6, 5, 4},
	  { 4, 3, 2, 1, 0, 6, 5},
	  { 5, 4, 3, 2, 1, 0, 6},
	  { 6, 5, 4, 3, 2, 1, 0} };
    for (unsigned x = 0; x < 7; x++)
      for (unsigned y = 0; y < 7; y++)
	{
	  if (weekday{x} - weekday{y} != days{diff_tbl[x][y]})
	    return false;
	  if (weekday{x} - days{diff_tbl[x][y]} != weekday{y})
	    return false;
	  if (weekday{x} != weekday{y} + days{diff_tbl[x][y]})
	    return false;
	  if (weekday{x} != days{diff_tbl[x][y]} + weekday{y})
	    return false;
	}
    return true;
  }());

  static_assert(Sunday.c_encoding() == 0);
  static_assert(Sunday.iso_encoding() == 7);
  static_assert(Monday.c_encoding() == 1);
  static_assert(Monday.iso_encoding() == 1);

  static_assert(!weekday{127}.ok());
  static_assert(weekday{0}.ok());
  static_assert(weekday{6}.ok());
  static_assert(weekday{7}.ok()); // Ctor wraps 7 to 0.
  static_assert(!weekday{8}.ok());

  static_assert(weekday{7} == weekday{0});
  static_assert(!(weekday{0} == weekday{1}));
  static_assert( (weekday{0} != weekday{2}));
}