is_lvalue_iterator.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. #include <deque>
  5. #include <iterator>
  6. #include <iostream>
  7. #include <cstddef> // std::ptrdiff_t
  8. #include <boost/static_assert.hpp>
  9. #include <boost/noncopyable.hpp>
  10. #include <boost/iterator/is_lvalue_iterator.hpp>
  11. // Last, for BOOST_NO_LVALUE_RETURN_DETECTION
  12. #include <boost/iterator/detail/config_def.hpp>
  13. struct v
  14. {
  15. v();
  16. ~v();
  17. };
  18. struct value_iterator
  19. {
  20. typedef std::input_iterator_tag iterator_category;
  21. typedef v value_type;
  22. typedef std::ptrdiff_t difference_type;
  23. typedef v* pointer;
  24. typedef v& reference;
  25. v operator*() const;
  26. };
  27. struct noncopyable_iterator
  28. {
  29. typedef std::forward_iterator_tag iterator_category;
  30. typedef boost::noncopyable value_type;
  31. typedef std::ptrdiff_t difference_type;
  32. typedef boost::noncopyable* pointer;
  33. typedef boost::noncopyable& reference;
  34. boost::noncopyable const& operator*() const;
  35. };
  36. template <class T>
  37. struct proxy_iterator
  38. {
  39. typedef T value_type;
  40. typedef std::output_iterator_tag iterator_category;
  41. typedef std::ptrdiff_t difference_type;
  42. typedef T* pointer;
  43. typedef T& reference;
  44. struct proxy
  45. {
  46. operator value_type&() const;
  47. proxy& operator=(value_type) const;
  48. };
  49. proxy operator*() const;
  50. };
  51. template <class T>
  52. struct lvalue_iterator
  53. {
  54. typedef T value_type;
  55. typedef T& reference;
  56. typedef T difference_type;
  57. typedef std::input_iterator_tag iterator_category;
  58. typedef T* pointer;
  59. T& operator*() const;
  60. lvalue_iterator& operator++();
  61. lvalue_iterator operator++(int);
  62. };
  63. template <class T>
  64. struct constant_lvalue_iterator
  65. {
  66. typedef T value_type;
  67. typedef T const& reference;
  68. typedef T difference_type;
  69. typedef std::input_iterator_tag iterator_category;
  70. typedef T const* pointer;
  71. T const& operator*() const;
  72. constant_lvalue_iterator& operator++();
  73. constant_lvalue_iterator operator++(int);
  74. };
  75. int main()
  76. {
  77. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v*>::value);
  78. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v const*>::value);
  79. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::iterator>::value);
  80. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value);
  81. BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
  82. BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::ostream_iterator<v> >::value);
  83. BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<v> >::value);
  84. BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<int> >::value);
  85. #ifndef BOOST_NO_LVALUE_RETURN_DETECTION
  86. BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<value_iterator>::value);
  87. #endif
  88. // Make sure inaccessible copy constructor doesn't prevent
  89. // reference binding
  90. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value);
  91. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<v> >::value);
  92. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<int> >::value);
  93. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<char*> >::value);
  94. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<float> >::value);
  95. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<v> >::value);
  96. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<int> >::value);
  97. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
  98. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<float> >::value);
  99. BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<v*>::value);
  100. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<v const*>::value);
  101. BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value);
  102. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value);
  103. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
  104. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::ostream_iterator<v> >::value);
  105. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<v> >::value);
  106. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<int> >::value);
  107. #ifndef BOOST_NO_LVALUE_RETURN_DETECTION
  108. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<value_iterator>::value);
  109. #endif
  110. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value);
  111. BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<v> >::value);
  112. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  113. BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<int> >::value);
  114. #endif
  115. BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<char*> >::value);
  116. BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<float> >::value);
  117. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v> >::value);
  118. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int> >::value);
  119. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
  120. BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float> >::value);
  121. return 0;
  122. }