11c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow//===----------------------------------------------------------------------===// 21c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// 31c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// The LLVM Compiler Infrastructure 41c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// 51c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// This file is dual licensed under the MIT and the University of Illinois Open 61c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// Source Licenses. See LICENSE.TXT for details. 71c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// 81c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow//===----------------------------------------------------------------------===// 9e33c0b01f892f8919f66a066a9c4064010104e49Stephan T. Lavavej// 101c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// UNSUPPORTED: c++98, c++03, c++11, c++14 111b8fc14abc2ac3bbef8a135fbc4ad2264493edc6Marshall Clow 121c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// <numeric> 131c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 141c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// template<class _M, class _N> 151c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow// constexpr common_type_t<_M,_N> gcd(_M __m, _N __n) 161c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 171c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow#include <numeric> 181c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow#include <cassert> 191c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow#include <cstdlib> // for rand() 201c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow#include <iostream> 211c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 221c1e91d9a35e51778b49a73b39012768770cd482Marshall Clowconstexpr struct { 231c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow int x; 241c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow int y; 251c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow int expect; 261c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow} Cases[] = { 271c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow {0, 0, 0}, 281c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow {1, 0, 1}, 291c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow {0, 1, 1}, 301c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow {1, 1, 1}, 311c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow {2, 3, 1}, 321c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow {2, 4, 2}, 331c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow {36, 17, 1}, 341c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow {36, 18, 18} 351c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow}; 361c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 371c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 381c1e91d9a35e51778b49a73b39012768770cd482Marshall Clowtemplate <typename Input1, typename Input2, typename Output> 391c1e91d9a35e51778b49a73b39012768770cd482Marshall Clowconstexpr bool test0(Input1 in1, Input2 in2, Output out) 401c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow{ 411c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert((std::is_same<Output, decltype(std::gcd(in1, in2))>::value), "" ); 421c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert((std::is_same<Output, decltype(std::gcd(in2, in1))>::value), "" ); 431c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow return out == std::gcd(in1, in2) ? true : (std::abort(), false); 441c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow} 451c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 461c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 471c1e91d9a35e51778b49a73b39012768770cd482Marshall Clowtemplate <typename Input1, typename Input2 = Input1> 480e5ebbc77c3c2cfd7d835fcfe40fcb65df0c5598Eric Fiselierconstexpr bool do_test(int = 0) 491c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow{ 501c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow using S1 = typename std::make_signed<Input1>::type; 511c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow using S2 = typename std::make_signed<Input2>::type; 521c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow using U1 = typename std::make_unsigned<Input1>::type; 531c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow using U2 = typename std::make_unsigned<Input2>::type; 541c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow bool accumulate = true; 551c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow for (auto TC : Cases) { 561c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow { // Test with two signed types 571c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow using Output = std::common_type_t<S1, S2>; 581c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S1, S2, Output>(TC.x, TC.y, TC.expect); 591c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S1, S2, Output>(-TC.x, TC.y, TC.expect); 601c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S1, S2, Output>(TC.x, -TC.y, TC.expect); 611c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S1, S2, Output>(-TC.x, -TC.y, TC.expect); 621c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S2, S1, Output>(TC.x, TC.y, TC.expect); 631c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S2, S1, Output>(-TC.x, TC.y, TC.expect); 641c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S2, S1, Output>(TC.x, -TC.y, TC.expect); 651c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S2, S1, Output>(-TC.x, -TC.y, TC.expect); 661c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow } 671c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow { // test with two unsigned types 681c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow using Output = std::common_type_t<U1, U2>; 691c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<U1, U2, Output>(TC.x, TC.y, TC.expect); 701c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<U2, U1, Output>(TC.x, TC.y, TC.expect); 711c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow } 721c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow { // Test with mixed signs 731c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow using Output = std::common_type_t<S1, U2>; 741c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S1, U2, Output>(TC.x, TC.y, TC.expect); 751c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<U2, S1, Output>(TC.x, TC.y, TC.expect); 761c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S1, U2, Output>(-TC.x, TC.y, TC.expect); 771c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<U2, S1, Output>(TC.x, -TC.y, TC.expect); 781c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow } 791c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow { // Test with mixed signs 801c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow using Output = std::common_type_t<S2, U1>; 811c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S2, U1, Output>(TC.x, TC.y, TC.expect); 821c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<U1, S2, Output>(TC.x, TC.y, TC.expect); 831c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<S2, U1, Output>(-TC.x, TC.y, TC.expect); 841c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow accumulate &= test0<U1, S2, Output>(TC.x, -TC.y, TC.expect); 851c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow } 861c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow } 871c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow return accumulate; 881c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow} 891c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 901c1e91d9a35e51778b49a73b39012768770cd482Marshall Clowint main() 911c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow{ 921c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow auto non_cce = std::rand(); // a value that can't possibly be constexpr 931c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 941c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<signed char>(), ""); 951c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<short>(), ""); 961c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<int>(), ""); 971c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<long>(), ""); 981c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<long long>(), ""); 991c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 1001c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert(do_test<signed char>(non_cce)); 1011c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert(do_test<short>(non_cce)); 1021c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert(do_test<int>(non_cce)); 1031c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert(do_test<long>(non_cce)); 1041c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert(do_test<long long>(non_cce)); 1051c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 1061c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test< int8_t>(), ""); 1071c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<int16_t>(), ""); 1081c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<int32_t>(), ""); 1091c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<int64_t>(), ""); 1101c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 1111c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert(do_test< int8_t>(non_cce)); 1121c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert(do_test<int16_t>(non_cce)); 1131c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert(do_test<int32_t>(non_cce)); 1141c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert(do_test<int64_t>(non_cce)); 1151c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 1161c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<signed char, int>(), ""); 1171c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<int, signed char>(), ""); 1181c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<short, int>(), ""); 1191c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<int, short>(), ""); 1201c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<int, long>(), ""); 1211c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<long, int>(), ""); 1221c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<int, long long>(), ""); 1231c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow static_assert(do_test<long long, int>(), ""); 1241c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow 1251c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert((do_test<signed char, int>(non_cce))); 1261c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert((do_test<int, signed char>(non_cce))); 1271c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert((do_test<short, int>(non_cce))); 1281c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert((do_test<int, short>(non_cce))); 1291c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert((do_test<int, long>(non_cce))); 1301c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert((do_test<long, int>(non_cce))); 1311c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert((do_test<int, long long>(non_cce))); 1321c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow assert((do_test<long long, int>(non_cce))); 13324597f254dc229da1aa50258b7f444a0e479460fMarshall Clow 13424597f254dc229da1aa50258b7f444a0e479460fMarshall Clow// LWG#2837 13524597f254dc229da1aa50258b7f444a0e479460fMarshall Clow { 13624597f254dc229da1aa50258b7f444a0e479460fMarshall Clow auto res = std::gcd((int64_t)1234, (int32_t)-2147483648); 13724597f254dc229da1aa50258b7f444a0e479460fMarshall Clow static_assert( std::is_same<decltype(res), std::common_type<int64_t, int32_t>::type>::value, ""); 13824597f254dc229da1aa50258b7f444a0e479460fMarshall Clow assert(res == 2); 13924597f254dc229da1aa50258b7f444a0e479460fMarshall Clow } 1401c1e91d9a35e51778b49a73b39012768770cd482Marshall Clow} 141