• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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