1// Copyright (C) 2019 T. Zachary Laine
2//
3// Distributed under the Boost Software License, Version 1.0. (See
4// accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6#include <boost/stl_interfaces/iterator_interface.hpp>
7
8#include <boost/core/lightweight_test.hpp>
9
10#include <array>
11#include <numeric>
12#include <vector>
13#include <type_traits>
14
15
16struct basic_output_iter
17 : boost::stl_interfaces::iterator_interface<
18#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
19 basic_output_iter,
20#endif
21 std::output_iterator_tag, int>
22{
23 basic_output_iter() : it_(nullptr) {}
24 basic_output_iter(int * it) : it_(it) {}
25
26 int & operator*() noexcept { return *it_; }
27 basic_output_iter & operator++() noexcept
28 {
29 ++it_;
30 return *this;
31 }
32
33 using base_type = boost::stl_interfaces::iterator_interface<
34#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
35 basic_output_iter,
36#endif
37 std::output_iterator_tag, int>;
38 using base_type::operator++;
39
40private:
41 int * it_;
42};
43
44using output = basic_output_iter;
45
46#if BOOST_STL_INTERFACES_USE_CONCEPTS
47static_assert(std::output_iterator<output, int>, "");
48BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
49 output,
50 void,
51 std::output_iterator_tag,
52 void,
53 void,
54 void,
55 std::ptrdiff_t)
56#else
57BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
58 output,
59 std::output_iterator_tag,
60 std::output_iterator_tag,
61 int,
62 int &,
63 void,
64 std::ptrdiff_t)
65#endif
66
67
68template<typename Container>
69struct back_insert_iter : boost::stl_interfaces::iterator_interface<
70#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
71 back_insert_iter<Container>,
72#endif
73 std::output_iterator_tag,
74 typename Container::value_type,
75 back_insert_iter<Container> &>
76{
77 back_insert_iter() : c_(nullptr) {}
78 back_insert_iter(Container & c) : c_(std::addressof(c)) {}
79
80 back_insert_iter & operator*() noexcept { return *this; }
81 back_insert_iter & operator++() noexcept { return *this; }
82
83 back_insert_iter & operator=(typename Container::value_type const & v)
84 {
85 c_->push_back(v);
86 return *this;
87 }
88 back_insert_iter & operator=(typename Container::value_type && v)
89 {
90 c_->push_back(std::move(v));
91 return *this;
92 }
93
94 using base_type = boost::stl_interfaces::iterator_interface<
95#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
96 back_insert_iter<Container>,
97#endif
98 std::output_iterator_tag,
99 typename Container::value_type,
100 back_insert_iter<Container> &>;
101 using base_type::operator++;
102
103private:
104 Container * c_;
105};
106
107using back_insert = back_insert_iter<std::vector<int>>;
108
109#if BOOST_STL_INTERFACES_USE_CONCEPTS
110static_assert(std::output_iterator<back_insert, int>, "");
111BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
112 back_insert,
113 void,
114 std::output_iterator_tag,
115 void,
116 void,
117 void,
118 std::ptrdiff_t)
119#else
120BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
121 back_insert,
122 std::output_iterator_tag,
123 std::output_iterator_tag,
124 int,
125 back_insert &,
126 void,
127 std::ptrdiff_t)
128#endif
129
130
131std::vector<int> ints = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
132
133
134int main()
135{
136
137{
138 std::vector<int> ints_copy(ints.size());
139 std::copy(first: ints.begin(), last: ints.end(), result: output(&ints_copy[0]));
140 BOOST_TEST(ints_copy == ints);
141}
142
143
144{
145 std::vector<int> ints_copy;
146 std::copy(first: ints.begin(), last: ints.end(), result: back_insert(ints_copy));
147 BOOST_TEST(ints_copy == ints);
148}
149
150 return boost::report_errors();
151}
152

source code of boost/libs/stl_interfaces/test/output.cpp