Implement N3421; comparison predicates<void>

llvm-svn: 187357
diff --git a/libcxx/test/utilities/function.objects/arithmetic.operations/divides.pass.cpp b/libcxx/test/utilities/function.objects/arithmetic.operations/divides.pass.cpp
index 13e5b68..5eeba18 100644
--- a/libcxx/test/utilities/function.objects/arithmetic.operations/divides.pass.cpp
+++ b/libcxx/test/utilities/function.objects/arithmetic.operations/divides.pass.cpp
@@ -21,4 +21,11 @@
     const F f = F();
     static_assert((std::is_base_of<std::binary_function<int, int, int>, F>::value), "");
     assert(f(36, 4) == 9);
+#if _LIBCPP_STD_VER > 11
+    typedef std::divides<> F2;
+    const F2 f2 = F2();
+    assert(f2(36, 4) == 9);
+    assert(f2(36.0, 4) == 9);
+    assert(f2(18, 4.0) == 4.5); // exact in binary
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/arithmetic.operations/minus.pass.cpp b/libcxx/test/utilities/function.objects/arithmetic.operations/minus.pass.cpp
index f777b23..2a8ecd6 100644
--- a/libcxx/test/utilities/function.objects/arithmetic.operations/minus.pass.cpp
+++ b/libcxx/test/utilities/function.objects/arithmetic.operations/minus.pass.cpp
@@ -21,4 +21,11 @@
     const F f = F();
     static_assert((std::is_base_of<std::binary_function<int, int, int>, F>::value), "");
     assert(f(3, 2) == 1);
+#if _LIBCPP_STD_VER > 11
+    typedef std::minus<> F2;
+    const F2 f2 = F2();
+    assert(f2(3,2) == 1);
+    assert(f2(3.0, 2) == 1);
+    assert(f2(3, 2.5) == 0.5);
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/arithmetic.operations/modulus.pass.cpp b/libcxx/test/utilities/function.objects/arithmetic.operations/modulus.pass.cpp
index 542711f..421f945 100644
--- a/libcxx/test/utilities/function.objects/arithmetic.operations/modulus.pass.cpp
+++ b/libcxx/test/utilities/function.objects/arithmetic.operations/modulus.pass.cpp
@@ -21,4 +21,11 @@
     const F f = F();
     static_assert((std::is_base_of<std::binary_function<int, int, int>, F>::value), "");
     assert(f(36, 8) == 4);
+#if _LIBCPP_STD_VER > 11
+    typedef std::modulus<> F2;
+    const F2 f2 = F2();
+    assert(f2(36, 8) == 4);
+    assert(f2(36L, 8) == 4);
+    assert(f2(36, 8L) == 4);
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp b/libcxx/test/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp
index c96938f..67bb5a5 100644
--- a/libcxx/test/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp
+++ b/libcxx/test/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp
@@ -21,4 +21,11 @@
     const F f = F();
     static_assert((std::is_base_of<std::binary_function<int, int, int>, F>::value), "");
     assert(f(3, 2) == 6);
+#if _LIBCPP_STD_VER > 11
+    typedef std::multiplies<> F2;
+    const F2 f2 = F2();
+    assert(f2(3,2) == 6);
+    assert(f2(3.0, 2) == 6);
+    assert(f2(3, 2.5) == 7.5); // exact in binary
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/arithmetic.operations/negate.pass.cpp b/libcxx/test/utilities/function.objects/arithmetic.operations/negate.pass.cpp
index 6c6957a..181c1fb 100644
--- a/libcxx/test/utilities/function.objects/arithmetic.operations/negate.pass.cpp
+++ b/libcxx/test/utilities/function.objects/arithmetic.operations/negate.pass.cpp
@@ -21,4 +21,11 @@
     const F f = F();
     static_assert((std::is_base_of<std::unary_function<int, int>, F>::value), "");
     assert(f(36) == -36);
+#if _LIBCPP_STD_VER > 11
+    typedef std::negate<> F2;
+    const F2 f2 = F2();
+    assert(f2(36) == -36);
+    assert(f2(36L) == -36);
+    assert(f2(36.0) == -36);
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/arithmetic.operations/plus.pass.cpp b/libcxx/test/utilities/function.objects/arithmetic.operations/plus.pass.cpp
index bc72195..4de23ff 100644
--- a/libcxx/test/utilities/function.objects/arithmetic.operations/plus.pass.cpp
+++ b/libcxx/test/utilities/function.objects/arithmetic.operations/plus.pass.cpp
@@ -21,4 +21,11 @@
     const F f = F();
     static_assert((std::is_base_of<std::binary_function<int, int, int>, F>::value), "");
     assert(f(3, 2) == 5);
+#if _LIBCPP_STD_VER > 11
+    typedef std::plus<> F2;
+    const F2 f2 = F2();
+    assert(f2(3,2) == 5);
+    assert(f2(3.0, 2) == 5);
+    assert(f2(3, 2.5) == 5.5);
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/bitwise.operations/bit_and.pass.cpp b/libcxx/test/utilities/function.objects/bitwise.operations/bit_and.pass.cpp
index ac10acd..1841232 100644
--- a/libcxx/test/utilities/function.objects/bitwise.operations/bit_and.pass.cpp
+++ b/libcxx/test/utilities/function.objects/bitwise.operations/bit_and.pass.cpp
@@ -25,4 +25,27 @@
     assert(f(0x58D3, 0xEA95) == 0x4891);
     assert(f(0x58D3, 0) == 0);
     assert(f(0xFFFF, 0x58D3) == 0x58D3);
+#if _LIBCPP_STD_VER > 11
+    typedef std::bit_and<> F2;
+    const F2 f2 = F2();
+    assert(f2(0xEA95, 0xEA95) == 0xEA95);
+    assert(f2(0xEA95L, 0xEA95) == 0xEA95);
+    assert(f2(0xEA95, 0xEA95L) == 0xEA95);
+
+    assert(f2(0xEA95, 0x58D3) == 0x4891);
+    assert(f2(0xEA95L, 0x58D3) == 0x4891);
+    assert(f2(0xEA95, 0x58D3L) == 0x4891);
+
+    assert(f2(0x58D3, 0xEA95) == 0x4891);
+    assert(f2(0x58D3L, 0xEA95) == 0x4891);
+    assert(f2(0x58D3, 0xEA95L) == 0x4891);
+
+    assert(f2(0x58D3, 0) == 0);
+    assert(f2(0x58D3L, 0) == 0);
+    assert(f2(0x58D3, 0L) == 0);
+
+    assert(f2(0xFFFF, 0x58D3) == 0x58D3);
+    assert(f2(0xFFFFL, 0x58D3) == 0x58D3);
+    assert(f2(0xFFFF, 0x58D3L) == 0x58D3);
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/bitwise.operations/bit_not.pass.cpp b/libcxx/test/utilities/function.objects/bitwise.operations/bit_not.pass.cpp
new file mode 100644
index 0000000..2158292
--- /dev/null
+++ b/libcxx/test/utilities/function.objects/bitwise.operations/bit_not.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// bit_not
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+    typedef std::bit_not<int> F;
+    const F f = F();
+    static_assert((std::is_base_of<std::unary_function<int, int>, F>::value), "");
+    assert((f(0xEA95) & 0xFFFF ) == 0x156A);
+    assert((f(0x58D3) & 0xFFFF ) == 0xA72C);
+    assert((f(0)      & 0xFFFF ) == 0xFFFF);
+    assert((f(0xFFFF) & 0xFFFF ) == 0);
+
+    typedef std::bit_not<> F2;
+    const F2 f2 = F2();
+    assert((f2(0xEA95)  & 0xFFFF ) == 0x156A);
+    assert((f2(0xEA95L) & 0xFFFF ) == 0x156A);
+    assert((f2(0x58D3)  & 0xFFFF ) == 0xA72C);
+    assert((f2(0x58D3L) & 0xFFFF ) == 0xA72C);
+    assert((f2(0)       & 0xFFFF ) == 0xFFFF);
+    assert((f2(0L)      & 0xFFFF ) == 0xFFFF);
+    assert((f2(0xFFFF)  & 0xFFFF ) == 0);
+    assert((f2(0xFFFFL)  & 0xFFFF ) == 0);
+#endif
+}
diff --git a/libcxx/test/utilities/function.objects/bitwise.operations/bit_or.pass.cpp b/libcxx/test/utilities/function.objects/bitwise.operations/bit_or.pass.cpp
index 6dc3911d..21ada12 100644
--- a/libcxx/test/utilities/function.objects/bitwise.operations/bit_or.pass.cpp
+++ b/libcxx/test/utilities/function.objects/bitwise.operations/bit_or.pass.cpp
@@ -25,4 +25,27 @@
     assert(f(0x58D3, 0xEA95) == 0xFAD7);
     assert(f(0x58D3, 0) == 0x58D3);
     assert(f(0xFFFF, 0x58D3) == 0xFFFF);
+#if _LIBCPP_STD_VER > 11
+    typedef std::bit_or<> F2;
+    const F2 f2 = F2();
+    assert(f2(0xEA95, 0xEA95) == 0xEA95);
+    assert(f2(0xEA95L, 0xEA95) == 0xEA95);
+    assert(f2(0xEA95, 0xEA95L) == 0xEA95);
+
+    assert(f2(0xEA95, 0x58D3) == 0xFAD7);
+    assert(f2(0xEA95L, 0x58D3) == 0xFAD7);
+    assert(f2(0xEA95, 0x58D3L) == 0xFAD7);
+
+    assert(f2(0x58D3, 0xEA95) == 0xFAD7);
+    assert(f2(0x58D3L, 0xEA95) == 0xFAD7);
+    assert(f2(0x58D3, 0xEA95L) == 0xFAD7);
+
+    assert(f2(0x58D3, 0) == 0x58D3);
+    assert(f2(0x58D3L, 0) == 0x58D3);
+    assert(f2(0x58D3, 0L) == 0x58D3);
+
+    assert(f2(0xFFFF, 0x58D3) == 0xFFFF);
+    assert(f2(0xFFFFL, 0x58D3) == 0xFFFF);
+    assert(f2(0xFFFF, 0x58D3L) == 0xFFFF);
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp b/libcxx/test/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp
index c3af462..8417d6e 100644
--- a/libcxx/test/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp
+++ b/libcxx/test/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp
@@ -25,4 +25,27 @@
     assert(f(0x58D3, 0xEA95) == 0xB246);
     assert(f(0x58D3, 0) == 0x58D3);
     assert(f(0xFFFF, 0x58D3) == 0xA72C);
+#if _LIBCPP_STD_VER > 11
+    typedef std::bit_xor<> F2;
+    const F2 f2 = F2();
+    assert(f(0xEA95, 0xEA95) == 0);
+    assert(f(0xEA95L, 0xEA95) == 0);
+    assert(f(0xEA95, 0xEA95L) == 0);
+
+    assert(f(0xEA95, 0x58D3) == 0xB246);
+    assert(f(0xEA95L, 0x58D3) == 0xB246);
+    assert(f(0xEA95, 0x58D3L) == 0xB246);
+
+    assert(f(0x58D3, 0xEA95) == 0xB246);
+    assert(f(0x58D3L, 0xEA95) == 0xB246);
+    assert(f(0x58D3, 0xEA95L) == 0xB246);
+
+    assert(f(0x58D3, 0) == 0x58D3);
+    assert(f(0x58D3L, 0) == 0x58D3);
+    assert(f(0x58D3, 0L) == 0x58D3);
+
+    assert(f(0xFFFF, 0x58D3) == 0xA72C);
+    assert(f(0xFFFFL, 0x58D3) == 0xA72C);
+    assert(f(0xFFFF, 0x58D3L) == 0xA72C);
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/comparisons/equal_to.pass.cpp b/libcxx/test/utilities/function.objects/comparisons/equal_to.pass.cpp
index 988e957..7904887 100644
--- a/libcxx/test/utilities/function.objects/comparisons/equal_to.pass.cpp
+++ b/libcxx/test/utilities/function.objects/comparisons/equal_to.pass.cpp
@@ -22,4 +22,12 @@
     static_assert((std::is_base_of<std::binary_function<int, int, bool>, F>::value), "");
     assert(f(36, 36));
     assert(!f(36, 6));
+#if _LIBCPP_STD_VER > 11
+    typedef std::equal_to<> F2;
+    const F2 f2 = F2();
+    assert(f2(36, 36));
+    assert(!f2(36, 6));
+    assert(f2(36, 36.0));
+    assert(f2(36.0, 36L));
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/comparisons/greater.pass.cpp b/libcxx/test/utilities/function.objects/comparisons/greater.pass.cpp
index 2cadd6d..8e9a891 100644
--- a/libcxx/test/utilities/function.objects/comparisons/greater.pass.cpp
+++ b/libcxx/test/utilities/function.objects/comparisons/greater.pass.cpp
@@ -23,4 +23,15 @@
     assert(!f(36, 36));
     assert(f(36, 6));
     assert(!f(6, 36));
+#if _LIBCPP_STD_VER > 11
+    typedef std::greater<> F2;
+    const F2 f2 = F2();
+    assert(!f2(36, 36));
+    assert(f2(36, 6));
+    assert(!f2(6, 36));
+    assert( f2(36, 6.0));
+    assert( f2(36.0, 6));
+    assert(!f2(6, 36.0));
+    assert(!f2(6.0, 36));
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/comparisons/greater_equal.pass.cpp b/libcxx/test/utilities/function.objects/comparisons/greater_equal.pass.cpp
index 3ecadd4..63aad67 100644
--- a/libcxx/test/utilities/function.objects/comparisons/greater_equal.pass.cpp
+++ b/libcxx/test/utilities/function.objects/comparisons/greater_equal.pass.cpp
@@ -23,4 +23,15 @@
     assert(f(36, 36));
     assert(f(36, 6));
     assert(!f(6, 36));
+#if _LIBCPP_STD_VER > 11
+    typedef std::greater_equal<> F2;
+    const F2 f2 = F2();
+    assert(f2(36, 36));
+    assert(f2(36, 6));
+    assert(!f2(6, 36));
+    assert( f2(36, 6.0));
+    assert( f2(36.0, 6));
+    assert(!f2(6, 36.0));
+    assert(!f2(6.0, 36));
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/comparisons/less.pass.cpp b/libcxx/test/utilities/function.objects/comparisons/less.pass.cpp
index 0946bbf..6060964 100644
--- a/libcxx/test/utilities/function.objects/comparisons/less.pass.cpp
+++ b/libcxx/test/utilities/function.objects/comparisons/less.pass.cpp
@@ -23,4 +23,15 @@
     assert(!f(36, 36));
     assert(!f(36, 6));
     assert(f(6, 36));
+#if _LIBCPP_STD_VER > 11
+    typedef std::less<> F2;
+    const F2 f2 = F2();
+    assert(!f2(36, 36));
+    assert(!f2(36, 6));
+    assert( f2(6, 36));
+    assert(!f2(36, 6.0));
+    assert(!f2(36.0, 6));
+    assert( f2(6, 36.0));
+    assert( f2(6.0, 36));
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/comparisons/less_equal.pass.cpp b/libcxx/test/utilities/function.objects/comparisons/less_equal.pass.cpp
index 818af4a..346e68b 100644
--- a/libcxx/test/utilities/function.objects/comparisons/less_equal.pass.cpp
+++ b/libcxx/test/utilities/function.objects/comparisons/less_equal.pass.cpp
@@ -23,4 +23,15 @@
     assert(f(36, 36));
     assert(!f(36, 6));
     assert(f(6, 36));
+#if _LIBCPP_STD_VER > 11
+    typedef std::less_equal<> F2;
+    const F2 f2 = F2();
+    assert( f2(36, 36));
+    assert(!f2(36, 6));
+    assert( f2(6, 36));
+    assert(!f2(36, 6.0));
+    assert(!f2(36.0, 6));
+    assert( f2(6, 36.0));
+    assert( f2(6.0, 36));
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/comparisons/not_equal_to.pass.cpp b/libcxx/test/utilities/function.objects/comparisons/not_equal_to.pass.cpp
index 0b8f8dd..d481e47 100644
--- a/libcxx/test/utilities/function.objects/comparisons/not_equal_to.pass.cpp
+++ b/libcxx/test/utilities/function.objects/comparisons/not_equal_to.pass.cpp
@@ -22,4 +22,14 @@
     static_assert((std::is_base_of<std::binary_function<int, int, bool>, F>::value), "");
     assert(!f(36, 36));
     assert(f(36, 6));
+#if _LIBCPP_STD_VER > 11
+    typedef std::not_equal_to<> F2;
+    const F2 f2 = F2();
+    assert(!f2(36, 36));
+    assert( f2(36, 6));
+    assert( f2(36, 6.0));
+    assert( f2(36.0, 6));
+    assert(!f2(36.0, 36));
+    assert(!f2(36, 36.0));
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/logical.operations/logical_and.pass.cpp b/libcxx/test/utilities/function.objects/logical.operations/logical_and.pass.cpp
index 914eb4c..4302f77 100644
--- a/libcxx/test/utilities/function.objects/logical.operations/logical_and.pass.cpp
+++ b/libcxx/test/utilities/function.objects/logical.operations/logical_and.pass.cpp
@@ -24,4 +24,19 @@
     assert(!f(36, 0));
     assert(!f(0, 36));
     assert(!f(0, 0));
+#if _LIBCPP_STD_VER > 11
+    typedef std::logical_and<> F2;
+    const F2 f2 = F2();
+    assert( f2(36, 36));
+    assert( f2(36, 36L));
+    assert( f2(36L, 36));
+    assert(!f2(36, 0));
+    assert(!f2(0, 36));
+    assert( f2(36, 36L));
+    assert(!f2(36, 0L));
+    assert(!f2(0, 36L));
+    assert( f2(36L, 36));
+    assert(!f2(36L, 0));
+    assert(!f2(0L, 36));
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/logical.operations/logical_not.pass.cpp b/libcxx/test/utilities/function.objects/logical.operations/logical_not.pass.cpp
index 289c924..40a4754 100644
--- a/libcxx/test/utilities/function.objects/logical.operations/logical_not.pass.cpp
+++ b/libcxx/test/utilities/function.objects/logical.operations/logical_not.pass.cpp
@@ -22,4 +22,12 @@
     static_assert((std::is_base_of<std::unary_function<int, bool>, F>::value), "");
     assert(!f(36));
     assert(f(0));
+#if _LIBCPP_STD_VER > 11
+    typedef std::logical_not<> F2;
+    const F2 f2 = F2();
+    assert(!f2(36));
+    assert( f2(0));
+    assert(!f2(36L));
+    assert( f2(0L));
+#endif
 }
diff --git a/libcxx/test/utilities/function.objects/logical.operations/logical_or.pass.cpp b/libcxx/test/utilities/function.objects/logical.operations/logical_or.pass.cpp
index 0cf217f..1c9b243 100644
--- a/libcxx/test/utilities/function.objects/logical.operations/logical_or.pass.cpp
+++ b/libcxx/test/utilities/function.objects/logical.operations/logical_or.pass.cpp
@@ -24,4 +24,18 @@
     assert(f(36, 0));
     assert(f(0, 36));
     assert(!f(0, 0));
+#if _LIBCPP_STD_VER > 11
+    typedef std::logical_or<> F2;
+    const F2 f2 = F2();
+    assert( f2(36, 36));
+    assert( f2(36, 36L));
+    assert( f2(36L, 36));
+    assert( f2(36, 0));
+    assert( f2(0, 36));
+    assert( f2(36, 0L));
+    assert( f2(0, 36L));
+    assert(!f2(0, 0));
+    assert(!f2(0, 0L));
+    assert(!f2(0L, 0));
+#endif
 }