From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1059) id 63EFA3954416; Fri, 28 Aug 2020 16:08:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 63EFA3954416 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1598630931; bh=69ziwgl0/DIgL7Iy8MJVRsI0qncU7QBEviQwQ3b0qmY=; h=From:To:Subject:Date:From; b=nIXIHwP/68szLaOiuZFK/ULCkMYwqZZn9BAoFQGwpiCZSKiYrQ9kDyn/51+7oJxif oaykt01F7peMH/9JcFpvSQsn88EwzXTsRNp6KvN+I5v3PBSPjAuDja8sPlsz0T5iCS zV2g3ySot34ExzjIiehOGhs3VBH90VSfKlO/a6hE= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Nathan Sidwell To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc/devel/c++-modules] libstdc++: Fix operator overload ambiguity with calendar types X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/devel/c++-modules X-Git-Oldrev: 04df5e7de2f3dd652a9cddc1c9adfbdf45947ae6 X-Git-Newrev: 7b743c67f04471a0129390ad2808e61e5538e0d3 Message-Id: <20200828160851.63EFA3954416@sourceware.org> Date: Fri, 28 Aug 2020 16:08:51 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Aug 2020 16:08:51 -0000 https://gcc.gnu.org/g:7b743c67f04471a0129390ad2808e61e5538e0d3 commit 7b743c67f04471a0129390ad2808e61e5538e0d3 Author: Patrick Palka Date: Thu Aug 27 14:09:52 2020 -0400 libstdc++: Fix operator overload ambiguity with calendar types We currently don't enforce a constraint on some of the calendar types' addition/subtraction operator overloads that take a 'months' arguments: Constraints: If the argument supplied by the caller for the months parameter is convertible to years, its implicit conversion sequence to years is worse than its implicit conversion sequence to months. This constraint is relevant when adding/subtracting a duration to/from, say, a year_month where the given duration is convertible to both 'months' and to 'years' (as in the new testcases below). The correct behavior here in light of this constraint is to perform the operation through the (more efficient) 'years'-based overload, but we currently emit an ambiguous overload error. This patch templatizes the 'months'-based addition/subtraction operator overloads so that in the event of an implicit-conversion tie, we select the non-template 'years'-based overload. This is the same approach that the date library takes for enforcing this constraint. libstdc++-v3/ChangeLog: * include/std/chrono (__detail::__months_years_conversion_disambiguator): Define. (year_month::operator+=): Templatize the 'months'-based overload so that the 'years'-based overload is selected in case of equally-ranked implicit conversion sequences to both 'months' and 'years' from the supplied argument. (year_month::operator-=): Likewise. (year_month::operator+): Likewise. (year_month::operator-): Likewise. (year_month_day::operator+=): Likewise. (year_month_day::operator-=): Likewise. (year_month_day::operator+): Likewise. (year_month_day::operator-): Likewise. (year_month_day_last::operator+=): Likewise. (year_month_day_last::operator-=): Likewise. (year_month_day_last::operator+): Likewise (year_month_day_last::operator-): Likewise. (year_month_day_weekday::operator+=): Likewise (year_month_day_weekday::operator-=): Likewise. (year_month_day_weekday::operator+): Likewise. (year_month_day_weekday::operator-): Likewise. (year_month_day_weekday_last::operator+=): Likewise (year_month_day_weekday_last::operator-=): Likewise. (year_month_day_weekday_last::operator+): Likewise. (year_month_day_weekday_last::operator-): Likewise. (testsuite/std/time/year_month/2.cc): New test. (testsuite/std/time/year_month_day/2.cc): New test. (testsuite/std/time/year_month_day_last/2.cc): New test. (testsuite/std/time/year_month_weekday/2.cc): New test. (testsuite/std/time/year_month_weekday_last/2.cc): New test. Diff: --- libstdc++-v3/include/std/chrono | 286 ++++++++++++--------- libstdc++-v3/testsuite/std/time/year_month/2.cc | 40 +++ .../testsuite/std/time/year_month_day/2.cc | 40 +++ .../testsuite/std/time/year_month_day_last/2.cc | 40 +++ .../testsuite/std/time/year_month_weekday/2.cc | 40 +++ .../std/time/year_month_weekday_last/2.cc | 40 +++ 6 files changed, 367 insertions(+), 119 deletions(-) diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index 01f1e2d2b71..df2f5d23f52 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -2046,6 +2046,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // YEAR_MONTH + namespace __detail + { + // [time.cal.ym], [time.cal.ymd], etc constrain the 'months'-based + // addition/subtraction operator overloads like so: + // + // Constraints: if the argument supplied by the caller for the months + // parameter is convertible to years, its implicit conversion sequence + // to years is worse than its implicit conversion sequence to months. + // + // We realize this constraint by templatizing the 'months'-based + // overloads (using a dummy defaulted template parameter), so that + // overload resolution doesn't select the 'months'-based overload unless + // the implicit conversion sequence to 'months' is better than that to + // 'years'. + using __months_years_conversion_disambiguator = void; + } + class year_month { private: @@ -2068,19 +2085,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION month() const noexcept { return _M_m; } - constexpr year_month& - operator+=(const months& __dm) noexcept - { - *this = *this + __dm; - return *this; - } + template + constexpr year_month& + operator+=(const months& __dm) noexcept + { + *this = *this + __dm; + return *this; + } - constexpr year_month& - operator-=(const months& __dm) noexcept - { - *this = *this - __dm; - return *this; - } + template + constexpr year_month& + operator-=(const months& __dm) noexcept + { + *this = *this - __dm; + return *this; + } constexpr year_month& operator+=(const years& __dy) noexcept @@ -2108,25 +2127,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator<=>(const year_month& __x, const year_month& __y) noexcept = default; - friend constexpr year_month - operator+(const year_month& __ym, const months& __dm) noexcept - { - // TODO: Optimize? - auto __m = __ym.month() + __dm; - auto __i = unsigned{__ym.month()} - 1 + __dm.count(); - auto __y = (__i < 0 - ? __ym.year() + years{(__i - 11) / 12} - : __ym.year() + years{__i / 12}); - return __y / __m; - } + template + friend constexpr year_month + operator+(const year_month& __ym, const months& __dm) noexcept + { + // TODO: Optimize? + auto __m = __ym.month() + __dm; + auto __i = unsigned{__ym.month()} - 1 + __dm.count(); + auto __y = (__i < 0 + ? __ym.year() + years{(__i - 11) / 12} + : __ym.year() + years{__i / 12}); + return __y / __m; + } - friend constexpr year_month - operator+(const months& __dm, const year_month& __ym) noexcept - { return __ym + __dm; } + template + friend constexpr year_month + operator+(const months& __dm, const year_month& __ym) noexcept + { return __ym + __dm; } - friend constexpr year_month - operator-(const year_month& __ym, const months& __dm) noexcept - { return __ym + -__dm; } + template + friend constexpr year_month + operator-(const year_month& __ym, const months& __dm) noexcept + { return __ym + -__dm; } friend constexpr months operator-(const year_month& __x, const year_month& __y) noexcept @@ -2200,19 +2222,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : year_month_day(sys_days{__dp.time_since_epoch()}) { } - constexpr year_month_day& - operator+=(const months& __m) noexcept - { - *this = *this + __m; - return *this; - } + template + constexpr year_month_day& + operator+=(const months& __m) noexcept + { + *this = *this + __m; + return *this; + } - constexpr year_month_day& - operator-=(const months& __m) noexcept - { - *this = *this - __m; - return *this; - } + template + constexpr year_month_day& + operator-=(const months& __m) noexcept + { + *this = *this - __m; + return *this; + } constexpr year_month_day& operator+=(const years& __y) noexcept @@ -2262,13 +2286,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept = default; - friend constexpr year_month_day - operator+(const year_month_day& __ymd, const months& __dm) noexcept - { return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); } + template + friend constexpr year_month_day + operator+(const year_month_day& __ymd, const months& __dm) noexcept + { return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); } - friend constexpr year_month_day - operator+(const months& __dm, const year_month_day& __ymd) noexcept - { return __ymd + __dm; } + template + friend constexpr year_month_day + operator+(const months& __dm, const year_month_day& __ymd) noexcept + { return __ymd + __dm; } friend constexpr year_month_day operator+(const year_month_day& __ymd, const years& __dy) noexcept @@ -2278,9 +2304,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator+(const years& __dy, const year_month_day& __ymd) noexcept { return __ymd + __dy; } - friend constexpr year_month_day - operator-(const year_month_day& __ymd, const months& __dm) noexcept - { return __ymd + -__dm; } + template + friend constexpr year_month_day + operator-(const year_month_day& __ymd, const months& __dm) noexcept + { return __ymd + -__dm; } friend constexpr year_month_day operator-(const year_month_day& __ymd, const years& __dy) noexcept @@ -2364,19 +2391,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_y{__y}, _M_mdl{__mdl} { } - constexpr year_month_day_last& - operator+=(const months& __m) noexcept - { - *this = *this + __m; - return *this; - } + template + constexpr year_month_day_last& + operator+=(const months& __m) noexcept + { + *this = *this + __m; + return *this; + } - constexpr year_month_day_last& - operator-=(const months& __m) noexcept - { - *this = *this - __m; - return *this; - } + template + constexpr year_month_day_last& + operator-=(const months& __m) noexcept + { + *this = *this - __m; + return *this; + } constexpr year_month_day_last& operator+=(const years& __y) noexcept @@ -2438,20 +2467,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const year_month_day_last& __y) noexcept = default; - friend constexpr year_month_day_last - operator+(const year_month_day_last& __ymdl, - const months& __dm) noexcept - { return (__ymdl.year() / __ymdl.month() + __dm) / last; } + template + friend constexpr year_month_day_last + operator+(const year_month_day_last& __ymdl, + const months& __dm) noexcept + { return (__ymdl.year() / __ymdl.month() + __dm) / last; } - friend constexpr year_month_day_last - operator+(const months& __dm, - const year_month_day_last& __ymdl) noexcept - { return __ymdl + __dm; } + template + friend constexpr year_month_day_last + operator+(const months& __dm, + const year_month_day_last& __ymdl) noexcept + { return __ymdl + __dm; } - friend constexpr year_month_day_last - operator-(const year_month_day_last& __ymdl, - const months& __dm) noexcept - { return __ymdl + -__dm; } + template + friend constexpr year_month_day_last + operator-(const year_month_day_last& __ymdl, + const months& __dm) noexcept + { return __ymdl + -__dm; } friend constexpr year_month_day_last operator+(const year_month_day_last& __ymdl, @@ -2544,19 +2576,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : year_month_weekday{sys_days{__dp.time_since_epoch()}} { } - constexpr year_month_weekday& - operator+=(const months& __m) noexcept - { - *this = *this + __m; - return *this; - } + template + constexpr year_month_weekday& + operator+=(const months& __m) noexcept + { + *this = *this + __m; + return *this; + } - constexpr year_month_weekday& - operator-=(const months& __m) noexcept - { - *this = *this - __m; - return *this; - } + template + constexpr year_month_weekday& + operator-=(const months& __m) noexcept + { + *this = *this - __m; + return *this; + } constexpr year_month_weekday& operator+=(const years& __y) noexcept @@ -2626,13 +2660,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && __x.weekday_indexed() == __y.weekday_indexed(); } - friend constexpr year_month_weekday - operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept - { return (__ymwd.year() / __ymwd.month() + __dm) / __ymwd.weekday_indexed(); } + template + friend constexpr year_month_weekday + operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept + { + return ((__ymwd.year() / __ymwd.month() + __dm) + / __ymwd.weekday_indexed()); + } - friend constexpr year_month_weekday - operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept - { return __ymwd + __dm; } + template + friend constexpr year_month_weekday + operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept + { return __ymwd + __dm; } friend constexpr year_month_weekday operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept @@ -2642,9 +2681,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept { return __ymwd + __dy; } - friend constexpr year_month_weekday - operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept - { return __ymwd + -__dm; } + template + friend constexpr year_month_weekday + operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept + { return __ymwd + -__dm; } friend constexpr year_month_weekday operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept @@ -2690,19 +2730,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl} { } - constexpr year_month_weekday_last& - operator+=(const months& __m) noexcept - { - *this = *this + __m; - return *this; - } + template + constexpr year_month_weekday_last& + operator+=(const months& __m) noexcept + { + *this = *this + __m; + return *this; + } - constexpr year_month_weekday_last& - operator-=(const months& __m) noexcept - { - *this = *this - __m; - return *this; - } + template + constexpr year_month_weekday_last& + operator-=(const months& __m) noexcept + { + *this = *this - __m; + return *this; + } constexpr year_month_weekday_last& operator+=(const years& __y) noexcept @@ -2759,15 +2801,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && __x.weekday_last() == __y.weekday_last(); } - friend constexpr year_month_weekday_last - operator+(const year_month_weekday_last& __ymwdl, - const months& __dm) noexcept - { return (__ymwdl.year() / __ymwdl.month() + __dm) / __ymwdl.weekday_last(); } + template + friend constexpr year_month_weekday_last + operator+(const year_month_weekday_last& __ymwdl, + const months& __dm) noexcept + { + return ((__ymwdl.year() / __ymwdl.month() + __dm) + / __ymwdl.weekday_last()); + } - friend constexpr year_month_weekday_last - operator+(const months& __dm, - const year_month_weekday_last& __ymwdl) noexcept - { return __ymwdl + __dm; } + template + friend constexpr year_month_weekday_last + operator+(const months& __dm, + const year_month_weekday_last& __ymwdl) noexcept + { return __ymwdl + __dm; } friend constexpr year_month_weekday_last operator+(const year_month_weekday_last& __ymwdl, @@ -2779,10 +2826,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const year_month_weekday_last& __ymwdl) noexcept { return __ymwdl + __dy; } - friend constexpr year_month_weekday_last - operator-(const year_month_weekday_last& __ymwdl, - const months& __dm) noexcept - { return __ymwdl + -__dm; } + template + friend constexpr year_month_weekday_last + operator-(const year_month_weekday_last& __ymwdl, + const months& __dm) noexcept + { return __ymwdl + -__dm; } friend constexpr year_month_weekday_last operator-(const year_month_weekday_last& __ymwdl, diff --git a/libstdc++-v3/testsuite/std/time/year_month/2.cc b/libstdc++-v3/testsuite/std/time/year_month/2.cc new file mode 100644 index 00000000000..36e14667547 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/year_month/2.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2020 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 +// . + +// Class template year_month [time.cal.year_month] + +#include + +constexpr void +constexpr_year_month_op_overload_disambiguation() +{ + using namespace std::chrono; + using decades = duration>; + static_assert(std::convertible_to + && std::convertible_to); + using ym = year_month; + + constexpr ym ym1 = 2015y/June; + static_assert(ym1 + decades{1} == 2025y/June); + static_assert(ym1 - decades{1} == 2005y/June); + static_assert(decades{1} + ym1 == 2025y/June); + static_assert((ym{ym1} += decades{1}) == 2025y/June); + static_assert((ym{ym1} -= decades{1}) == 2005y/June); +} diff --git a/libstdc++-v3/testsuite/std/time/year_month_day/2.cc b/libstdc++-v3/testsuite/std/time/year_month_day/2.cc new file mode 100644 index 00000000000..80d1f033c1d --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/year_month_day/2.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2020 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 +// . + +// Class template year_month_day [time.cal.year_month_day] + +#include + +constexpr void +constexpr_year_month_day_op_overload_disambiguation() +{ + using namespace std::chrono; + using decades = duration>; + static_assert(std::convertible_to + && std::convertible_to); + using ymd = year_month_day; + + constexpr ymd ymd1 = 2015y/June/15d; + static_assert(ymd1 + decades{1} == 2025y/June/15d); + static_assert(ymd1 - decades{1} == 2005y/June/15d); + static_assert(decades{1} + ymd1 == 2025y/June/15d); + static_assert((ymd{ymd1} += decades{1}) == 2025y/June/15d); + static_assert((ymd{ymd1} -= decades{1}) == 2005y/June/15d); +} diff --git a/libstdc++-v3/testsuite/std/time/year_month_day_last/2.cc b/libstdc++-v3/testsuite/std/time/year_month_day_last/2.cc new file mode 100644 index 00000000000..dadbd3c38b5 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/year_month_day_last/2.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2020 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 +// . + +// Class template year_month_day_last [time.cal.year_month_day_last] + +#include + +constexpr void +constexpr_year_month_day_last_op_overload_disambiguation() +{ + using namespace std::chrono; + using decades = duration>; + static_assert(std::convertible_to + && std::convertible_to); + using ymdl = year_month_day_last; + + constexpr ymdl ymdl1 = 2015y/June/last; + static_assert(ymdl1 + decades{1} == 2025y/June/last); + static_assert(ymdl1 - decades{1} == 2005y/June/last); + static_assert(decades{1} + ymdl1 == 2025y/June/last); + static_assert((ymdl{ymdl1} += decades{1}) == 2025y/June/last); + static_assert((ymdl{ymdl1} -= decades{1}) == 2005y/June/last); +} diff --git a/libstdc++-v3/testsuite/std/time/year_month_weekday/2.cc b/libstdc++-v3/testsuite/std/time/year_month_weekday/2.cc new file mode 100644 index 00000000000..6ddfb15b283 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/year_month_weekday/2.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2020 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 +// . + +// Class template year_month_weekday [time.cal.year_month_weekday] + +#include + +constexpr void +constexpr_year_month_weekday_op_overload_disambiguation() +{ + using namespace std::chrono; + using decades = duration>; + static_assert(std::convertible_to + && std::convertible_to); + using ymwd = year_month_weekday; + + constexpr ymwd ymwd1 = 2015y/June/Monday[3]; + static_assert(ymwd1 + decades{1} == 2025y/June/Monday[3]); + static_assert(ymwd1 - decades{1} == 2005y/June/Monday[3]); + static_assert(decades{1} + ymwd1 == 2025y/June/Monday[3]); + static_assert((ymwd{ymwd1} += decades{1}) == 2025y/June/Monday[3]); + static_assert((ymwd{ymwd1} -= decades{1}) == 2005y/June/Monday[3]); +} diff --git a/libstdc++-v3/testsuite/std/time/year_month_weekday_last/2.cc b/libstdc++-v3/testsuite/std/time/year_month_weekday_last/2.cc new file mode 100644 index 00000000000..170b5a45ad6 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/year_month_weekday_last/2.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2020 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 +// . + +// Class template year_month_weekday_last [time.cal.year_month_weekday_last] + +#include + +constexpr void +constexpr_year_month_weekday_last_op_overload_disambiguation() +{ + using namespace std::chrono; + using decades = duration>; + static_assert(std::convertible_to + && std::convertible_to); + using ymwdl = year_month_weekday_last; + + constexpr ymwdl ymwdl1 = 2015y/June/Monday[last]; + static_assert(ymwdl1 + decades{1} == 2025y/June/Monday[last]); + static_assert(ymwdl1 - decades{1} == 2005y/June/Monday[last]); + static_assert(decades{1} + ymwdl1 == 2025y/June/Monday[last]); + static_assert((ymwdl{ymwdl1} += decades{1}) == 2025y/June/Monday[last]); + static_assert((ymwdl{ymwdl1} -= decades{1}) == 2005y/June/Monday[last]); +}