addressof.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Andrey Diduh 2019
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #include <sstream>
  14. #include <vector>
  15. #include <range/v3/core.hpp>
  16. #include <range/v3/view/addressof.hpp>
  17. #include <range/v3/view/facade.hpp>
  18. #include <range/v3/view/iota.hpp>
  19. #include <range/v3/view/take.hpp>
  20. #include "../simple_test.hpp"
  21. #include "../test_utils.hpp"
  22. using namespace ranges;
  23. void simple_test()
  24. {
  25. std::vector<int> list = {1,2,3};
  26. auto out = list | views::addressof;
  27. check_equal(out, {&list[0], &list[1], &list[2]});
  28. }
  29. struct test_istream_range
  30. : view_facade<test_istream_range, unknown>
  31. {
  32. private:
  33. friend range_access;
  34. std::vector<int> *list;
  35. struct cursor
  36. {
  37. private:
  38. std::size_t i = 0;
  39. std::vector<int> *list = nullptr;
  40. public:
  41. cursor() = default;
  42. explicit cursor(std::vector<int> &list_)
  43. : list(&list_)
  44. {}
  45. void next()
  46. {
  47. ++i;
  48. }
  49. int &read() const noexcept
  50. {
  51. return (*list)[i];
  52. }
  53. bool equal(default_sentinel_t) const
  54. {
  55. return i == list->size();
  56. }
  57. };
  58. cursor begin_cursor()
  59. {
  60. return cursor{*list};
  61. }
  62. public:
  63. test_istream_range() = default;
  64. explicit test_istream_range(std::vector<int> &list_)
  65. : list(&list_)
  66. {}
  67. };
  68. void test_input_range()
  69. {
  70. // It is implementation dependent,
  71. // for how long returned reference remains valid.
  72. // It should be valid at least until next read.
  73. // For test purposes we use custom input range.
  74. std::vector<int> list{1, 2, 3};
  75. auto rng = test_istream_range(list);
  76. CPP_assert(input_range<decltype(rng)>);
  77. auto out = rng | views::addressof;
  78. check_equal(out, {&list[0], &list[1], &list[2]});
  79. }
  80. struct test_xvalue_range
  81. : view_facade<test_xvalue_range, unknown>
  82. {
  83. private:
  84. friend range_access;
  85. struct cursor
  86. {
  87. cursor() = default;
  88. void next();
  89. int &&read() const noexcept;
  90. bool equal(default_sentinel_t) const;
  91. };
  92. cursor begin_cursor();
  93. };
  94. template<typename, typename = void>
  95. constexpr bool can_view = false;
  96. template<typename R>
  97. constexpr bool can_view<R,
  98. meta::void_<decltype(views::addressof(std::declval<R>()))>> = true;
  99. // prvalue ranges cannot be passed to views::addressof
  100. CPP_assert(!can_view<decltype(views::iota(0, 3))>);
  101. // xvalue ranges cannot be passed to views::addressof
  102. CPP_assert(!can_view<test_xvalue_range>);
  103. int main()
  104. {
  105. simple_test();
  106. test_input_range();
  107. return test_result();
  108. }