forked from OSchip/llvm-project
Implement constexpr support for reverse_iterator. Reviewed as https://reviews.llvm.org/D25534
llvm-svn: 284602
This commit is contained in:
parent
5f05ea84d5
commit
1b8f260ed9
|
@ -89,57 +89,60 @@ public:
|
|||
typedef typename iterator_traits<Iterator>::reference reference;
|
||||
typedef typename iterator_traits<Iterator>::pointer pointer;
|
||||
|
||||
reverse_iterator();
|
||||
explicit reverse_iterator(Iterator x);
|
||||
template <class U> reverse_iterator(const reverse_iterator<U>& u);
|
||||
Iterator base() const;
|
||||
reference operator*() const;
|
||||
pointer operator->() const;
|
||||
reverse_iterator& operator++();
|
||||
reverse_iterator operator++(int);
|
||||
reverse_iterator& operator--();
|
||||
reverse_iterator operator--(int);
|
||||
reverse_iterator operator+ (difference_type n) const;
|
||||
reverse_iterator& operator+=(difference_type n);
|
||||
reverse_iterator operator- (difference_type n) const;
|
||||
reverse_iterator& operator-=(difference_type n);
|
||||
reference operator[](difference_type n) const;
|
||||
constexpr reverse_iterator();
|
||||
constexpr explicit reverse_iterator(Iterator x);
|
||||
template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
|
||||
template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
|
||||
constexpr Iterator base() const;
|
||||
constexpr reference operator*() const;
|
||||
constexpr pointer operator->() const;
|
||||
constexpr reverse_iterator& operator++();
|
||||
constexpr reverse_iterator operator++(int);
|
||||
constexpr reverse_iterator& operator--();
|
||||
constexpr reverse_iterator operator--(int);
|
||||
constexpr reverse_iterator operator+ (difference_type n) const;
|
||||
constexpr reverse_iterator& operator+=(difference_type n);
|
||||
constexpr reverse_iterator operator- (difference_type n) const;
|
||||
constexpr reverse_iterator& operator-=(difference_type n);
|
||||
constexpr reference operator[](difference_type n) const;
|
||||
};
|
||||
|
||||
template <class Iterator1, class Iterator2>
|
||||
bool
|
||||
constexpr bool // constexpr in C++17
|
||||
operator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
||||
|
||||
template <class Iterator1, class Iterator2>
|
||||
bool
|
||||
constexpr bool // constexpr in C++17
|
||||
operator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
||||
|
||||
template <class Iterator1, class Iterator2>
|
||||
bool
|
||||
constexpr bool // constexpr in C++17
|
||||
operator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
||||
|
||||
template <class Iterator1, class Iterator2>
|
||||
bool
|
||||
constexpr bool // constexpr in C++17
|
||||
operator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
||||
|
||||
template <class Iterator1, class Iterator2>
|
||||
bool
|
||||
constexpr bool // constexpr in C++17
|
||||
operator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
||||
|
||||
template <class Iterator1, class Iterator2>
|
||||
bool
|
||||
constexpr bool // constexpr in C++17
|
||||
operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
||||
|
||||
template <class Iterator1, class Iterator2>
|
||||
auto
|
||||
constexpr auto
|
||||
operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y)
|
||||
-> decltype(__y.base() - __x.base());
|
||||
-> decltype(__y.base() - __x.base()); // constexpr in C++17
|
||||
|
||||
template <class Iterator>
|
||||
reverse_iterator<Iterator>
|
||||
operator+(typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& x);
|
||||
constexpr reverse_iterator<Iterator>
|
||||
operator+(typename reverse_iterator<Iterator>::difference_type n,
|
||||
const reverse_iterator<Iterator>& x); // constexpr in C++17
|
||||
|
||||
template <class Iterator> reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14
|
||||
template <class Iterator>
|
||||
constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17
|
||||
|
||||
template <class Container>
|
||||
class back_insert_iterator
|
||||
|
@ -618,7 +621,7 @@ class _LIBCPP_TYPE_VIS_ONLY reverse_iterator
|
|||
typename iterator_traits<_Iter>::reference>
|
||||
{
|
||||
private:
|
||||
mutable _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
|
||||
/*mutable*/ _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
|
||||
protected:
|
||||
_Iter current;
|
||||
public:
|
||||
|
@ -627,33 +630,45 @@ public:
|
|||
typedef typename iterator_traits<_Iter>::reference reference;
|
||||
typedef typename iterator_traits<_Iter>::pointer pointer;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY reverse_iterator() : current() {}
|
||||
_LIBCPP_INLINE_VISIBILITY explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
|
||||
template <class _Up> _LIBCPP_INLINE_VISIBILITY reverse_iterator(const reverse_iterator<_Up>& __u)
|
||||
: __t(__u.base()), current(__u.base()) {}
|
||||
_LIBCPP_INLINE_VISIBILITY _Iter base() const {return current;}
|
||||
_LIBCPP_INLINE_VISIBILITY reference operator*() const {_Iter __tmp = current; return *--__tmp;}
|
||||
_LIBCPP_INLINE_VISIBILITY pointer operator->() const {return _VSTD::addressof(operator*());}
|
||||
_LIBCPP_INLINE_VISIBILITY reverse_iterator& operator++() {--current; return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY reverse_iterator operator++(int)
|
||||
{reverse_iterator __tmp(*this); --current; return __tmp;}
|
||||
_LIBCPP_INLINE_VISIBILITY reverse_iterator& operator--() {++current; return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY reverse_iterator operator--(int)
|
||||
{reverse_iterator __tmp(*this); ++current; return __tmp;}
|
||||
_LIBCPP_INLINE_VISIBILITY reverse_iterator operator+ (difference_type __n) const
|
||||
{return reverse_iterator(current - __n);}
|
||||
_LIBCPP_INLINE_VISIBILITY reverse_iterator& operator+=(difference_type __n)
|
||||
{current -= __n; return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY reverse_iterator operator- (difference_type __n) const
|
||||
{return reverse_iterator(current + __n);}
|
||||
_LIBCPP_INLINE_VISIBILITY reverse_iterator& operator-=(difference_type __n)
|
||||
{current += __n; return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
|
||||
{return *(*this + __n);}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator() : __t(), current() {}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator(const reverse_iterator<_Up>& __u) : __t(__u.base()), current(__u.base()) {}
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator& operator=(const reverse_iterator<_Up>& __u)
|
||||
{ __t = current = __u.base(); return *this; }
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
_Iter base() const {return current;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reference operator*() const {_Iter __tmp = current; return *--__tmp;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
pointer operator->() const {return _VSTD::addressof(operator*());}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator& operator++() {--current; return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator& operator--() {++current; return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reference operator[](difference_type __n) const {return *(*this + __n);}
|
||||
};
|
||||
|
||||
template <class _Iter1, class _Iter2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
bool
|
||||
operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
||||
{
|
||||
|
@ -661,7 +676,7 @@ operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>&
|
|||
}
|
||||
|
||||
template <class _Iter1, class _Iter2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
bool
|
||||
operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
||||
{
|
||||
|
@ -669,7 +684,7 @@ operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _
|
|||
}
|
||||
|
||||
template <class _Iter1, class _Iter2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
bool
|
||||
operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
||||
{
|
||||
|
@ -677,7 +692,7 @@ operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>&
|
|||
}
|
||||
|
||||
template <class _Iter1, class _Iter2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
bool
|
||||
operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
||||
{
|
||||
|
@ -685,7 +700,7 @@ operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _
|
|||
}
|
||||
|
||||
template <class _Iter1, class _Iter2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
bool
|
||||
operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
||||
{
|
||||
|
@ -693,7 +708,7 @@ operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>&
|
|||
}
|
||||
|
||||
template <class _Iter1, class _Iter2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
bool
|
||||
operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
||||
{
|
||||
|
@ -702,7 +717,7 @@ operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>&
|
|||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
template <class _Iter1, class _Iter2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
auto
|
||||
operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
||||
-> decltype(__y.base() - __x.base())
|
||||
|
@ -720,7 +735,7 @@ operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _
|
|||
#endif
|
||||
|
||||
template <class _Iter>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator<_Iter>
|
||||
operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
|
||||
{
|
||||
|
@ -729,7 +744,7 @@ operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_i
|
|||
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
template <class _Iter>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
|
||||
{
|
||||
return reverse_iterator<_Iter>(__i);
|
||||
|
|
|
@ -11,10 +11,13 @@
|
|||
|
||||
// reverse_iterator
|
||||
|
||||
// reverse_iterator();
|
||||
// constexpr reverse_iterator();
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -30,4 +33,10 @@ int main()
|
|||
test<random_access_iterator<char*> >();
|
||||
test<char*>();
|
||||
test<const char*>();
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr std::reverse_iterator<const char *> it;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
|
||||
// reverse_iterator
|
||||
|
||||
// explicit reverse_iterator(Iter x);
|
||||
// explicit constexpr reverse_iterator(Iter x);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -32,4 +35,12 @@ int main()
|
|||
test(bidirectional_iterator<const char*>(s));
|
||||
test(random_access_iterator<const char*>(s));
|
||||
test(s);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
constexpr std::reverse_iterator<const char *> it(p);
|
||||
static_assert(it.base() == p);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,11 +13,14 @@
|
|||
|
||||
// template <class U>
|
||||
// requires HasConstructor<Iter, const U&>
|
||||
// reverse_iterator(const reverse_iterator<U> &u);
|
||||
// constexpr reverse_iterator(const reverse_iterator<U> &u);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It, class U>
|
||||
|
@ -39,4 +42,13 @@ int main()
|
|||
test<bidirectional_iterator<Base*> >(bidirectional_iterator<Derived*>(&d));
|
||||
test<random_access_iterator<const Base*> >(random_access_iterator<Derived*>(&d));
|
||||
test<Base*>(&d);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const Derived *p = nullptr;
|
||||
constexpr std::reverse_iterator<const Derived *> it1 = std::make_reverse_iterator(p);
|
||||
constexpr std::reverse_iterator<const Base *> it2(it1);
|
||||
static_assert(it2.base() == p);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -12,12 +12,16 @@
|
|||
|
||||
// reverse_iterator
|
||||
|
||||
// template <class Iterator> reverse_iterator<Iterator>
|
||||
// template <class Iterator>
|
||||
// constexpr reverse_iterator<Iterator>
|
||||
// make_reverse_iterator(Iterator i);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -35,5 +39,13 @@ int main()
|
|||
random_access_iterator<const char*>e(s+10);
|
||||
while ( b != e )
|
||||
test ( b++ );
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
constexpr auto it1 = std::make_reverse_iterator(p);
|
||||
static_assert(it1.base() == p, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
// template <BidirectionalIterator Iter1, BidirectionalIterator Iter2>
|
||||
// requires HasEqualTo<Iter1, Iter2>
|
||||
// bool
|
||||
// constexpr bool
|
||||
// operator!=(const reverse_iterator<Iter1>& x, const reverse_iterator<Iter2>& y);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -39,4 +42,16 @@ int main()
|
|||
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), true);
|
||||
test(s, s, false);
|
||||
test(s, s+1, true);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p);
|
||||
constexpr RI it3 = std::make_reverse_iterator(p+1);
|
||||
static_assert(!(it1 != it2), "");
|
||||
static_assert( (it1 != it3), "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
|
||||
// reverse_iterator
|
||||
|
||||
// reverse_iterator operator++(int);
|
||||
// constexpr reverse_iterator operator++(int);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -34,4 +37,17 @@ int main()
|
|||
test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s));
|
||||
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s));
|
||||
test(s+1, s);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p+1);
|
||||
static_assert(it1 != it2, "");
|
||||
constexpr RI it3 = std::make_reverse_iterator(p+1) ++;
|
||||
static_assert(it1 != it3, "");
|
||||
static_assert(it2 == it3, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
|
||||
// reverse_iterator
|
||||
|
||||
// reverse_iterator& operator++();
|
||||
// constexpr reverse_iterator& operator++();
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -34,4 +37,18 @@ int main()
|
|||
test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s));
|
||||
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s));
|
||||
test(s+1, s);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p+1);
|
||||
static_assert(it1 != it2, "");
|
||||
constexpr RI it3 = ++ std::make_reverse_iterator(p+1);
|
||||
static_assert(it1 == it3, "");
|
||||
static_assert(it2 != it3, "");
|
||||
static_assert(*(++std::make_reverse_iterator(p+2)) == '1', "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -12,11 +12,14 @@
|
|||
// reverse_iterator
|
||||
|
||||
// requires RandomAccessIterator<Iter>
|
||||
// reverse_iterator operator+(difference_type n) const;
|
||||
// constexpr reverse_iterator operator+(difference_type n) const;
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -33,4 +36,17 @@ int main()
|
|||
const char* s = "1234567890";
|
||||
test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s));
|
||||
test(s+5, 5, s);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p + 5);
|
||||
constexpr RI it3 = it2 + 5;
|
||||
static_assert(it1 != it2, "");
|
||||
static_assert(it1 == it3, "");
|
||||
static_assert(it2 != it3, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -12,11 +12,14 @@
|
|||
// reverse_iterator
|
||||
|
||||
// requires RandomAccessIterator<Iter>
|
||||
// reverse_iterator& operator+=(difference_type n);
|
||||
// constexpr reverse_iterator& operator+=(difference_type n);
|
||||
//
|
||||
// constexpr in C++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -34,4 +37,13 @@ int main()
|
|||
const char* s = "1234567890";
|
||||
test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s));
|
||||
test(s+5, 5, s);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
constexpr auto it1 = std::make_reverse_iterator(p);
|
||||
constexpr auto it2 = std::make_reverse_iterator(p+5) += 5;
|
||||
static_assert(it1 == it2, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
|
||||
// reverse_iterator
|
||||
|
||||
// reverse_iterator operator--(int);
|
||||
// constexpr reverse_iterator operator--(int);
|
||||
//
|
||||
// constexpr in C++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -34,4 +37,17 @@ int main()
|
|||
test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s+2));
|
||||
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s+2));
|
||||
test(s+1, s+2);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p+1);
|
||||
static_assert(it1 != it2, "");
|
||||
constexpr RI it3 = std::make_reverse_iterator(p) --;
|
||||
static_assert(it1 == it3, "");
|
||||
static_assert(it2 != it3, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
|
||||
// reverse_iterator
|
||||
|
||||
// reverse_iterator& operator--();
|
||||
// constexpr reverse_iterator& operator--();
|
||||
//
|
||||
// constexpr in C++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -34,4 +37,18 @@ int main()
|
|||
test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s+2));
|
||||
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s+2));
|
||||
test(s+1, s+2);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p+1);
|
||||
static_assert(it1 != it2, "");
|
||||
constexpr RI it3 = -- std::make_reverse_iterator(p);
|
||||
static_assert(it1 != it3, "");
|
||||
static_assert(it2 == it3, "");
|
||||
static_assert(*(--std::make_reverse_iterator(p)) == '1', "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -12,11 +12,14 @@
|
|||
// reverse_iterator
|
||||
|
||||
// requires RandomAccessIterator<Iter>
|
||||
// reverse_iterator operator-(difference_type n) const;
|
||||
// constexpr reverse_iterator operator-(difference_type n) const;
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -33,4 +36,17 @@ int main()
|
|||
const char* s = "1234567890";
|
||||
test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s+10));
|
||||
test(s+5, 5, s+10);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p + 5);
|
||||
constexpr RI it3 = it1 - 5;
|
||||
static_assert(it1 != it2, "");
|
||||
static_assert(it1 != it3, "");
|
||||
static_assert(it2 == it3, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -12,11 +12,14 @@
|
|||
// reverse_iterator
|
||||
|
||||
// requires RandomAccessIterator<Iter>
|
||||
// reverse_iterator& operator-=(difference_type n);
|
||||
// constexpr reverse_iterator& operator-=(difference_type n);
|
||||
//
|
||||
// constexpr in C++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -34,4 +37,13 @@ int main()
|
|||
const char* s = "1234567890";
|
||||
test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s+10));
|
||||
test(s+5, 5, s+10);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
constexpr auto it1 = std::make_reverse_iterator(p+5);
|
||||
constexpr auto it2 = std::make_reverse_iterator(p) -= 5;
|
||||
static_assert(it1 == it2, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
|
||||
// reverse_iterator
|
||||
|
||||
// reference operator*() const;
|
||||
// constexpr reference operator*() const;
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
// Be sure to respect LWG 198:
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#198
|
||||
|
@ -21,6 +23,8 @@
|
|||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_;
|
||||
|
@ -44,4 +48,15 @@ int main()
|
|||
{
|
||||
A a;
|
||||
test(&a+1, A());
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p+1);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p+2);
|
||||
static_assert(*it1 == p[0], "");
|
||||
static_assert(*it2 == p[1], "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
// template <class U>
|
||||
// requires HasAssign<Iter, const U&>
|
||||
// reverse_iterator&
|
||||
// constexpr reverse_iterator&
|
||||
// operator=(const reverse_iterator<U>& u);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It, class U>
|
||||
|
@ -42,4 +45,15 @@ int main()
|
|||
test<bidirectional_iterator<Base*> >(bidirectional_iterator<Derived*>(&d));
|
||||
test<random_access_iterator<const Base*> >(random_access_iterator<Derived*>(&d));
|
||||
test<Base*>(&d);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
using BaseIter = std::reverse_iterator<const Base *>;
|
||||
using DerivedIter = std::reverse_iterator<const Derived *>;
|
||||
constexpr const Derived *p = nullptr;
|
||||
constexpr DerivedIter it1 = std::make_reverse_iterator(p);
|
||||
constexpr BaseIter it2 = (BaseIter{nullptr} = it1);
|
||||
static_assert(it2.base() == p, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
// template <BidirectionalIterator Iter1, BidirectionalIterator Iter2>
|
||||
// requires HasEqualTo<Iter1, Iter2>
|
||||
// bool
|
||||
// constexpr bool
|
||||
// operator==(const reverse_iterator<Iter1>& x, const reverse_iterator<Iter2>& y);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -39,4 +42,17 @@ int main()
|
|||
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), false);
|
||||
test(s, s, true);
|
||||
test(s, s+1, false);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p);
|
||||
constexpr RI it3 = std::make_reverse_iterator(p+1);
|
||||
static_assert( (it1 == it2), "");
|
||||
static_assert(!(it1 == it3), "");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -13,13 +13,16 @@
|
|||
|
||||
// template <RandomAccessIterator Iter1, RandomAccessIterator Iter2>
|
||||
// requires HasMinus<Iter2, Iter1>
|
||||
// auto operator-(const reverse_iterator<Iter1>& x, const reverse_iterator<Iter2>& y)
|
||||
// constexpr auto operator-(const reverse_iterator<Iter1>& x, const reverse_iterator<Iter2>& y)
|
||||
// -> decltype(y.base() - x.base());
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It1, class It2>
|
||||
|
@ -40,4 +43,15 @@ int main()
|
|||
test(s, s, 0);
|
||||
test(s, s+1, 1);
|
||||
test(s+1, s, -1);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p+1);
|
||||
static_assert( it1 - it2 == 1, "");
|
||||
static_assert( it2 - it1 == -1, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
// template <RandomAccessIterator Iter1, RandomAccessIterator Iter2>
|
||||
// requires HasGreater<Iter1, Iter2>
|
||||
// bool
|
||||
// constexpr bool
|
||||
// operator>(const reverse_iterator<Iter1>& x, const reverse_iterator<Iter2>& y);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -39,4 +42,16 @@ int main()
|
|||
test(s, s, false);
|
||||
test(s, s+1, true);
|
||||
test(s+1, s, false);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p);
|
||||
constexpr RI it3 = std::make_reverse_iterator(p+1);
|
||||
static_assert(!(it1 > it2), "");
|
||||
static_assert( (it1 > it3), "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
// template <RandomAccessIterator Iter1, RandomAccessIterator Iter2>
|
||||
// requires HasGreater<Iter1, Iter2>
|
||||
// bool
|
||||
// constexpr bool
|
||||
// operator>=(const reverse_iterator<Iter1>& x, const reverse_iterator<Iter2>& y);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -39,4 +42,16 @@ int main()
|
|||
test(s, s, true);
|
||||
test(s, s+1, true);
|
||||
test(s+1, s, false);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p);
|
||||
constexpr RI it3 = std::make_reverse_iterator(p+1);
|
||||
static_assert( (it1 >= it2), "");
|
||||
static_assert( (it1 >= it3), "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
// template <RandomAccessIterator Iter1, RandomAccessIterator Iter2>
|
||||
// requires HasGreater<Iter1, Iter2>
|
||||
// bool
|
||||
// constexpr bool
|
||||
// operator<(const reverse_iterator<Iter1>& x, const reverse_iterator<Iter2>& y);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -39,4 +42,16 @@ int main()
|
|||
test(s, s, false);
|
||||
test(s, s+1, false);
|
||||
test(s+1, s, true);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p);
|
||||
constexpr RI it3 = std::make_reverse_iterator(p+1);
|
||||
static_assert(!(it1 < it2), "");
|
||||
static_assert(!(it1 < it3), "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
// template <RandomAccessIterator Iter1, RandomAccessIterator Iter2>
|
||||
// requires HasGreater<Iter1, Iter2>
|
||||
// bool
|
||||
// constexpr bool
|
||||
// operator<=(const reverse_iterator<Iter1>& x, const reverse_iterator<Iter2>& y);
|
||||
//
|
||||
// constexpr in c++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -39,4 +42,16 @@ int main()
|
|||
test(s, s, true);
|
||||
test(s, s+1, false);
|
||||
test(s+1, s, true);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p);
|
||||
constexpr RI it3 = std::make_reverse_iterator(p+1);
|
||||
static_assert( (it1 <= it2), "");
|
||||
static_assert(!(it1 <= it3), "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
|
||||
// reverse_iterator
|
||||
|
||||
// pointer operator->() const;
|
||||
// constexpr pointer operator->() const;
|
||||
//
|
||||
// constexpr in C++17
|
||||
|
||||
// Be sure to respect LWG 198:
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#198
|
||||
|
@ -23,6 +25,8 @@
|
|||
#include <list>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_;
|
||||
|
@ -59,6 +63,20 @@ public:
|
|||
B *operator&() { return nullptr; }
|
||||
};
|
||||
|
||||
class C
|
||||
{
|
||||
int data_;
|
||||
public:
|
||||
TEST_CONSTEXPR C() : data_(1) {}
|
||||
|
||||
TEST_CONSTEXPR int get() const {return data_;}
|
||||
|
||||
friend TEST_CONSTEXPR bool operator==(const C& x, const C& y)
|
||||
{return x.data_ == y.data_;}
|
||||
};
|
||||
|
||||
TEST_CONSTEXPR C gC;
|
||||
|
||||
int main()
|
||||
{
|
||||
A a;
|
||||
|
@ -86,4 +104,13 @@ int main()
|
|||
assert ( ri == l.rend ());
|
||||
}
|
||||
}
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
typedef std::reverse_iterator<const C *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(&gC+1);
|
||||
|
||||
static_assert(it1->get() == gC.get(), "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
// reverse_iterator
|
||||
|
||||
// template <RandomAccessIterator Iterator>
|
||||
// reverse_iterator<Iter>
|
||||
// constexpr reverse_iterator<Iter>
|
||||
// operator+(Iter::difference_type n, const reverse_iterator<Iter>& x);
|
||||
//
|
||||
// constexpr in C++17
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class It>
|
||||
|
@ -34,4 +37,17 @@ int main()
|
|||
const char* s = "1234567890";
|
||||
test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s));
|
||||
test(s+5, 5, s);
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
constexpr const char *p = "123456789";
|
||||
typedef std::reverse_iterator<const char *> RI;
|
||||
constexpr RI it1 = std::make_reverse_iterator(p);
|
||||
constexpr RI it2 = std::make_reverse_iterator(p + 5);
|
||||
constexpr RI it3 = 5 + it2;
|
||||
static_assert(it1 != it2, "");
|
||||
static_assert(it1 == it3, "");
|
||||
static_assert(it2 != it3, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
<tr><td><a href="http://wg21.link/P0025R0">P0025R0</a></td><td>LWG</td><td>An algorithm to "clamp" a value between a pair of boundary values</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0154R1">P0154R1</a></td><td>LWG</td><td>constexpr std::hardware_{constructive,destructive}_interference_size</td><td>Jacksonville</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0030R1">P0030R1</a></td><td>LWG</td><td>Proposal to Introduce a 3-Argument Overload to std::hypot</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0031R0">P0031R0</a></td><td>LWG</td><td>A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access</td><td>Jacksonville</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0031R0">P0031R0</a></td><td>LWG</td><td>A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access</td><td>Jacksonville</td><td>In progress</td><td>4.0</td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0272R1">P0272R1</a></td><td>LWG</td><td>Give <tt>std::string</tt> a non-const <tt>.data()</tt> member function</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0077R2">P0077R2</a></td><td>LWG</td><td><tt>is_callable</tt>, the missing INVOKE related trait</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
|
||||
<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
|
|
Loading…
Reference in New Issue