iterator_ext.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Boost.Range library
  2. //
  3. // Copyright Neil Groves 2014. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // For more information, see http://www.boost.org/libs/range/
  9. //
  10. #include <boost/range/iterator.hpp>
  11. #include <boost/static_assert.hpp>
  12. #include <boost/type_traits/is_same.hpp>
  13. #include <boost/type_traits/is_base_of.hpp>
  14. #include <boost/type_traits/decay.hpp>
  15. #include <boost/test/test_tools.hpp>
  16. #include <boost/test/unit_test.hpp>
  17. #include <vector>
  18. namespace boost_range_test
  19. {
  20. struct point
  21. {
  22. int x;
  23. int y;
  24. };
  25. class shape
  26. {
  27. public:
  28. virtual ~shape()
  29. {
  30. }
  31. const std::vector<point>& points() const
  32. {
  33. return m_points;
  34. }
  35. private:
  36. std::vector<point> m_points;
  37. };
  38. class rectangle : public shape
  39. {
  40. };
  41. class circle : public shape
  42. {
  43. };
  44. class container
  45. {
  46. typedef std::vector<point> impl_t;
  47. };
  48. } // namespace boost_range_test
  49. namespace boost
  50. {
  51. template<typename T>
  52. struct range_mutable_iterator<
  53. T,
  54. typename boost::enable_if<
  55. boost::is_base_of<
  56. boost_range_test::shape,
  57. typename boost::remove_reference<
  58. typename boost::remove_cv<T>::type
  59. >::type
  60. >
  61. >::type
  62. >
  63. {
  64. typedef std::vector<boost_range_test::point>::iterator type;
  65. };
  66. template<typename T>
  67. struct range_const_iterator<
  68. T,
  69. typename boost::enable_if<
  70. boost::is_base_of<
  71. boost_range_test::shape,
  72. typename boost::remove_reference<
  73. typename boost::remove_cv<T>::type
  74. >::type
  75. >
  76. >::type
  77. >
  78. {
  79. typedef std::vector<boost_range_test::point>::const_iterator type;
  80. };
  81. template<>
  82. struct range_mutable_iterator<boost_range_test::container>
  83. {
  84. typedef std::vector<boost_range_test::point>::iterator type;
  85. };
  86. template<>
  87. struct range_const_iterator<boost_range_test::container>
  88. {
  89. typedef std::vector<boost_range_test::point>::const_iterator type;
  90. };
  91. }
  92. namespace boost_range_test
  93. {
  94. template<typename Shape>
  95. void test_iterator_impl()
  96. {
  97. BOOST_STATIC_ASSERT((
  98. boost::is_same<
  99. std::vector<point>::iterator,
  100. typename boost::range_iterator<Shape>::type
  101. >::value));
  102. BOOST_STATIC_ASSERT((
  103. boost::is_same<
  104. std::vector<point>::const_iterator,
  105. typename boost::range_iterator<const Shape>::type
  106. >::value));
  107. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  108. BOOST_STATIC_ASSERT((
  109. boost::is_same<
  110. std::vector<point>::iterator,
  111. typename boost::range_iterator<Shape&&>::type
  112. >::value));
  113. #endif
  114. }
  115. void test_iterator()
  116. {
  117. test_iterator_impl<shape>();
  118. test_iterator_impl<rectangle>();
  119. test_iterator_impl<circle>();
  120. test_iterator_impl<container>();
  121. }
  122. } // namespace boost_range_test
  123. boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
  124. {
  125. boost::unit_test::test_suite* test =
  126. BOOST_TEST_SUITE("Boost.Range range_iterator meta-function");
  127. test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator));
  128. return test;
  129. }