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
16 struct basic_output_iter
17 : boost::stl_interfaces::
18 iterator_interface<basic_output_iter, std::output_iterator_tag, int>
19 {
basic_output_iterbasic_output_iter20 basic_output_iter() : it_(nullptr) {}
basic_output_iterbasic_output_iter21 basic_output_iter(int * it) : it_(it) {}
22
operator *basic_output_iter23 int & operator*() noexcept { return *it_; }
operator ++basic_output_iter24 basic_output_iter & operator++() noexcept
25 {
26 ++it_;
27 return *this;
28 }
29
30 using base_type = boost::stl_interfaces::
31 iterator_interface<basic_output_iter, std::output_iterator_tag, int>;
32 using base_type::operator++;
33
34 private:
35 int * it_;
36 };
37
38 using output = basic_output_iter;
39
40 #if 201703L < __cplusplus && defined(__cpp_lib_concepts)
41 static_assert(std::output_iterator<output, int>, "");
42 #endif
43 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
44 output,
45 std::output_iterator_tag,
46 std::output_iterator_tag,
47 int,
48 int &,
49 void,
50 std::ptrdiff_t)
51
52 template<typename Container>
53 struct back_insert_iter : boost::stl_interfaces::iterator_interface<
54 back_insert_iter<Container>,
55 std::output_iterator_tag,
56 typename Container::value_type,
57 back_insert_iter<Container> &>
58 {
back_insert_iterback_insert_iter59 back_insert_iter() : c_(nullptr) {}
back_insert_iterback_insert_iter60 back_insert_iter(Container & c) : c_(std::addressof(c)) {}
61
operator *back_insert_iter62 back_insert_iter & operator*() noexcept { return *this; }
operator ++back_insert_iter63 back_insert_iter & operator++() noexcept { return *this; }
64
operator =back_insert_iter65 back_insert_iter & operator=(typename Container::value_type const & v)
66 {
67 c_->push_back(v);
68 return *this;
69 }
operator =back_insert_iter70 back_insert_iter & operator=(typename Container::value_type && v)
71 {
72 c_->push_back(std::move(v));
73 return *this;
74 }
75
76 using base_type = boost::stl_interfaces::iterator_interface<
77 back_insert_iter<Container>,
78 std::output_iterator_tag,
79 typename Container::value_type,
80 back_insert_iter<Container> &>;
81 using base_type::operator++;
82
83 private:
84 Container * c_;
85 };
86
87 using back_insert = back_insert_iter<std::vector<int>>;
88
89 #if 201703L < __cplusplus && defined(__cpp_lib_concepts)
90 static_assert(std::output_iterator<back_insert, int>, "");
91 #endif
92 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
93 back_insert,
94 std::output_iterator_tag,
95 std::output_iterator_tag,
96 int,
97 back_insert &,
98 void,
99 std::ptrdiff_t)
100
101
102 std::vector<int> ints = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
103
104
main()105 int main()
106 {
107
108 {
109 std::vector<int> ints_copy(ints.size());
110 std::copy(ints.begin(), ints.end(), output(&ints_copy[0]));
111 BOOST_TEST(ints_copy == ints);
112 }
113
114
115 {
116 std::vector<int> ints_copy;
117 std::copy(ints.begin(), ints.end(), back_insert(ints_copy));
118 BOOST_TEST(ints_copy == ints);
119 }
120
121
122 {
123 std::vector<int> ints_copy;
124 back_insert out(ints_copy);
125 for (int i = 0; i < 10; ++i)
126 out++;
127 }
128
129 return boost::report_errors();
130 }
131