mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 20:40:28 -04:00 
			
		
		
		
	
		
			
	
	
		
			228 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			228 lines
		
	
	
		
			4.7 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 <boost/polymorphic_cast.hpp>
 | ||
|  | #include <boost/type_traits/is_convertible.hpp>
 | ||
|  | #include <boost/utility/enable_if.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 | ||
|  | { | ||
|  |     void mutator() {} // non-const member function
 | ||
|  | }; | ||
|  | 
 | ||
|  | struct input_iter | ||
|  |   : boost::iterator_facade< | ||
|  |         input_iter | ||
|  |       , value | ||
|  |       , boost::single_pass_traversal_tag | ||
|  |       , value | ||
|  |     > | ||
|  | { | ||
|  |  public: | ||
|  |     input_iter() {} | ||
|  | 
 | ||
|  |     void increment() | ||
|  |     { | ||
|  |     } | ||
|  |     value | ||
|  |     dereference() const | ||
|  |     { | ||
|  |         return value(); | ||
|  |     } | ||
|  | 
 | ||
|  |     bool equal(input_iter const& y) const | ||
|  |     { | ||
|  |         return false; | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | 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 boost::enable_if< boost::is_convertible<U,T> >::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 T, class U> | ||
|  | void same_type(U const&) | ||
|  | { BOOST_MPL_ASSERT((boost::is_same<T,U>)); } | ||
|  | 
 | ||
|  | 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 = boost::polymorphic_cast<const derived *>(&b)->state; | ||
|  |     } | ||
|  | 
 | ||
|  |     virtual bool equal(const base &b) const | ||
|  |     { | ||
|  |         return state == boost::polymorphic_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)
 | ||
|  |         input_iter p; | ||
|  |         (*p).mutator(); | ||
|  |         p->mutator(); | ||
|  | 
 | ||
|  |         same_type<input_iter::pointer>(p.operator->()); | ||
|  |     } | ||
|  | 
 | ||
|  |     { | ||
|  |         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(); | ||
|  | } |