1 // Copyright David Abrahams 2003. Use, modification and distribution is 2 // subject to the Boost Software License, Version 1.0. (See accompanying 3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 5 #include <deque> 6 #include <iterator> 7 #include <iostream> 8 #include <cstddef> // std::ptrdiff_t 9 #include <boost/static_assert.hpp> 10 #include <boost/noncopyable.hpp> 11 #include <boost/iterator/is_lvalue_iterator.hpp> 12 13 // Last, for BOOST_NO_LVALUE_RETURN_DETECTION 14 #include <boost/iterator/detail/config_def.hpp> 15 16 struct v 17 { 18 v(); 19 ~v(); 20 }; 21 22 23 struct value_iterator 24 { 25 typedef std::input_iterator_tag iterator_category; 26 typedef v value_type; 27 typedef std::ptrdiff_t difference_type; 28 typedef v* pointer; 29 typedef v& reference; 30 31 v operator*() const; 32 }; 33 34 struct noncopyable_iterator 35 { 36 typedef std::forward_iterator_tag iterator_category; 37 typedef boost::noncopyable value_type; 38 typedef std::ptrdiff_t difference_type; 39 typedef boost::noncopyable* pointer; 40 typedef boost::noncopyable& reference; 41 42 boost::noncopyable const& operator*() const; 43 }; 44 45 template <class T> 46 struct proxy_iterator 47 { 48 typedef T value_type; 49 typedef std::output_iterator_tag iterator_category; 50 typedef std::ptrdiff_t difference_type; 51 typedef T* pointer; 52 typedef T& reference; 53 54 struct proxy 55 { 56 operator value_type&() const; 57 proxy& operator=(value_type) const; 58 }; 59 60 proxy operator*() const; 61 }; 62 63 template <class T> 64 struct lvalue_iterator 65 { 66 typedef T value_type; 67 typedef T& reference; 68 typedef T difference_type; 69 typedef std::input_iterator_tag iterator_category; 70 typedef T* pointer; 71 72 T& operator*() const; 73 lvalue_iterator& operator++(); 74 lvalue_iterator operator++(int); 75 }; 76 77 template <class T> 78 struct constant_lvalue_iterator 79 { 80 typedef T value_type; 81 typedef T const& reference; 82 typedef T difference_type; 83 typedef std::input_iterator_tag iterator_category; 84 typedef T const* pointer; 85 86 T const& operator*() const; 87 constant_lvalue_iterator& operator++(); 88 constant_lvalue_iterator operator++(int); 89 }; 90 91 main()92int main() 93 { 94 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v*>::value); 95 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v const*>::value); 96 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::iterator>::value); 97 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value); 98 BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value); 99 BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::ostream_iterator<v> >::value); 100 BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<v> >::value); 101 BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<int> >::value); 102 #ifndef BOOST_NO_LVALUE_RETURN_DETECTION 103 BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<value_iterator>::value); 104 #endif 105 // Make sure inaccessible copy constructor doesn't prevent 106 // reference binding 107 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value); 108 109 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<v> >::value); 110 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<int> >::value); 111 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<char*> >::value); 112 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<float> >::value); 113 114 115 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<v> >::value); 116 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<int> >::value); 117 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<char*> >::value); 118 BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<float> >::value); 119 120 121 122 BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<v*>::value); 123 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<v const*>::value); 124 BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value); 125 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value); 126 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value); 127 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::ostream_iterator<v> >::value); 128 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<v> >::value); 129 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<int> >::value); 130 #ifndef BOOST_NO_LVALUE_RETURN_DETECTION 131 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<value_iterator>::value); 132 #endif 133 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value); 134 135 BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<v> >::value); 136 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) 137 BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<int> >::value); 138 #endif 139 BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<char*> >::value); 140 BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<float> >::value); 141 142 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v> >::value); 143 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int> >::value); 144 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*> >::value); 145 BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float> >::value); 146 147 return 0; 148 } 149