// 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" );
}
