mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-09 23:23:54 +00:00
С++03 support was deprecated in 1.85 and now can be removed. This PR clears many of workarounds, which are no longer needed now. * Remove unused workaround macros (many of). * Remove BOOST_STATIC_ASSERT usages. * Minimize Boost::type_traits dependency (in favour of STL's type_traits). Closes https://github.com/boostorg/iterator/pull/82. Squashed commit of the following: commit 741a627b736ba81fe0054e5bf373141b04a8a597 Author: Georgy Guminov <gogagum@gmail.com> Date: Sat Jan 25 12:13:05 2025 +0300 Replace testers with standard metafunctions. commit bf4cce611454713f1c8e5f46a2c3e599c548656d Author: Georgy Guminov <gogagum@gmail.com> Date: Sat Jan 25 11:51:32 2025 +0300 Refactor is_lvalue_iterator.hpp. commit 8d080c6c58726269cf55aedd64aa239f7d098fc7 Author: Georgy Guminov <gogagum@gmail.com> Date: Sat Jan 25 10:27:32 2025 +0300 Remove more workarounds. commit 5a4ba24d361ac0676d2cce95fdff22824ecdc287 Author: Georgy Guminov <gogagum@gmail.com> Date: Sun Jan 19 16:38:30 2025 +0300 Fixes. commit fdfafce2b9a71b1d85cbc697983652788f1c4bb7 Author: Georgy Guminov <gogagum@gmail.com> Date: Sat Oct 26 15:06:43 2024 +0300 Remove BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY Correct static_assert messages. Fix messages & replace is_standard_layout with is_copy_constructible. commit c69ac1408af2fe5a105b288644367bbb6e0bc30d Author: Georgy Guminov <gogagum@gmail.com> Date: Sat Oct 26 14:48:51 2024 +0300 Correct static_assert messages. commit b5df827151a6d752168a59fa8c20c9ffd3766c0b Author: Georqy Guminov <gogagum@gmail.com> Date: Sun Jun 23 16:12:29 2024 +0300 Fixes. Remove some Boost.MPL usages. Remove unused includes. commit 01fd35e9f87d43f4bb46ed525a0e8eec46cba44a Author: Georgiy Guminov <gogagum@gmail.com> Date: Wed Jun 12 17:14:21 2024 +0300 abstract conjunction. commit c02def8acf68e0829082761d26955320974e5078 Author: Georgiy Guminov <gogagum@gmail.com> Date: Wed Jun 12 16:35:43 2024 +0300 return addressof & conjunction. commit 3b3d1625752cbe8c9ec62662e594a1af1fd9a458 Author: Georgiy Guminov <gogagum@gmail.com> Date: Wed Jun 12 16:30:44 2024 +0300 Make macro more readable. commit 4ab19e045fc535dc80228062d11bb6584ccd17ff Author: Georgiy Guminov <gogagum@gmail.com> Date: Wed Jun 12 15:56:49 2024 +0300 Add static_assert messages. commit 82b5c44cd34435d63af5cdbc7fcc1b07b39394de Author: Georgiy Guminov <gogagum@gmail.com> Date: Wed Jun 12 14:12:10 2024 +0300 Return is iterator CXX17 test. commit 2d58d65462e837430a0990c2a414d5c397e9fa31 Author: Georgiy Guminov <gogagum@gmail.com> Date: Tue Jun 11 14:04:17 2024 +0300 Omitted. commit a0d04d9491de818df990188436e04afc3ddba3ad Author: Georgiy Guminov <gogagum@gmail.com> Date: Tue Jun 11 14:00:35 2024 +0300 Replace move with static_cast commit 4a49b8a1a2d44d2da728dd064fe810ca86d8d1fd Author: Georgiy Guminov <gogagum@gmail.com> Date: Mon Jun 10 21:38:53 2024 +0300 Return BOOST_NOEXCEPT commit 054c013bba75c42710537a819de91d6abfe25658 Author: Georgiy Guminov <gogagum@gmail.com> Date: Sun Jun 9 15:20:41 2024 +0300 CXX11
261 lines
5.8 KiB
C++
261 lines
5.8 KiB
C++
// Copyright David Abrahams 2004. Distributed under the Boost
|
|
// Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
// This is really an incomplete test; should be fleshed out.
|
|
|
|
#include <boost/iterator/iterator_facade.hpp>
|
|
#include <boost/iterator/new_iterator_tests.hpp>
|
|
|
|
#include <boost/call_traits.hpp>
|
|
#include <type_traits>
|
|
|
|
#include "static_assert_same.hpp"
|
|
|
|
// This is a really, really limited test so far. All we're doing
|
|
// right now is checking that the postfix++ proxy for single-pass
|
|
// iterators works properly.
|
|
template <class Ref>
|
|
class counter_iterator
|
|
: public boost::iterator_facade<
|
|
counter_iterator<Ref>
|
|
, int const
|
|
, boost::single_pass_traversal_tag
|
|
, Ref
|
|
>
|
|
{
|
|
public:
|
|
counter_iterator() {}
|
|
counter_iterator(int* state) : state(state) {}
|
|
|
|
void increment()
|
|
{
|
|
++*state;
|
|
}
|
|
|
|
Ref
|
|
dereference() const
|
|
{
|
|
return *state;
|
|
}
|
|
|
|
bool equal(counter_iterator const& y) const
|
|
{
|
|
return *this->state == *y.state;
|
|
}
|
|
|
|
int* state;
|
|
};
|
|
|
|
struct proxy
|
|
{
|
|
proxy(int& x) : state(x) {}
|
|
|
|
operator int const&() const
|
|
{
|
|
return state;
|
|
}
|
|
|
|
int& operator=(int x) { state = x; return state; }
|
|
|
|
int& state;
|
|
};
|
|
|
|
struct value
|
|
{
|
|
int increment_count;
|
|
int private_mutator_count;
|
|
int& shared_mutator_count;
|
|
|
|
explicit value(int& shared_mutator_count) :
|
|
increment_count(0),
|
|
private_mutator_count(0),
|
|
shared_mutator_count(shared_mutator_count)
|
|
{
|
|
}
|
|
|
|
// non-const member function
|
|
void mutator()
|
|
{
|
|
++private_mutator_count;
|
|
++shared_mutator_count;
|
|
}
|
|
};
|
|
|
|
struct input_iter
|
|
: boost::iterator_facade<
|
|
input_iter
|
|
, value
|
|
, boost::single_pass_traversal_tag
|
|
, value
|
|
>
|
|
{
|
|
public:
|
|
explicit input_iter(value& val) : state(&val) {}
|
|
|
|
void increment()
|
|
{
|
|
++(state->increment_count);
|
|
}
|
|
value
|
|
dereference() const
|
|
{
|
|
return *state;
|
|
}
|
|
|
|
bool equal(input_iter const&) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
value* state;
|
|
};
|
|
|
|
template <class T>
|
|
struct wrapper
|
|
{
|
|
T m_x;
|
|
explicit wrapper(typename boost::call_traits<T>::param_type x)
|
|
: m_x(x)
|
|
{ }
|
|
template <class U>
|
|
wrapper(const wrapper<U>& other,
|
|
typename std::enable_if< std::is_convertible<U,T>::value >::type* = 0)
|
|
: m_x(other.m_x)
|
|
{ }
|
|
};
|
|
|
|
struct iterator_with_proxy_reference
|
|
: boost::iterator_facade<
|
|
iterator_with_proxy_reference
|
|
, wrapper<int>
|
|
, boost::incrementable_traversal_tag
|
|
, wrapper<int&>
|
|
>
|
|
{
|
|
int& m_x;
|
|
explicit iterator_with_proxy_reference(int& x)
|
|
: m_x(x)
|
|
{ }
|
|
|
|
void increment()
|
|
{ }
|
|
wrapper<int&> dereference() const
|
|
{ return wrapper<int&>(m_x); }
|
|
};
|
|
|
|
template <class I, class A>
|
|
struct abstract_iterator
|
|
: boost::iterator_facade<
|
|
abstract_iterator<I, A>
|
|
, A&
|
|
// In order to be value type as a reference, traversal category has
|
|
// to satisfy least forward traversal.
|
|
, boost::forward_traversal_tag
|
|
, A&
|
|
>
|
|
{
|
|
abstract_iterator(I iter) : iter(iter) {}
|
|
|
|
void increment()
|
|
{ ++iter; }
|
|
|
|
A& dereference() const
|
|
{ return *iter; }
|
|
|
|
bool equal(abstract_iterator const& y) const
|
|
{ return iter == y.iter; }
|
|
|
|
I iter;
|
|
};
|
|
|
|
struct base
|
|
{
|
|
virtual void assign(const base&) = 0;
|
|
virtual bool equal(const base&) const = 0;
|
|
};
|
|
|
|
struct derived : base
|
|
{
|
|
derived(int state) : state(state) { }
|
|
derived(const derived& d) : state(d.state) { }
|
|
derived(const base& b) { derived::assign(b); }
|
|
|
|
virtual void assign(const base& b)
|
|
{
|
|
state = dynamic_cast<const derived& >(b).state;
|
|
}
|
|
|
|
virtual bool equal(const base& b) const
|
|
{
|
|
return state == dynamic_cast<const derived&>(b).state;
|
|
}
|
|
|
|
int state;
|
|
};
|
|
|
|
inline bool operator==(const base& lhs, const base& rhs)
|
|
{
|
|
return lhs.equal(rhs);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
{
|
|
int state = 0;
|
|
boost::readable_iterator_test(counter_iterator<int const&>(&state), 0);
|
|
state = 3;
|
|
boost::readable_iterator_test(counter_iterator<proxy>(&state), 3);
|
|
boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7);
|
|
BOOST_TEST(state == 8);
|
|
}
|
|
|
|
{
|
|
// test for a fix to http://tinyurl.com/zuohe
|
|
// These two lines should be equivalent (and both compile)
|
|
int shared_mutator_count = 0;
|
|
value val(shared_mutator_count);
|
|
input_iter p(val);
|
|
(*p).mutator();
|
|
p->mutator();
|
|
BOOST_TEST_EQ(val.increment_count, 0);
|
|
BOOST_TEST_EQ(val.private_mutator_count, 0); // mutator() should be invoked on an object returned by value
|
|
BOOST_TEST_EQ(shared_mutator_count, 2);
|
|
|
|
STATIC_ASSERT_SAME(input_iter::pointer, std::remove_cv<std::remove_reference<decltype(p.operator->())>::type>::type);
|
|
}
|
|
|
|
{
|
|
// Test that accessing dereferenced value of a post-incremented iterator works
|
|
int shared_mutator_count = 0;
|
|
value val(shared_mutator_count);
|
|
input_iter p(val);
|
|
(*p++).mutator();
|
|
(p++)->mutator();
|
|
BOOST_TEST_EQ(val.increment_count, 2);
|
|
BOOST_TEST_EQ(val.private_mutator_count, 0); // mutator() should be invoked on an object returned by value
|
|
BOOST_TEST_EQ(shared_mutator_count, 2);
|
|
}
|
|
|
|
{
|
|
int x = 0;
|
|
iterator_with_proxy_reference i(x);
|
|
BOOST_TEST(x == 0);
|
|
BOOST_TEST(i.m_x == 0);
|
|
++(*i).m_x;
|
|
BOOST_TEST(x == 1);
|
|
BOOST_TEST(i.m_x == 1);
|
|
++i->m_x;
|
|
BOOST_TEST(x == 2);
|
|
BOOST_TEST(i.m_x == 2);
|
|
}
|
|
|
|
{
|
|
derived d(1);
|
|
boost::readable_iterator_test(abstract_iterator<derived *, base>(&d), derived(1));
|
|
}
|
|
|
|
return boost::report_errors();
|
|
}
|