LWG Issue 2128: Implement global cbegin/rbegin/cend/rbegin

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@189634 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/iterator b/include/iterator
index 979a964..d16aa2a 100644
--- a/include/iterator
+++ b/include/iterator
@@ -309,6 +309,19 @@
 template <class T, size_t N> T* begin(T (&array)[N]);
 template <class T, size_t N> T* end(T (&array)[N]);
 
+template <class C> auto cbegin(const C& c) -> decltype(std::begin(c));        // C++14
+template <class C> auto cend(const C& c) -> decltype(std::end(c));            // C++14
+template <class C> auto rbegin(C& c) -> decltype(c.rbegin());                 // C++14
+template <class C> auto rbegin(const C& c) -> decltype(c.rbegin());           // C++14
+template <class C> auto rend(C& c) -> decltype(c.rend());                     // C++14
+template <class C> auto rend(const C& c) -> decltype(c.rend());               // C++14
+template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il); // C++14
+template <class E> reverse_iterator<const E*> rend(initializer_list<E> il);   // C++14
+template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]);      // C++14
+template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]);        // C++14
+template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
+template <class C> auto crend(const C& c) -> decltype(std::rend(c));          // C++14
+
 }  // std
 
 */
@@ -317,6 +330,7 @@
 #include <type_traits>
 #include <cstddef>
 #include <iosfwd>
+#include <initializer_list>
 #ifdef __APPLE__
 #include <Availability.h>
 #endif
@@ -1405,6 +1419,67 @@
     return __c.end();
 }
 
+#if _LIBCPP_STD_VER > 11
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto cbegin(const _Cp& __c) -> decltype(begin(__c))
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto cend(const _Cp& __c) -> decltype(end(__c))
+{
+    return __c.end();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
+{
+    return __c.rbegin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
+{
+    return __c.rbegin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rend(_Cp& __c) -> decltype(__c.rend())
+{
+    return __c.rend();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rend(const _Cp& __c) -> decltype(__c.rend())
+{
+    return __c.rend();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto crbegin(const _Cp& __c) -> decltype(rbegin(__c))
+{
+    return rbegin(__c);
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto crend(const _Cp& __c) -> decltype(rend(__c))
+{
+    return rend(__c);
+}
+
+#endif
+
+
 #else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
 
 template <class _Cp>
@@ -1457,6 +1532,37 @@
     return __array + _Np;
 }
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
+{
+    return reverse_iterator<_Tp*>(__array + _Np);
+}
+
+template <class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
+{
+    return reverse_iterator<_Tp*>(__array);
+}
+
+template <class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
+{
+    return reverse_iterator<const _Ep*>(__il.end());
+}
+
+template <class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
+{
+    return reverse_iterator<const _Ep*>(__il.begin());
+}
+
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_ITERATOR