File: addressof.cpp

package info (click to toggle)
range-v3 0.12.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,652 kB
  • sloc: cpp: 76,839; xml: 226; sh: 89; python: 34; makefile: 19; perl: 15
file content (129 lines) | stat: -rw-r--r-- 2,824 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/// \file
// Range v3 library
//
//  Copyright Andrey Diduh 2019
//
//  Use, modification and distribution is subject to 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)
//
// Project home: https://github.com/ericniebler/range-v3
//

#include <sstream>
#include <vector>

#include <range/v3/core.hpp>
#include <range/v3/view/addressof.hpp>
#include <range/v3/view/facade.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/take.hpp>

#include "../simple_test.hpp"
#include "../test_utils.hpp"

using namespace ranges;

void simple_test()
{
    std::vector<int> list = {1,2,3};

    auto out = list | views::addressof;

    check_equal(out, {&list[0], &list[1], &list[2]});
}

struct test_istream_range
  : view_facade<test_istream_range, unknown>
{
private:
    friend range_access;

    std::vector<int> *list;

    struct cursor
    {
    private:
        std::size_t i = 0;
        std::vector<int> *list = nullptr;
    public:
        cursor() = default;
        explicit cursor(std::vector<int> &list_)
          : list(&list_)
        {}
        void next()
        {
            ++i;
        }
        int &read() const noexcept
        {
            return (*list)[i];
        }
        bool equal(default_sentinel_t) const
        {
            return i == list->size();
        }
    };

    cursor begin_cursor()
    {
        return cursor{*list};
    }
public:
    test_istream_range() = default;
    explicit test_istream_range(std::vector<int> &list_)
      : list(&list_)
    {}
};

void test_input_range()
{
    // It is implementation dependent,
    // for how long returned reference remains valid.
    // It should be valid at least until next read.
    // For test purposes we use custom input range.

    std::vector<int> list{1, 2, 3};
    auto rng = test_istream_range(list);
    CPP_assert(input_range<decltype(rng)>);

    auto out = rng | views::addressof;
    check_equal(out, {&list[0], &list[1], &list[2]});
}

struct test_xvalue_range
  : view_facade<test_xvalue_range, unknown>
{
private:
    friend range_access;

    struct cursor
    {
        cursor() = default;
        void next();
        int &&read() const noexcept;
        bool equal(default_sentinel_t) const;
    };

    cursor begin_cursor();
};

template<typename, typename = void>
constexpr bool can_view = false;
template<typename R>
constexpr bool can_view<R,
    meta::void_<decltype(views::addressof(std::declval<R>()))>> = true;

// prvalue ranges cannot be passed to views::addressof
CPP_assert(!can_view<decltype(views::iota(0, 3))>);
// xvalue ranges cannot be passed to views::addressof
CPP_assert(!can_view<test_xvalue_range>);

int main()
{
    simple_test();
    test_input_range();

    return test_result();
}