From patchwork Tue Aug 25 19:47:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1351421 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=jCbk6nwl; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Bbffr1tyYz9sRK for ; Wed, 26 Aug 2020 05:48:04 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 197223857001; Tue, 25 Aug 2020 19:48:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 197223857001 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1598384882; bh=yhygM5fE1a1ixD2iEJ/VC+5LMk4U21tRR5wfIgZCfu8=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=jCbk6nwl7PDWjC5Yh57k2XhZM14yTKVR4qNRUVhJG6sU3lo7z0Jbix0fHqCXiDOzF xMZdGjBiwPLkcfr1+nfv3MewvrBvDbYw/XHAnicCheiLClnrHYjMbzoCoBmtT79oIk xE6CO5WpEj9MRU5tPPkbCiGdpNs+bxixJ9YCDGhA= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by sourceware.org (Postfix) with ESMTP id 408AD385783E for ; Tue, 25 Aug 2020 19:47:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 408AD385783E Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-168-bHECjFp4OYepVOHuBtFtow-1; Tue, 25 Aug 2020 15:47:45 -0400 X-MC-Unique: bHECjFp4OYepVOHuBtFtow-1 Received: by mail-qv1-f70.google.com with SMTP id h6so9511271qvz.14 for ; Tue, 25 Aug 2020 12:47:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=yhygM5fE1a1ixD2iEJ/VC+5LMk4U21tRR5wfIgZCfu8=; b=rmkevZgwam+ZEMQvRPTu4PR2x5k6VVmV8Ajj1ZzmdE/QwQPx8+NCx+aHwkadwlUQYC o6AzUae+eyxXWGeqpLluQZXHcoaLYDD+7EAVG9gKS160nVXsd+JiBRG7FOR3WNO9i82O Gn51MMkF37PyqGa2j+fUk/tatgQA54uMmtXuayb/M5nx0ihgjgZ1cHDmeDDOAit6ofRF GiMSz1DZG2i32n0JPD46rMuSsYH3+TGSkRoQLg0fhgNnQinV7ei4JNWDoDcN55O+4ry/ E/K7yxglRQ+3pUEi0E3WbwtdRj8DfbxsEut8WDo+cfq1ibz3D9qtpKJ7/VLIfQFQzzKK BgAA== X-Gm-Message-State: AOAM532/IP9k1ltn1OMCUe0nxulVXWH+7dvecqnniK3opO5ay27yg/fv u3BLR/aCwdUcIgCPFPSyb/feevAj2PQOsjqWRXSAN3b//jQBKziqaLdalV4gRJNCiMgjHoAkYMi 6eGOWWiM2o+prxf1i3g== X-Received: by 2002:ac8:5504:: with SMTP id j4mr11231981qtq.357.1598384861552; Tue, 25 Aug 2020 12:47:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzInSA2ABY+4qmKAVD4Mi73fQ8qnH74349aOOvYgRWwWYDoO5AmV44emWIC97M4EKa8mZAHoA== X-Received: by 2002:ac8:5504:: with SMTP id j4mr11231960qtq.357.1598384861090; Tue, 25 Aug 2020 12:47:41 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id 84sm61593qkm.103.2020.08.25.12.47.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Aug 2020 12:47:40 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] libstdc++: Fix operator overload resolution for calendar types Date: Tue, 25 Aug 2020 15:47:36 -0400 Message-Id: <20200825194736.425343-1-ppalka@redhat.com> X-Mailer: git-send-email 2.28.0.337.ge9b77c84a0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-16.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Cc: libstdc++@gcc.gnu.org Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" My original patch that implemented the calendar type operations failed to enforce a constraint on some of the addition/subtraction operator overloads that take a 'months' argument: 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 when the given duration is convertible to both 'months' and to 'years'. The correct behavior here in light of this constraint is to select the (more efficient) 'years'-taking overload, but we currently emit an ambiguous overload error. This patch follows the approach taken in the 'date' library and defines the constrained 'months'-taking operator overloads as function templates, so that we break such a implicit-conversion tie by selecting the non-template 'years'-taking overload. Tested on x86_64-pc-linux-gnu, does this look OK to commit? (The below diff is generated with --ignore-space-change for easier review. In the actual patch, the function templates are indented two extra spaces after the template parameter list.) libstdc++-v3/ChangeLog: * include/std/chrono (__detail::__unspecified_month_disambuator): Define. (year_month::operator+=): Turn the 'months'-taking overload into a function template, so that the 'years'-taking overload is selected in case of an equally-ranked implicit conversion sequence 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. --- libstdc++-v3/include/std/chrono | 52 ++++++++++++++++++- .../testsuite/std/time/year_month/2.cc | 40 ++++++++++++++ .../testsuite/std/time/year_month_day/2.cc | 40 ++++++++++++++ .../std/time/year_month_day_last/2.cc | 40 ++++++++++++++ .../std/time/year_month_weekday/2.cc | 40 ++++++++++++++ .../std/time/year_month_weekday_last/2.cc | 40 ++++++++++++++ 6 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 libstdc++-v3/testsuite/std/time/year_month/2.cc create mode 100644 libstdc++-v3/testsuite/std/time/year_month_day/2.cc create mode 100644 libstdc++-v3/testsuite/std/time/year_month_day_last/2.cc create mode 100644 libstdc++-v3/testsuite/std/time/year_month_weekday/2.cc create mode 100644 libstdc++-v3/testsuite/std/time/year_month_weekday_last/2.cc diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index 3cc1438a7b6..0e272c3da58 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'-taking + // 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 defining the 'months'-taking overloads as + // function templates (with a dummy defaulted template parameter), so that + // overload resolution doesn't select the 'months'-taking 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,6 +2085,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION month() const noexcept { return _M_m; } + template constexpr year_month& operator+=(const months& __dm) noexcept { @@ -2075,6 +2093,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + template constexpr year_month& operator-=(const months& __dm) noexcept { @@ -2108,6 +2127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator<=>(const year_month& __x, const year_month& __y) noexcept = default; + template friend constexpr year_month operator+(const year_month& __ym, const months& __dm) noexcept { @@ -2120,10 +2140,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __y / __m; } + template friend constexpr year_month operator+(const months& __dm, const year_month& __ym) noexcept { return __ym + __dm; } + template friend constexpr year_month operator-(const year_month& __ym, const months& __dm) noexcept { return __ym + -__dm; } @@ -2200,6 +2222,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : year_month_day(sys_days{__dp.time_since_epoch()}) { } + template constexpr year_month_day& operator+=(const months& __m) noexcept { @@ -2207,6 +2230,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + template constexpr year_month_day& operator-=(const months& __m) noexcept { @@ -2262,10 +2286,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept = default; + template 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 months& __dm, const year_month_day& __ymd) noexcept { return __ymd + __dm; } @@ -2278,6 +2304,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator+(const years& __dy, const year_month_day& __ymd) noexcept { return __ymd + __dy; } + template friend constexpr year_month_day operator-(const year_month_day& __ymd, const months& __dm) noexcept { return __ymd + -__dm; } @@ -2364,6 +2391,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_y{__y}, _M_mdl{__mdl} { } + template constexpr year_month_day_last& operator+=(const months& __m) noexcept { @@ -2371,6 +2399,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + template constexpr year_month_day_last& operator-=(const months& __m) noexcept { @@ -2438,16 +2467,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const year_month_day_last& __y) noexcept = default; + 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; } + template 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 year_month_day_last& __ymdl, const months& __dm) noexcept @@ -2544,6 +2576,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : year_month_weekday{sys_days{__dp.time_since_epoch()}} { } + template constexpr year_month_weekday& operator+=(const months& __m) noexcept { @@ -2551,6 +2584,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + template constexpr year_month_weekday& operator-=(const months& __m) noexcept { @@ -2626,10 +2660,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && __x.weekday() == __y.weekday(); } + 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(); } + { + return ((__ymwd.year() / __ymwd.month() + __dm) + / __ymwd.weekday_indexed()); + } + template friend constexpr year_month_weekday operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept { return __ymwd + __dm; } @@ -2642,6 +2681,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept { return __ymwd + __dy; } + template friend constexpr year_month_weekday operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept { return __ymwd + -__dm; } @@ -2690,6 +2730,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl} { } + template constexpr year_month_weekday_last& operator+=(const months& __m) noexcept { @@ -2697,6 +2738,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + template constexpr year_month_weekday_last& operator-=(const months& __m) noexcept { @@ -2759,11 +2801,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && __x.weekday_last() == __y.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(); } + { + return ((__ymwdl.year() / __ymwdl.month() + __dm) + / __ymwdl.weekday_last()); + } + template friend constexpr year_month_weekday_last operator+(const months& __dm, const year_month_weekday_last& __ymwdl) noexcept @@ -2779,6 +2826,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const year_month_weekday_last& __ymwdl) noexcept { return __ymwdl + __dy; } + template friend constexpr year_month_weekday_last operator-(const year_month_weekday_last& __ymwdl, const months& __dm) noexcept 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]); +}