aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2015-01-19 16:37:03 +0200
committerJonathan Wakely <redi@gcc.gnu.org>2015-01-19 14:37:03 +0000
commit8bae22b708305524126b9462999890242c7e809e (patch)
tree1432527859f849943601f0a946e3f3591ed05d4f
parent75f1620105d7dda4132363674b902cbb1e57e8eb (diff)
downloadgcc-8bae22b708305524126b9462999890242c7e809e.zip
gcc-8bae22b708305524126b9462999890242c7e809e.tar.gz
gcc-8bae22b708305524126b9462999890242c7e809e.tar.bz2
range_access.h (begin, end): Use _GLIBCXX14_CONSTEXPR on overloads for arrays.
2015-01-19 Ville Voutilainen <ville.voutilainen@gmail.com> Jonathan Wakely <jwakely@redhat.com> * include/bits/range_access.h (begin, end): Use _GLIBCXX14_CONSTEXPR on overloads for arrays. (cbegin, cend, rbegin, rend, crbegin, crend): New. * testsuite/24_iterators/range_access_cpp14.cc: New. Co-Authored-By: Jonathan Wakely <jwakely@redhat.com> From-SVN: r219846
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/include/bits/range_access.h131
-rw-r--r--libstdc++-v3/testsuite/24_iterators/range_access_cpp14.cc82
3 files changed, 218 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 52f77b8..23969cb 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2015-01-19 Ville Voutilainen <ville.voutilainen@gmail.com>
+ Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/range_access.h (begin, end): Use _GLIBCXX14_CONSTEXPR
+ on overloads for arrays.
+ (cbegin, cend, rbegin, rend, crbegin, crend): New.
+ * testsuite/24_iterators/range_access_cpp14.cc: New.
+
2015-01-18 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/64646
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index fa18aa2..510c0b1 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -33,7 +33,7 @@
#pragma GCC system_header
#if __cplusplus >= 201103L
-
+#include <initializer_list>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -83,7 +83,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __arr Array.
*/
template<class _Tp, size_t _Nm>
- inline _Tp*
+ inline _GLIBCXX14_CONSTEXPR _Tp*
begin(_Tp (&__arr)[_Nm])
{ return __arr; }
@@ -93,10 +93,135 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __arr Array.
*/
template<class _Tp, size_t _Nm>
- inline _Tp*
+ inline _GLIBCXX14_CONSTEXPR _Tp*
end(_Tp (&__arr)[_Nm])
{ return __arr + _Nm; }
+#if __cplusplus >= 201402L
+ /**
+ * @brief Return an iterator pointing to the first element of
+ * the const container.
+ * @param __cont Container.
+ */
+ template<class _Container>
+ inline constexpr auto
+ cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
+ -> decltype(std::begin(__cont))
+ { return std::begin(__cont); }
+
+ /**
+ * @brief Return an iterator pointing to one past the last element of
+ * the const container.
+ * @param __cont Container.
+ */
+ template<class _Container>
+ inline constexpr auto
+ cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
+ -> decltype(std::end(__cont))
+ { return std::end(__cont); }
+
+ /**
+ * @brief Return a reverse iterator pointing to the last element of
+ * the container.
+ * @param __cont Container.
+ */
+ template<class _Container>
+ inline auto
+ rbegin(_Container& __cont) -> decltype(__cont.rbegin())
+ { return __cont.rbegin(); }
+
+ /**
+ * @brief Return a reverse iterator pointing to the last element of
+ * the const container.
+ * @param __cont Container.
+ */
+ template<class _Container>
+ inline auto
+ rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
+ { return __cont.rbegin(); }
+
+ /**
+ * @brief Return a reverse iterator pointing one past the first element of
+ * the container.
+ * @param __cont Container.
+ */
+ template<class _Container>
+ inline auto
+ rend(_Container& __cont) -> decltype(__cont.rend())
+ { return __cont.rend(); }
+
+ /**
+ * @brief Return a reverse iterator pointing one past the first element of
+ * the const container.
+ * @param __cont Container.
+ */
+ template<class _Container>
+ inline auto
+ rend(const _Container& __cont) -> decltype(__cont.rend())
+ { return __cont.rend(); }
+
+ /**
+ * @brief Return a reverse iterator pointing to the last element of
+ * the array.
+ * @param __arr Array.
+ */
+ template<class _Tp, size_t _Nm>
+ inline reverse_iterator<_Tp*>
+ rbegin(_Tp (&__arr)[_Nm])
+ { return reverse_iterator<_Tp*>(__arr + _Nm); }
+
+ /**
+ * @brief Return a reverse iterator pointing one past the first element of
+ * the array.
+ * @param __arr Array.
+ */
+ template<class _Tp, size_t _Nm>
+ inline reverse_iterator<_Tp*>
+ rend(_Tp (&__arr)[_Nm])
+ { return reverse_iterator<_Tp*>(__arr); }
+
+ /**
+ * @brief Return a reverse iterator pointing to the last element of
+ * the initializer_list.
+ * @param __il initializer_list.
+ */
+ template<class _Tp>
+ inline reverse_iterator<const _Tp*>
+ rbegin(initializer_list<_Tp> __il)
+ { return reverse_iterator<const _Tp*>(__il.end()); }
+
+ /**
+ * @brief Return a reverse iterator pointing one past the first element of
+ * the initializer_list.
+ * @param __il initializer_list.
+ */
+ template<class _Tp>
+ inline reverse_iterator<const _Tp*>
+ rend(initializer_list<_Tp> __il)
+ { return reverse_iterator<const _Tp*>(__il.begin()); }
+
+ /**
+ * @brief Return a reverse iterator pointing to the last element of
+ * the const container.
+ * @param __cont Container.
+ */
+ template<class _Container>
+ inline auto
+ crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
+ { return std::rbegin(__cont); }
+
+ /**
+ * @brief Return a reverse iterator pointing one past the first element of
+ * the const container.
+ * @param __cont Container.
+ */
+ template<class _Container>
+ inline auto
+ crend(const _Container& __cont) -> decltype(std::rend(__cont))
+ { return std::rend(__cont); }
+
+#endif // C++14
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/testsuite/24_iterators/range_access_cpp14.cc b/libstdc++-v3/testsuite/24_iterators/range_access_cpp14.cc
new file mode 100644
index 0000000..a75e04c
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/range_access_cpp14.cc
@@ -0,0 +1,82 @@
+// { dg-do run }
+// { dg-options "-std=gnu++14" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 24.6.5, range access [iterator.range]
+
+#include <iterator>
+#include <vector>
+#include <testsuite_hooks.h>
+
+bool test __attribute__((unused)) = true;
+
+void
+test01()
+{
+ int i[1];
+ VERIFY(std::cbegin(i) == i);
+ VERIFY(std::cend(i) == i+1);
+ VERIFY(std::rbegin(i) == std::reverse_iterator<int*>(i+1));
+ VERIFY(std::rend(i) == std::reverse_iterator<int*>(i));
+ VERIFY(std::crbegin(i) == std::reverse_iterator<int*>(i+1));
+ VERIFY(std::crend(i) == std::reverse_iterator<int*>(i));
+}
+
+void
+test02()
+{
+ static int i[1];
+ constexpr auto b __attribute__((unused)) = std::begin(i);
+ constexpr auto e __attribute__((unused)) = std::end(i);
+ constexpr auto cb __attribute__((unused)) = std::cbegin(i);
+ constexpr auto ce __attribute__((unused)) = std::cend(i);
+}
+
+int
+test03()
+{
+ std::initializer_list<int> il{1};
+ VERIFY(std::cbegin(il) == il.begin());
+ VERIFY(std::cend(il) == il.end());
+ VERIFY(std::rbegin(il) == std::reverse_iterator<const int*>(il.end()));
+ VERIFY(std::rend(il) == std::reverse_iterator<const int*>(il.begin()));
+ VERIFY(std::crbegin(il) == std::reverse_iterator<const int*>(il.end()));
+ VERIFY(std::crend(il) == std::reverse_iterator<const int*>(il.begin()));
+}
+
+int
+test04()
+{
+ std::vector<int> v{1};
+ VERIFY(std::cbegin(v) == v.cbegin());
+ VERIFY(std::cend(v) == v.cend());
+ VERIFY(std::rbegin(v) == v.rbegin());
+ VERIFY(std::rend(v) == v.rend());
+ VERIFY(std::crbegin(v) == v.crbegin());
+ VERIFY(std::crend(v) == v.crend());
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}