blob: 7ee71a20bcd369269457e5634e0b4d94c1bb03c2 [file] [log] [blame]
// Copyright (C) 2020-2021 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/>.
// { dg-do compile { target c++11 } }
// Test the changes introduced by P0548R1 "common_type and duration".
// Specifically, duration<R,P>::period should be the reduced ratio,
// and common_type<D1, D2>::type should be a duration using the
// reduced ratio.
#include <chrono>
using std::chrono::duration;
using std::ratio;
using std::common_type;
using std::is_same;
void
test01()
{
using D1 = duration<int, ratio<10, 10>>;
static_assert( is_same<D1::period, ratio<1, 1>>::value,
"duration<R, P>::period is P::type, not P" );
using C1 = common_type<D1>::type;
static_assert( is_same<C1, duration<int, D1::period>>::value,
"common_type_t<duration<R, P1> is duration<R, P1::type>");
static_assert( is_same<common_type<D1, D1>::type, C1>::value,
"common_type_t<D1, D1> is common_type_t<D1>" );
static_assert( is_same<common_type<D1, D1, D1>::type, C1>::value,
"common_type_t<D1, D1, D1> is common_type_t<D1>" );
using D2 = duration<int, ratio<30, 15>>;
static_assert( is_same<D2::period, ratio<2, 1>>::value,
"duration<R, P2>::period is P2::type, not P2" );
using C2 = common_type<D2>::type;
static_assert( is_same<C2, duration<int, D2::period>>::value,
"common_type_t<duration<R, P2> is duration<R, P2::type>");
static_assert( is_same<common_type<D2, D2>::type, C2>::value,
"common_type_t<D2, D2> is common_type_t<D2>" );
static_assert( is_same<common_type<D2, D2, D2>::type, C2>::value,
"common_type_t<D2, D2, D2> is common_type_t<D2>" );
using D3 = duration<int, ratio<4, 12>>;
static_assert( is_same<D3::period, ratio<1, 3>>::value,
"duration<R, P3>::period is P3::type, not P3" );
using C3 = common_type<D3>::type;
static_assert( is_same<C3, duration<int, D3::period>>::value,
"common_type_t<duration<R, P3> is duration<R, P3::type>");
static_assert( is_same<common_type<D3, D3>::type, C3>::value,
"common_type_t<D3, D3> is common_type_t<D3>" );
static_assert( is_same<common_type<D3, D3, D3>::type, C3>::value,
"common_type_t<D3, D3, D3> is common_type_t<D3>" );
using C12 = common_type<D1, D2>::type;
static_assert( is_same<C12, C1>::value,
"common_type_t<D1, D2> uses the right period" );
using C21 = common_type<D2, D1>::type;
static_assert( is_same<C21, C12>::value,
"common_type_t<D1, D2> is common_type_t<D2, D1>" );
using C13 = common_type<D1, D3>::type;
static_assert( is_same<C13, C3>::value,
"common_type_t<D1, D3> uses the right period" );
using C31 = common_type<D3, D1>::type;
static_assert( is_same<C31, C13>::value,
"common_type_t<D1, D3> is common_type_t<D3, D1>" );
using C23 = common_type<D2, D3>::type;
static_assert( is_same<C23, C3>::value,
"common_type_t<D2, D3> uses the right period" );
using C32 = common_type<D3, D2>::type;
static_assert( is_same<C32, C23>::value,
"common_type_t<D2, D3> is common_type_t<D3, D2>" );
using C123 = common_type<D1, D2, D3>::type;
static_assert( is_same<C123, C3>::value,
"common_type of three durations uses the right period" );
using C132 = common_type<D1, D3, D2>::type;
static_assert( is_same<C132, C123>::value, "order doesn't matter" );
using C312 = common_type<D3, D1, D2>::type;
static_assert( is_same<C312, C123>::value, "order doesn't matter" );
using C321 = common_type<D3, D2, D1>::type;
static_assert( is_same<C321, C123>::value, "order doesn't matter" );
using C = common_type<duration<short, ratio<1, 3>>,
duration<unsigned, ratio<1, 2>>>::type;
static_assert( is_same<C, duration<common_type<short, unsigned>::type,
ratio<1, 6>>>::value, "" );
}
void
test02()
{
using D1 = duration<int, ratio<10, 10>>;
D1 d1;
static_assert( is_same<decltype(+d1), common_type<D1>::type>::value,
"unary + returns the reduced duration" );
static_assert( is_same<decltype(-d1), common_type<D1>::type>::value,
"unary - returns the reduced duration" );
using D2 = duration<int, ratio<30, 15>>;
D2 d2;
static_assert( is_same<decltype(+d2), common_type<D2>::type>::value,
"unary + returns the reduced duration" );
static_assert( is_same<decltype(-d2), common_type<D2>::type>::value,
"unary - returns the reduced duration" );
using D3 = duration<int, ratio<4, 12>>;
D3 d3;
static_assert( is_same<decltype(+d3), common_type<D3>::type>::value,
"unary + returns the reduced duration" );
static_assert( is_same<decltype(-d3), common_type<D3>::type>::value,
"unary - returns the reduced duration" );
}
template<typename T>
struct Number
{
explicit
Number(T t = 0) : i(t)
{ }
template<typename U, bool B = std::is_convertible<U, T>::value,
typename = typename std::enable_if<B>::type>
explicit
Number(Number<U> n) : i(n.i)
{ }
T i = 0;
Number& operator+=(Number n) { i += n.i; return *this; }
Number& operator-=(Number n) { i -= n.i; return *this; }
Number& operator*=(Number n) { i *= n.i; return *this; }
Number& operator/=(Number n) { i /= n.i; return *this; }
Number& operator%=(Number n) { i %= n.i; return *this; }
Number operator+(Number n) { return Number{ i + n.i }; }
Number operator-(Number n) { return Number{ i - n.i }; }
Number operator*(Number n) { return Number{ i * n.i }; }
Number operator/(Number n) { return Number{ i / n.i }; }
Number operator%(Number n) { return Number{ i % n.i }; }
};
namespace std
{
// Specialise common_type to give a different type
template<>
struct common_type<Number<int>, Number<int>>
{ using type = Number<long>; };
}
void
test03()
{
using D4 = duration<Number<int>, ratio<49, 21>>;
static_assert( is_same<common_type<D4>::type,
duration<Number<long>, ratio<7, 3>>>::value,
"common_type_t<duration<R,P>> uses common_type_t<R>" );
D4 d4;
static_assert( is_same<decltype(+d4), common_type<D4>::type>::value,
"unary + returns type with common_type_t<D4::rep> as rep" );
static_assert( is_same<decltype(-d4), common_type<D4>::type>::value,
"unary - returns type with common_type_t<D4::rep> as rep" );
}