Add support for N4389 - std::bool_constant

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@237636 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/ratio b/include/ratio
index 25ab503..6ddc19b 100644
--- a/include/ratio
+++ b/include/ratio
@@ -398,11 +398,11 @@
 
 template <class _R1, class _R2>
 struct _LIBCPP_TYPE_VIS_ONLY ratio_equal
-    : public integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den> {};
+    : public _LIBCPP_BOOL_CONSTANT((_R1::num == _R2::num && _R1::den == _R2::den)) {};
 
 template <class _R1, class _R2>
 struct _LIBCPP_TYPE_VIS_ONLY ratio_not_equal
-    : public integral_constant<bool, !ratio_equal<_R1, _R2>::value> {};
+    : public _LIBCPP_BOOL_CONSTANT((!ratio_equal<_R1, _R2>::value)) {};
 
 // ratio_less
 
@@ -461,19 +461,19 @@
 
 template <class _R1, class _R2>
 struct _LIBCPP_TYPE_VIS_ONLY ratio_less
-    : public integral_constant<bool, __ratio_less<_R1, _R2>::value> {};
+    : public _LIBCPP_BOOL_CONSTANT((__ratio_less<_R1, _R2>::value)) {};
 
 template <class _R1, class _R2>
 struct _LIBCPP_TYPE_VIS_ONLY ratio_less_equal
-    : public integral_constant<bool, !ratio_less<_R2, _R1>::value> {};
+    : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R2, _R1>::value)) {};
 
 template <class _R1, class _R2>
 struct _LIBCPP_TYPE_VIS_ONLY ratio_greater
-    : public integral_constant<bool, ratio_less<_R2, _R1>::value> {};
+    : public _LIBCPP_BOOL_CONSTANT((ratio_less<_R2, _R1>::value)) {};
 
 template <class _R1, class _R2>
 struct _LIBCPP_TYPE_VIS_ONLY ratio_greater_equal
-    : public integral_constant<bool, !ratio_less<_R1, _R2>::value> {};
+    : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R1, _R2>::value)) {};
 
 template <class _R1, class _R2>
 struct __ratio_gcd
diff --git a/include/type_traits b/include/type_traits
index 49eecac..4753a61 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -19,8 +19,13 @@
 
     // helper class:
     template <class T, T v> struct integral_constant;
-    typedef integral_constant<bool, true>  true_type;
-    typedef integral_constant<bool, false> false_type;
+    typedef integral_constant<bool, true>  true_type;   // C++11
+    typedef integral_constant<bool, false> false_type;  // C++11
+    
+    template <bool B>                                   // C++14
+    using bool_constant = integral_constant<bool, B>;   // C++14
+    typedef bool_constant<true> true_type;              // C++14
+    typedef bool_constant<false> false_type;            // C++14
 
     // helper traits
     template <bool, class T = void> struct enable_if;
@@ -260,8 +265,16 @@
 template <class _Tp, _Tp __v>
 _LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value;
 
-typedef integral_constant<bool, true>  true_type;
-typedef integral_constant<bool, false> false_type;
+#if _LIBCPP_STD_VER > 14
+template <bool __b>
+using bool_constant = integral_constant<bool, __b>;
+#define	_LIBCPP_BOOL_CONSTANT(__b) bool_constant<(__b)>
+#else
+#define	_LIBCPP_BOOL_CONSTANT(__b) integral_constant<bool,(__b)>
+#endif
+
+typedef _LIBCPP_BOOL_CONSTANT(true)  true_type;
+typedef _LIBCPP_BOOL_CONSTANT(false) false_type;
 
 // is_const
 
@@ -679,7 +692,7 @@
 // is_signed
 
 template <class _Tp, bool = is_integral<_Tp>::value>
-struct __libcpp_is_signed_impl : public integral_constant<bool, _Tp(-1) < _Tp(0)> {};
+struct __libcpp_is_signed_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(-1) < _Tp(0)) {};
 
 template <class _Tp>
 struct __libcpp_is_signed_impl<_Tp, false> : public true_type {};  // floating point
@@ -694,7 +707,7 @@
 // is_unsigned
 
 template <class _Tp, bool = is_integral<_Tp>::value>
-struct __libcpp_is_unsigned_impl : public integral_constant<bool, _Tp(0) < _Tp(-1)> {};
+struct __libcpp_is_unsigned_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {};
 
 template <class _Tp>
 struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {};  // floating point
diff --git a/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp b/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp
new file mode 100644
index 0000000..71110ea
--- /dev/null
+++ b/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// bool_constant
+
+#include <type_traits>
+#include <cassert>
+
+int main()
+{
+#if __cplusplus > 201402L
+    typedef std::bool_constant<true> _t;
+    static_assert(_t::value, "");
+    static_assert((std::is_same<_t::value_type, bool>::value), "");
+    static_assert((std::is_same<_t::type, _t>::value), "");
+    static_assert((_t() == true), "");
+
+    typedef std::bool_constant<false> _f;
+    static_assert(!_f::value, "");
+    static_assert((std::is_same<_f::value_type, bool>::value), "");
+    static_assert((std::is_same<_f::type, _f>::value), "");
+    static_assert((_f() == false), "");
+#endif
+}
diff --git a/www/cxx1z_status.html b/www/cxx1z_status.html
index 818e574..e39584b 100644
--- a/www/cxx1z_status.html
+++ b/www/cxx1z_status.html
@@ -64,7 +64,7 @@
 	<tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4285.html">N4285</a></td><td>CWG</td></td><td>Cleanup for exception-specification and throw-expression.</td><td>Urbana</td><td></td><td></td></tr>
   	<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
 	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4387">N4387</a></td><td>LWG</td></td><td>improving pair and tuple</td><td>Lenexa</td><td></td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4389">N4389</a></td><td>LWG</td></td><td>bool_constant</td><td>Lenexa</td><td></td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4389">N4389</a></td><td>LWG</td></td><td>bool_constant</td><td>Lenexa</td><td></td><td>Complete</td></tr>
 	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4508">N4508</a></td><td>LWG</td></td><td>shared_mutex for C++17</td><td>Lenexa</td><td></td><td></td></tr>
 	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4366">N4366</a></td><td>LWG</td></td><td>LWG 2228 missing SFINAE rule</td><td>Lenexa</td><td></td><td></td></tr>	
 	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4510">N4510</a></td><td>LWG</td></td><td>Minimal incomplete type support for standard containers, revision 4</td><td>Lenexa</td><td></td><td></td></tr>