Browse Source

cmstd: Extend header <cm/iterator>

Marc Chevrier 6 years ago
parent
commit
4a08690ccf
1 changed files with 138 additions and 0 deletions
  1. 138 0
      Utilities/std/cm/iterator

+ 138 - 0
Utilities/std/cm/iterator

@@ -15,6 +15,11 @@ using std::make_reverse_iterator;
 
 using std::cbegin;
 using std::cend;
+
+using std::rbegin;
+using std::rend;
+using std::crbegin;
+using std::crend;
 #else
 template <class Iter>
 std::reverse_iterator<Iter> make_reverse_iterator(Iter it)
@@ -44,10 +49,91 @@ constexpr auto cend(C const& c) noexcept(noexcept(std::end(c)))
 {
   return std::end(c);
 }
+
+// std::r{begin,end} backport from C++14
+template <class C>
+#  if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#  endif
+  auto
+  rbegin(C& c) -> decltype(c.rbegin())
+{
+  return c.rbegin();
+}
+template <class C>
+#  if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#  endif
+  auto
+  rbegin(C const& c) -> decltype(c.rbegin())
+{
+  return c.rbegin();
+}
+template <typename T, size_t N>
+#  if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#  endif
+  std::reverse_iterator<T*>
+    rbegin(T (&arr)[N])
+{
+  return std::reverse_iterator<T*>(arr + N);
+}
+
+template <class C>
+#  if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#  endif
+  auto
+  rend(C& c) -> decltype(c.rend())
+{
+  return c.rend();
+}
+template <class C>
+#  if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#  endif
+  auto
+  rend(C const& c) -> decltype(c.rend())
+{
+  return c.rend();
+}
+template <typename T, size_t N>
+#  if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#  endif
+  std::reverse_iterator<T*>
+    rend(T (&arr)[N])
+{
+  return std::reverse_iterator<T*>(arr);
+}
+
+// std::cr{begin,end} backport from C++14
+template <class C>
+#  if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#  endif
+  auto
+  crbegin(C const& c) -> decltype(cm::rbegin(c))
+{
+  return cm::rbegin(c);
+}
+
+template <class C>
+#  if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#  endif
+  auto
+  crend(C const& c) -> decltype(cm::rend(c))
+{
+  return cm::rend(c);
+}
 #endif
 
 #if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
 using std::size;
+
+using std::empty;
+using std::data;
 #else
 
 // std::size backport from C++17.
@@ -71,6 +157,58 @@ constexpr
   return N;
 }
 
+// std::empty backport from C++17.
+template <class C>
+#  if defined(_MSC_VER) && _MSC_VER < 1900
+auto empty(C const& c)
+#  else
+constexpr auto empty(C const& c) noexcept(noexcept(c.empty()))
+#  endif
+  -> decltype(c.empty())
+{
+  return c.empty();
+}
+template <typename T, size_t N>
+#  if defined(_MSC_VER) && _MSC_VER < 1900
+bool empty(const T (&)[N])
+#  else
+constexpr bool empty(const T (&)[N]) noexcept
+#  endif
+{
+  return false;
+}
+
+// std::data backport from C++17.
+template <class C>
+#  if defined(_MSC_VER) && _MSC_VER < 1900
+auto data(C const& c)
+#  else
+constexpr auto data(C const& c) noexcept(noexcept(c.data()))
+#  endif
+  -> decltype(c.data())
+{
+  return c.data();
+}
+template <class C>
+#  if defined(_MSC_VER) && _MSC_VER < 1900
+auto data(C& c)
+#  else
+constexpr auto data(C& c) noexcept(noexcept(c.data()))
+#  endif
+  -> decltype(c.data())
+{
+  return c.data();
+}
+template <typename T, size_t N>
+#  if defined(_MSC_VER) && _MSC_VER < 1900
+T* data(T (&)[N])
+#  else
+constexpr T* data(T (&arr)[N]) noexcept
+#  endif
+{
+  return arr;
+}
+
 #endif
 
 } // namespace cm