mclow.lists created this revision.
mclow.lists added reviewers: EricWF, howard.hinnant.
mclow.lists added a subscriber: cfe-commits.

These are probably going to end up in C++17 as well.

This is a straight addition; no changes to existing code.

http://reviews.llvm.org/D21343

Files:
  include/experimental/numeric
  test/std/experimental/numeric/numeric.ops.overview/nothing_to_do.pass.cpp
  test/std/experimental/numeric/numeric.ops/nothing_to_do.pass.cpp
  
test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.not_integral1.fail.cpp
  
test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.not_integral2.fail.cpp
  test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.pass.cpp
  
test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.not_integral1.fail.cpp
  
test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.not_integral2.fail.cpp
  test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.pass.cpp

Index: test/std/experimental/numeric/numeric.ops.overview/nothing_to_do.pass.cpp
===================================================================
--- test/std/experimental/numeric/numeric.ops.overview/nothing_to_do.pass.cpp
+++ test/std/experimental/numeric/numeric.ops.overview/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <experimental/numeric>
+
+int main () {}
Index: test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.pass.cpp
===================================================================
--- test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.pass.cpp
+++ test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.pass.cpp
@@ -0,0 +1,252 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <numeric>
+
+// template<class _M, class _N>
+// constexpr common_type_t<_M,_N> gcd(_M __m, _N __n)
+
+#include <experimental/numeric>
+#include <cassert>
+#include <iostream>
+
+template <typename Input1, typename Input2, typename Output>
+void test0(Input1 in1, Input2 in2, Output out)
+{
+    static_assert((std::is_same<Output, decltype(std::experimental::lcm(Input1(0), Input2(0)))>::value), "" );
+    assert(out == std::experimental::lcm(in1, in2));
+}
+
+
+template <typename Input>
+void test_same_signed()
+{
+    static_assert(( std::is_signed<Input>::value), "" );
+
+//  Returns: zero when either m or n is zero.
+    test0<Input, Input, Input>( 0,  0,  0);
+    test0<Input, Input, Input>( 1,  0,  0);
+    test0<Input, Input, Input>( 0,  1,  0);
+    test0<Input, Input, Input>(-1,  0,  0);
+    test0<Input, Input, Input>( 0, -1,  0);
+
+//  Otherwise, returns the least common multiple of |m| and |n|.
+    test0<Input, Input, Input>(  1,   1,  1);
+    test0<Input, Input, Input>(  2,   3,  6);
+    test0<Input, Input, Input>(  2,   4,  4);
+    test0<Input, Input, Input>(  3,  17, 51);
+    test0<Input, Input, Input>( 36,  18, 36);
+    
+    test0<Input, Input, Input>( -1,   1,  1);
+    test0<Input, Input, Input>( -2,   3,  6);
+    test0<Input, Input, Input>( -2,   4,  4);
+    test0<Input, Input, Input>( -3,  17, 51);
+    test0<Input, Input, Input>(-36,  18, 36);
+
+    test0<Input, Input, Input>(  1,  -1,  1);
+    test0<Input, Input, Input>(  2,  -3,  6);
+    test0<Input, Input, Input>(  2,  -4,  4);
+    test0<Input, Input, Input>(  3, -17, 51);
+    test0<Input, Input, Input>( 36, -18, 36);
+    
+    test0<Input, Input, Input>( -1,  -1,  1);
+    test0<Input, Input, Input>( -2,  -3,  6);
+    test0<Input, Input, Input>( -2,  -4,  4);
+    test0<Input, Input, Input>( -3, -17, 51);
+    test0<Input, Input, Input>(-36, -18, 36);
+}
+
+template <typename Input>
+void test_same_unsigned()
+{
+    static_assert((!std::is_signed<Input>::value), "" );
+
+//  Returns: zero when either m or n is zero.
+    test0<Input, Input, Input>( 0,  0,  0);
+    test0<Input, Input, Input>( 1,  0,  0);
+    test0<Input, Input, Input>( 0,  1,  0);
+
+//  Otherwise, returns the least common multiple of |m| and |n|.
+    test0<Input, Input, Input>(  1,   1,  1);
+    test0<Input, Input, Input>(  2,   3,  6);
+    test0<Input, Input, Input>(  2,   4,  4);
+    test0<Input, Input, Input>(  3,  17, 51);
+    test0<Input, Input, Input>( 36,  18, 36);
+}
+
+
+template <typename Input1, typename Input2, typename Output>
+void test_different_signed()
+{
+    static_assert(( std::is_signed<Input1>::value), "" );
+    static_assert(( std::is_signed<Input2>::value), "" );
+
+//  Returns: zero when either m or n is zero.
+    test0<Input1, Input2, Output>( 0,  0,  0);
+    test0<Input1, Input2, Output>( 1,  0,  0);
+    test0<Input1, Input2, Output>( 0,  1,  0);
+    test0<Input1, Input2, Output>(-1,  0,  0);
+    test0<Input1, Input2, Output>( 0, -1,  0);
+
+//  Otherwise, returns the least common multiple of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,   1,  1);
+    test0<Input1, Input2, Output>(  2,   3,  6);
+    test0<Input1, Input2, Output>(  2,   4,  4);
+    test0<Input1, Input2, Output>(  3,  17, 51);
+    test0<Input1, Input2, Output>( 36,  18, 36);
+
+    test0<Input1, Input2, Output>( -1,   1,  1);
+    test0<Input1, Input2, Output>( -2,   3,  6);
+    test0<Input1, Input2, Output>( -2,   4,  4);
+    test0<Input1, Input2, Output>( -3,  17, 51);
+    test0<Input1, Input2, Output>(-36,  18, 36);
+    
+    test0<Input1, Input2, Output>(  1,  -1,  1);
+    test0<Input1, Input2, Output>(  2,  -3,  6);
+    test0<Input1, Input2, Output>(  2,  -4,  4);
+    test0<Input1, Input2, Output>(  3, -17, 51);
+    test0<Input1, Input2, Output>( 36, -18, 36);
+
+    test0<Input1, Input2, Output>( -1,  -1,  1);
+    test0<Input1, Input2, Output>( -2,  -3,  6);
+    test0<Input1, Input2, Output>( -2,  -4,  4);
+    test0<Input1, Input2, Output>( -3, -17, 51);
+    test0<Input1, Input2, Output>(-36, -18, 36);
+}
+
+template <typename Input1, typename Input2, typename Output>
+void test_different_unsigned()
+{
+    static_assert((!std::is_signed<Input1>::value), "" );
+    static_assert((!std::is_signed<Input2>::value), "" );
+
+//  Returns: zero when either m or n is zero.
+    test0<Input1, Input2, Output>( 0,  0,  0);
+    test0<Input1, Input2, Output>( 1,  0,  0);
+    test0<Input1, Input2, Output>( 0,  1,  0);
+
+//  Otherwise, returns the least common multiple of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,   1,  1);
+    test0<Input1, Input2, Output>(  2,   3,  6);
+    test0<Input1, Input2, Output>(  2,   4,  4);
+    test0<Input1, Input2, Output>(  3,  17, 51);
+    test0<Input1, Input2, Output>( 36,  18, 36);
+}
+
+template <typename Input1, typename Input2, typename Output>
+void test_mixed_first_signed()
+{
+    static_assert(( std::is_signed<Input1>::value), "" );
+    static_assert((!std::is_signed<Input2>::value), "" );
+
+//  Returns: zero when either m or n is zero.
+    test0<Input1, Input2, Output>( 0,  0,  0);
+    test0<Input1, Input2, Output>( 1,  0,  0);
+    test0<Input1, Input2, Output>(-1,  0,  0);
+    test0<Input1, Input2, Output>( 0,  1,  0);
+
+//  Otherwise, returns the least common multiple of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,   1,  1);
+    test0<Input1, Input2, Output>(  2,   3,  6);
+    test0<Input1, Input2, Output>(  2,   4,  4);
+    test0<Input1, Input2, Output>(  3,  17, 51);
+    test0<Input1, Input2, Output>( 36,  18, 36);
+
+    test0<Input1, Input2, Output>( -1,   1,  1);
+    test0<Input1, Input2, Output>( -2,   3,  6);
+    test0<Input1, Input2, Output>( -2,   4,  4);
+    test0<Input1, Input2, Output>( -3,  17, 51);
+    test0<Input1, Input2, Output>(-36,  18, 36);
+}
+
+template <typename Input1, typename Input2, typename Output>
+void test_mixed_second_signed()
+{
+    static_assert((!std::is_signed<Input1>::value), "" );
+    static_assert(( std::is_signed<Input2>::value), "" );
+
+//  Returns: zero when either m or n is zero.
+    test0<Input1, Input2, Output>( 0,  0,  0);
+    test0<Input1, Input2, Output>( 1,  0,  0);
+    test0<Input1, Input2, Output>( 0,  1,  0);
+    test0<Input1, Input2, Output>( 0, -1,  0);
+
+//  Otherwise, returns the least common multiple of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,   1,  1);
+    test0<Input1, Input2, Output>(  2,   3,  6);
+    test0<Input1, Input2, Output>(  2,   4,  4);
+    test0<Input1, Input2, Output>(  3,  17, 51);
+    test0<Input1, Input2, Output>( 36,  18, 36);
+
+//  Otherwise, returns the least common multiple of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,  -1,  1);
+    test0<Input1, Input2, Output>(  2,  -3,  6);
+    test0<Input1, Input2, Output>(  2,  -4,  4);
+    test0<Input1, Input2, Output>(  3, -17, 51);
+    test0<Input1, Input2, Output>( 36, -18, 36);
+}
+
+int main()
+{
+    test_same_signed<signed char>();
+    test_same_signed<short>();
+    test_same_signed<int>();
+    test_same_signed<long>();
+    test_same_signed<long long>();
+
+    test_same_signed< int8_t>();
+    test_same_signed<int16_t>();
+    test_same_signed<int32_t>();
+    test_same_signed<int64_t>();
+
+    test_same_unsigned<unsigned char>();
+    test_same_unsigned<unsigned short>();
+    test_same_unsigned<unsigned int>();
+    test_same_unsigned<unsigned long>();
+    test_same_unsigned<unsigned long long>();
+    test_same_unsigned<std::size_t>();
+
+    test_same_unsigned< uint8_t>();
+    test_same_unsigned<uint16_t>();
+    test_same_unsigned<uint32_t>();
+    test_same_unsigned<uint64_t>();
+    
+    test_different_signed<signed char, int, int>();
+    test_different_signed<int, signed char, int>();
+    test_different_signed<short, int, int>();
+    test_different_signed<int, short, int>();
+    test_different_signed<int, long, long>();
+    test_different_signed<long, int, long>();
+    test_different_signed<int, long long, long long>();
+    test_different_signed<long long, int, long long>();
+    
+    test_different_unsigned<unsigned char, unsigned int, unsigned int>();
+    test_different_unsigned<unsigned int, unsigned char, unsigned int>();
+    test_different_unsigned<unsigned short, unsigned int, unsigned int>();
+    test_different_unsigned<unsigned int, unsigned short, unsigned int>();
+    test_different_unsigned<unsigned int, unsigned long, unsigned long>();
+    test_different_unsigned<unsigned long, unsigned int, unsigned long>();
+    test_different_unsigned<unsigned int, unsigned long long, unsigned long long>();
+    test_different_unsigned<unsigned long long, unsigned int, unsigned long long>();
+
+    test_mixed_first_signed<signed char, unsigned char, int>();
+    test_mixed_first_signed<int, unsigned char, int>();
+    test_mixed_first_signed<int, unsigned int, unsigned int>();
+    test_mixed_first_signed<long, unsigned int, long>();
+    test_mixed_first_signed<long long, unsigned int, long long>();
+    test_mixed_first_signed<long long, unsigned long, unsigned long long>();
+
+    test_mixed_second_signed<unsigned char, signed char, int>();
+    test_mixed_second_signed<unsigned char, int, int>();
+    test_mixed_second_signed<unsigned int, int, unsigned int>();
+    test_mixed_second_signed<unsigned int, long, long>();
+    test_mixed_second_signed<unsigned int, long long, long long>();
+    test_mixed_second_signed<unsigned long, long long, unsigned long long>();
+}
Index: test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.not_integral2.fail.cpp
===================================================================
--- test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.not_integral2.fail.cpp
+++ test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.not_integral2.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <numeric>
+
+// template<class _M, class _N>
+// constexpr common_type_t<_M,_N> lcm(_M __m, _N __n)
+
+// Remarks: If either M or N is not an integer type, the program is ill-formed.
+
+#include <experimental/numeric>
+
+
+int main()
+{
+    std::experimental::lcm(4, 6.0);
+}
Index: test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.not_integral1.fail.cpp
===================================================================
--- test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.not_integral1.fail.cpp
+++ test/std/experimental/numeric/numeric.ops/numeric.ops.lcm/lcm.not_integral1.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <numeric>
+
+// template<class _M, class _N>
+// constexpr common_type_t<_M,_N> lcm(_M __m, _N __n)
+
+// Remarks: If either M or N is not an integer type, the program is ill-formed.
+
+#include <experimental/numeric>
+
+
+int main()
+{
+    std::experimental::lcm(2.0, 4);
+}
Index: test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.pass.cpp
===================================================================
--- test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.pass.cpp
+++ test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.pass.cpp
@@ -0,0 +1,251 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <numeric>
+
+// template<class _M, class _N>
+// constexpr common_type_t<_M,_N> gcd(_M __m, _N __n)
+
+#include <experimental/numeric>
+#include <cassert>
+#include <iostream>
+
+template <typename Input1, typename Input2, typename Output>
+void test0(Input1 in1, Input2 in2, Output out)
+{
+    static_assert((std::is_same<Output, decltype(std::experimental::gcd(Input1(0), Input2(0)))>::value), "" );
+    assert(out == std::experimental::gcd(in1, in2));
+}
+
+
+template <typename Input>
+void test_same_signed()
+{
+    static_assert(( std::is_signed<Input>::value), "" );
+
+//  Returns: zero when m and n are both zero.
+    test0<Input, Input, Input>( 0,  0,  0);
+    test0<Input, Input, Input>( 1,  0,  1);
+    test0<Input, Input, Input>( 0,  1,  1);
+    test0<Input, Input, Input>(-1,  0,  1);
+    test0<Input, Input, Input>( 0, -1,  1);
+
+//  Otherwise, returns the greatest common divisor of |m| and |n|.
+    test0<Input, Input, Input>(  1,   1,  1);
+    test0<Input, Input, Input>(  2,   3,  1);  // relatively prime
+    test0<Input, Input, Input>(  2,   4,  2);
+    test0<Input, Input, Input>( 36,  17,  1);  // relatively prime
+    test0<Input, Input, Input>( 36,  18, 18);
+    
+    test0<Input, Input, Input>( -1,   1,  1);
+    test0<Input, Input, Input>( -2,   3,  1);
+    test0<Input, Input, Input>( -2,   4,  2);
+    test0<Input, Input, Input>(-36,  17,  1);
+    test0<Input, Input, Input>(-36,  18, 18);
+
+    test0<Input, Input, Input>(  1,  -1,  1);
+    test0<Input, Input, Input>(  2,  -3,  1);
+    test0<Input, Input, Input>(  2,  -4,  2);
+    test0<Input, Input, Input>( 36, -17,  1);
+    test0<Input, Input, Input>( 36, -18, 18);
+
+    test0<Input, Input, Input>( -1,  -1,  1);
+    test0<Input, Input, Input>( -2,  -3,  1);
+    test0<Input, Input, Input>( -2,  -4,  2);
+    test0<Input, Input, Input>(-36, -17,  1);
+    test0<Input, Input, Input>(-36, -18, 18);
+}
+
+template <typename Input>
+void test_same_unsigned()
+{
+    static_assert((!std::is_signed<Input>::value), "" );
+
+//  Returns: zero when m and n are both zero.
+    test0<Input, Input, Input>( 0,  0,  0);
+    test0<Input, Input, Input>( 1,  0,  1);
+    test0<Input, Input, Input>( 0,  1,  1);
+
+//  Otherwise, returns the greatest common divisor of |m| and |n|.
+    test0<Input, Input, Input>(  1,   1,  1);
+    test0<Input, Input, Input>(  2,   3,  1);  // relatively prime
+    test0<Input, Input, Input>(  2,   4,  2);
+    test0<Input, Input, Input>( 36,  17,  1);  // relatively prime
+    test0<Input, Input, Input>( 36,  18, 18);
+}
+
+
+template <typename Input1, typename Input2, typename Output>
+void test_different_signed()
+{
+    static_assert(( std::is_signed<Input1>::value), "" );
+    static_assert(( std::is_signed<Input2>::value), "" );
+
+//  Returns: zero when m and n are both zero.
+    test0<Input1, Input2, Output>( 0,  0,  0);
+    test0<Input1, Input2, Output>( 1,  0,  1);
+    test0<Input1, Input2, Output>( 0,  1,  1);
+    test0<Input1, Input2, Output>(-1,  0,  1);
+    test0<Input1, Input2, Output>( 0, -1,  1);
+
+//  Otherwise, returns the greatest common divisor of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,   1,  1);
+    test0<Input1, Input2, Output>(  2,   3,  1);  // relatively prime
+    test0<Input1, Input2, Output>(  2,   4,  2);
+    test0<Input1, Input2, Output>( 36,  17,  1);  // relatively prime
+    test0<Input1, Input2, Output>( 36,  18, 18);
+    
+    test0<Input1, Input2, Output>( -1,   1,  1);
+    test0<Input1, Input2, Output>( -2,   3,  1);
+    test0<Input1, Input2, Output>( -2,   4,  2);
+    test0<Input1, Input2, Output>(-36,  17,  1);
+    test0<Input1, Input2, Output>(-36,  18, 18);
+
+    test0<Input1, Input2, Output>(  1,  -1,  1);
+    test0<Input1, Input2, Output>(  2,  -3,  1);
+    test0<Input1, Input2, Output>(  2,  -4,  2);
+    test0<Input1, Input2, Output>( 36, -17,  1);
+    test0<Input1, Input2, Output>( 36, -18, 18);
+
+    test0<Input1, Input2, Output>( -1,  -1,  1);
+    test0<Input1, Input2, Output>( -2,  -3,  1);
+    test0<Input1, Input2, Output>( -2,  -4,  2);
+    test0<Input1, Input2, Output>(-36, -17,  1);
+    test0<Input1, Input2, Output>(-36, -18, 18);
+}
+
+template <typename Input1, typename Input2, typename Output>
+void test_different_unsigned()
+{
+    static_assert((!std::is_signed<Input1>::value), "" );
+    static_assert((!std::is_signed<Input2>::value), "" );
+
+//  Returns: zero when m and n are both zero.
+    test0<Input1, Input2, Output>( 0,  0,  0);
+    test0<Input1, Input2, Output>( 1,  0,  1);
+    test0<Input1, Input2, Output>( 0,  1,  1);
+
+//  Otherwise, returns the greatest common divisor of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,   1,  1);
+    test0<Input1, Input2, Output>(  2,   3,  1);  // relatively prime
+    test0<Input1, Input2, Output>(  2,   4,  2);
+    test0<Input1, Input2, Output>( 36,  17,  1);  // relatively prime
+    test0<Input1, Input2, Output>( 36,  18, 18);
+}
+
+template <typename Input1, typename Input2, typename Output>
+void test_mixed_first_signed()
+{
+    static_assert(( std::is_signed<Input1>::value), "" );
+    static_assert((!std::is_signed<Input2>::value), "" );
+
+//  Returns: zero when m and n are both zero.
+    test0<Input1, Input2, Output>( 0,  0,  0);
+    test0<Input1, Input2, Output>( 1,  0,  1);
+    test0<Input1, Input2, Output>( 0,  1,  1);
+
+//  Otherwise, returns the greatest common divisor of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,   1,  1);
+    test0<Input1, Input2, Output>(  2,   3,  1);  // relatively prime
+    test0<Input1, Input2, Output>(  2,   4,  2);
+    test0<Input1, Input2, Output>( 36,  17,  1);  // relatively prime
+    test0<Input1, Input2, Output>( 36,  18, 18);
+
+//  Otherwise, returns the greatest common divisor of |m| and |n|.
+    test0<Input1, Input2, Output>( -1,   1,  1);
+    test0<Input1, Input2, Output>( -2,   3,  1);  // relatively prime
+    test0<Input1, Input2, Output>( -2,   4,  2);
+    test0<Input1, Input2, Output>(-36,  17,  1);  // relatively prime
+    test0<Input1, Input2, Output>(-36,  18, 18);
+}
+
+template <typename Input1, typename Input2, typename Output>
+void test_mixed_second_signed()
+{
+    static_assert((!std::is_signed<Input1>::value), "" );
+    static_assert(( std::is_signed<Input2>::value), "" );
+
+//  Returns: zero when m and n are both zero.
+    test0<Input1, Input2, Output>( 0,  0,  0);
+    test0<Input1, Input2, Output>( 1,  0,  1);
+    test0<Input1, Input2, Output>( 0,  1,  1);
+
+//  Otherwise, returns the greatest common divisor of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,   1,  1);
+    test0<Input1, Input2, Output>(  2,   3,  1);  // relatively prime
+    test0<Input1, Input2, Output>(  2,   4,  2);
+    test0<Input1, Input2, Output>( 36,  17,  1);  // relatively prime
+    test0<Input1, Input2, Output>( 36,  18, 18);
+
+//  Otherwise, returns the greatest common divisor of |m| and |n|.
+    test0<Input1, Input2, Output>(  1,  -1,  1);
+    test0<Input1, Input2, Output>(  2,  -3,  1);  // relatively prime
+    test0<Input1, Input2, Output>(  2,  -4,  2);
+    test0<Input1, Input2, Output>( 36, -17,  1);  // relatively prime
+    test0<Input1, Input2, Output>( 36, -18, 18);
+}
+
+int main()
+{
+    test_same_signed<signed char>();
+    test_same_signed<short>();
+    test_same_signed<int>();
+    test_same_signed<long>();
+    test_same_signed<long long>();
+
+    test_same_signed< int8_t>();
+    test_same_signed<int16_t>();
+    test_same_signed<int32_t>();
+    test_same_signed<int64_t>();
+
+    test_same_unsigned<unsigned char>();
+    test_same_unsigned<unsigned short>();
+    test_same_unsigned<unsigned int>();
+    test_same_unsigned<unsigned long>();
+    test_same_unsigned<unsigned long long>();
+    test_same_unsigned<std::size_t>();
+
+    test_same_unsigned< uint8_t>();
+    test_same_unsigned<uint16_t>();
+    test_same_unsigned<uint32_t>();
+    test_same_unsigned<uint64_t>();
+    
+    test_different_signed<signed char, int, int>();
+    test_different_signed<int, signed char, int>();
+    test_different_signed<short, int, int>();
+    test_different_signed<int, short, int>();
+    test_different_signed<int, long, long>();
+    test_different_signed<long, int, long>();
+    test_different_signed<int, long long, long long>();
+    test_different_signed<long long, int, long long>();
+    
+    test_different_unsigned<unsigned char, unsigned int, unsigned int>();
+    test_different_unsigned<unsigned int, unsigned char, unsigned int>();
+    test_different_unsigned<unsigned short, unsigned int, unsigned int>();
+    test_different_unsigned<unsigned int, unsigned short, unsigned int>();
+    test_different_unsigned<unsigned int, unsigned long, unsigned long>();
+    test_different_unsigned<unsigned long, unsigned int, unsigned long>();
+    test_different_unsigned<unsigned int, unsigned long long, unsigned long long>();
+    test_different_unsigned<unsigned long long, unsigned int, unsigned long long>();
+
+    test_mixed_first_signed<signed char, unsigned char, int>();
+    test_mixed_first_signed<int, unsigned char, int>();
+    test_mixed_first_signed<int, unsigned int, unsigned int>();
+    test_mixed_first_signed<long, unsigned int, long>();
+    test_mixed_first_signed<long long, unsigned int, long long>();
+    test_mixed_first_signed<long long, unsigned long, unsigned long long>();
+
+    test_mixed_second_signed<unsigned char, signed char, int>();
+    test_mixed_second_signed<unsigned char, int, int>();
+    test_mixed_second_signed<unsigned int, int, unsigned int>();
+    test_mixed_second_signed<unsigned int, long, long>();
+    test_mixed_second_signed<unsigned int, long long, long long>();
+    test_mixed_second_signed<unsigned long, long long, unsigned long long>();
+}
Index: test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.not_integral2.fail.cpp
===================================================================
--- test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.not_integral2.fail.cpp
+++ test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.not_integral2.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <numeric>
+
+// template<class _M, class _N>
+// constexpr common_type_t<_M,_N> gcd(_M __m, _N __n)
+
+// Remarks: If either M or N is not an integer type, the program is ill-formed.
+
+#include <experimental/numeric>
+
+
+int main()
+{
+    std::experimental::gcd(4, 6.0);
+}
Index: test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.not_integral1.fail.cpp
===================================================================
--- test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.not_integral1.fail.cpp
+++ test/std/experimental/numeric/numeric.ops/numeric.ops.gcd/gcd.not_integral1.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <numeric>
+
+// template<class _M, class _N>
+// constexpr common_type_t<_M,_N> gcd(_M __m, _N __n)
+
+// Remarks: If either M or N is not an integer type, the program is ill-formed.
+
+#include <experimental/numeric>
+
+
+int main()
+{
+    std::experimental::gcd(2.0, 4);
+}
Index: test/std/experimental/numeric/numeric.ops/nothing_to_do.pass.cpp
===================================================================
--- test/std/experimental/numeric/numeric.ops/nothing_to_do.pass.cpp
+++ test/std/experimental/numeric/numeric.ops/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <experimental/numeric>
+
+int main () {}
Index: include/experimental/numeric
===================================================================
--- include/experimental/numeric
+++ include/experimental/numeric
@@ -0,0 +1,79 @@
+// -*- C++ -*-
+//===--------------------------- numeric ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL_NUMERIC
+#define _LIBCPP_EXPERIMENTAL_NUMERIC
+/*
+    experimental/numeric synopsis
+
+// C++1z
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v2 {
+
+  // 13.1.2, Greatest common divisor
+  template<class M, class N>
+  constexpr common_type_t<M,N> gcd(M m, N n);
+
+  // 13.1.3, Least common multiple
+  template<class M, class N>
+  constexpr common_type_t<M,N> lcm(M m, N n);
+
+} // namespace fundamentals_v2
+} // namespace experimental
+} // namespace std
+
+ */
+
+#include <experimental/__config>
+#include <numeric>
+#include <type_traits>  			// is_integral
+#include <cstdlib> 					// abs
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
+
+template <typename _Tp, bool _IsSigned = _VSTD::is_signed<_Tp>::value> struct __abs;
+
+template <typename _Tp>
+struct __abs<_Tp, true> {
+	_LIBCPP_INLINE_VISIBILITY _Tp operator()(_Tp __t) const noexcept { return _VSTD::abs(__t); }
+};
+
+template <typename _Tp>
+struct __abs<_Tp, false> {
+	_LIBCPP_INLINE_VISIBILITY _Tp operator()(_Tp __t) const noexcept { return __t; }
+};
+
+
+template<class _Tp, class _Up>
+constexpr common_type_t<_Tp,_Up> _LIBCPP_INLINE_VISIBILITY
+gcd(_Tp __m, _Up __n)
+{
+	static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to gcd must be integer types");
+	return __n == 0 ? __abs<_Tp>()(__m) : gcd(__n, __abs<_Tp>()(__m) % __abs<_Up>()(__n));
+}
+
+template<class _Tp, class _Up>
+constexpr common_type_t<_Tp,_Up> _LIBCPP_INLINE_VISIBILITY
+lcm(_Tp __m, _Up __n)
+{
+	static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to lcm must be integer types");
+	if (__m == 0 || __n == 0)
+		return 0;
+	return (__abs<_Tp>()(__m) / gcd(__m,__n)) * __abs<_Up>()(__n);
+}
+
+_LIBCPP_END_NAMESPACE_EXPERIMENTAL
+
+#endif /* _LIBCPP_EXPERIMENTAL_MAP */
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to