Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:38:52

0001 #ifndef BOOST_NEW_ITERATOR_TESTS_HPP
0002 #define BOOST_NEW_ITERATOR_TESTS_HPP
0003 
0004 //
0005 // Copyright (c) David Abrahams 2001.
0006 // Copyright (c) Jeremy Siek 2001-2003.
0007 // Copyright (c) Thomas Witt 2002.
0008 //
0009 // Use, modification and distribution is subject to the
0010 // Boost Software License, Version 1.0.
0011 // (See accompanying file LICENSE_1_0.txt or copy at
0012 // http://www.boost.org/LICENSE_1_0.txt)
0013 //
0014 
0015 // This is meant to be the beginnings of a comprehensive, generic
0016 // test suite for STL concepts such as iterators and containers.
0017 //
0018 // Revision History:
0019 // 28 Oct 2002  Started update for new iterator categories
0020 //              (Jeremy Siek)
0021 // 28 Apr 2002  Fixed input iterator requirements.
0022 //              For a == b a++ == b++ is no longer required.
0023 //              See 24.1.1/3 for details.
0024 //              (Thomas Witt)
0025 // 08 Feb 2001  Fixed bidirectional iterator test so that
0026 //              --i is no longer a precondition.
0027 //              (Jeremy Siek)
0028 // 04 Feb 2001  Added lvalue test, corrected preconditions
0029 //              (David Abrahams)
0030 
0031 #include <boost/concept_archetype.hpp> // for detail::dummy_constructor
0032 #include <boost/iterator/is_lvalue_iterator.hpp>
0033 #include <boost/iterator/is_readable_iterator.hpp>
0034 #include <boost/pending/iterator_tests.hpp>
0035 #include <boost/core/lightweight_test.hpp>
0036 #include <boost/detail/is_incrementable.hpp>
0037 #include <boost/iterator/detail/type_traits/conjunction.hpp>
0038 
0039 #include <iterator>
0040 #include <type_traits>
0041 
0042 namespace boost {
0043 
0044 // Do separate tests for *i++ so we can treat, e.g., smart pointers,
0045 // as readable and/or writable iterators.
0046 template <class Iterator, class T>
0047 void readable_iterator_traversal_test(Iterator i1, T v, std::true_type)
0048 {
0049     T v2(*i1++);
0050     BOOST_TEST(v == v2);
0051 }
0052 
0053 template <class Iterator, class T>
0054 void readable_iterator_traversal_test(const Iterator i1, T v, std::false_type)
0055 {}
0056 
0057 template <class Iterator, class T>
0058 void writable_iterator_traversal_test(Iterator i1, T v, std::true_type)
0059 {
0060     ++i1; // we just wrote into that position
0061     *i1++ = v;
0062     Iterator x(i1++);
0063     (void)x;
0064 }
0065 
0066 template <class Iterator, class T>
0067 void writable_iterator_traversal_test(const Iterator i1, T v, std::false_type)
0068 {}
0069 
0070 // Preconditions: *i == v
0071 template <class Iterator, class T>
0072 void readable_iterator_test(const Iterator i1, T v)
0073 {
0074   Iterator i2(i1); // Copy Constructible
0075   typedef typename std::iterator_traits<Iterator>::reference ref_t;
0076   ref_t r1 = *i1;
0077   ref_t r2 = *i2;
0078   T v1 = r1;
0079   T v2 = r2;
0080   BOOST_TEST(v1 == v);
0081   BOOST_TEST(v2 == v);
0082 
0083   readable_iterator_traversal_test(
0084       i1, v,
0085       std::integral_constant<
0086           bool, detail::is_postfix_incrementable<Iterator>::value>{});
0087 
0088   // I think we don't really need this as it checks the same things as
0089   // the above code.
0090   static_assert(is_readable_iterator<Iterator>::value,
0091                 "Iterator must be readable.");
0092 }
0093 
0094 template <class Iterator, class T>
0095 void writable_iterator_test(Iterator i, T v, T v2)
0096 {
0097   Iterator i2(i); // Copy Constructible
0098   *i2 = v;
0099 
0100   writable_iterator_traversal_test(
0101       i, v2,
0102       iterators::detail::conjunction<
0103           std::integral_constant<bool, detail::is_incrementable<Iterator>::value>,
0104           std::integral_constant<bool, detail::is_postfix_incrementable<Iterator>::value>
0105       >());
0106 }
0107 
0108 template <class Iterator>
0109 void swappable_iterator_test(Iterator i, Iterator j)
0110 {
0111   Iterator i2(i), j2(j);
0112   typename std::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
0113   iter_swap(i2, j2);
0114   typename std::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
0115   BOOST_TEST(bi == aj && bj == ai);
0116 }
0117 
0118 template <class Iterator, class T>
0119 void constant_lvalue_iterator_test(Iterator i, T v1)
0120 {
0121   Iterator i2(i);
0122   typedef typename std::iterator_traits<Iterator>::value_type value_type;
0123   typedef typename std::iterator_traits<Iterator>::reference reference;
0124   static_assert(std::is_same<const value_type&, reference>::value,
0125                 "reference type must be the same as const value_type& for "
0126                 "constant lvalue iterator.");
0127   const T& v2 = *i2;
0128   BOOST_TEST(v1 == v2);
0129 #ifndef BOOST_NO_LVALUE_RETURN_DETECTION
0130   static_assert(is_lvalue_iterator<Iterator>::value
0131                 && !is_non_const_lvalue_iterator<Iterator>::value,
0132                 "Iterator must be a const lvalue iterator.");
0133 #endif
0134 }
0135 
0136 template <class Iterator, class T>
0137 void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
0138 {
0139   Iterator i2(i);
0140   typedef typename std::iterator_traits<Iterator>::value_type value_type;
0141   typedef typename std::iterator_traits<Iterator>::reference reference;
0142   static_assert(std::is_same<value_type&, reference>::value,
0143                 "reference type must be the same as value_type& for "
0144                 "non-constant lvalue iterator.");
0145   T& v3 = *i2;
0146   BOOST_TEST(v1 == v3);
0147 
0148   // A non-const lvalue iterator is not necessarily writable, but we
0149   // are assuming the value_type is assignable here
0150   *i = v2;
0151 
0152   T& v4 = *i2;
0153   BOOST_TEST(v2 == v4);
0154   static_assert(is_lvalue_iterator<Iterator>::value,
0155                 "Iterator must be an lvalue iterator.");
0156   static_assert(is_non_const_lvalue_iterator<Iterator>::value,
0157                 "Iterator must be non-const.");
0158 }
0159 
0160 template <class Iterator, class T>
0161 void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)
0162 {
0163   Iterator i2;
0164   Iterator i3(i);
0165   i2 = i;
0166   BOOST_TEST(i2 == i3);
0167   BOOST_TEST(i != j);
0168   BOOST_TEST(i2 != j);
0169   readable_iterator_test(i, val1);
0170   readable_iterator_test(i2, val1);
0171   readable_iterator_test(i3, val1);
0172 
0173   BOOST_TEST(i == i2++);
0174   BOOST_TEST(i != ++i3);
0175 
0176   readable_iterator_test(i2, val2);
0177   readable_iterator_test(i3, val2);
0178 
0179   readable_iterator_test(i, val1);
0180 }
0181 
0182 template <class Iterator, class T>
0183 void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)
0184 {
0185   forward_readable_iterator_test(i, j, val1, val2);
0186   Iterator i2 = i;
0187   ++i2;
0188   swappable_iterator_test(i, i2);
0189 }
0190 
0191 // bidirectional
0192 // Preconditions: *i == v1, *++i == v2
0193 template <class Iterator, class T>
0194 void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
0195 {
0196   Iterator j(i);
0197   ++j;
0198   forward_readable_iterator_test(i, j, v1, v2);
0199   ++i;
0200 
0201   Iterator i1 = i, i2 = i;
0202 
0203   BOOST_TEST(i == i1--);
0204   BOOST_TEST(i != --i2);
0205 
0206   readable_iterator_test(i, v2);
0207   readable_iterator_test(i1, v1);
0208   readable_iterator_test(i2, v1);
0209 
0210   --i;
0211   BOOST_TEST(i == i1);
0212   BOOST_TEST(i == i2);
0213   ++i1;
0214   ++i2;
0215 
0216   readable_iterator_test(i, v1);
0217   readable_iterator_test(i1, v2);
0218   readable_iterator_test(i2, v2);
0219 }
0220 
0221 // random access
0222 // Preconditions: [i,i+N) is a valid range
0223 template <class Iterator, class TrueVals>
0224 void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
0225 {
0226   bidirectional_readable_iterator_test(i, vals[0], vals[1]);
0227   const Iterator j = i;
0228   int c;
0229 
0230   for (c = 0; c < N - 1; ++c)
0231   {
0232     BOOST_TEST(i == j + c);
0233     BOOST_TEST(*i == vals[c]);
0234     typename std::iterator_traits<Iterator>::value_type x = j[c];
0235     BOOST_TEST(*i == x);
0236     BOOST_TEST(*i == *(j + c));
0237     BOOST_TEST(*i == *(c + j));
0238     ++i;
0239     BOOST_TEST(i > j);
0240     BOOST_TEST(i >= j);
0241     BOOST_TEST(j <= i);
0242     BOOST_TEST(j < i);
0243   }
0244 
0245   Iterator k = j + N - 1;
0246   for (c = 0; c < N - 1; ++c)
0247   {
0248     BOOST_TEST(i == k - c);
0249     BOOST_TEST(*i == vals[N - 1 - c]);
0250     typename std::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
0251     BOOST_TEST(*i == x);
0252     Iterator q = k - c;
0253     BOOST_TEST(*i == *q);
0254     BOOST_TEST(i > j);
0255     BOOST_TEST(i >= j);
0256     BOOST_TEST(j <= i);
0257     BOOST_TEST(j < i);
0258     --i;
0259   }
0260 }
0261 
0262 } // namespace boost
0263 
0264 #endif // BOOST_NEW_ITERATOR_TESTS_HPP