File indexing completed on 2025-01-18 10:09:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef RANGES_V3_ITERATOR_INSERT_ITERATORS_HPP
0014 #define RANGES_V3_ITERATOR_INSERT_ITERATORS_HPP
0015
0016 #include <cstddef>
0017 #include <utility>
0018
0019 #include <range/v3/range_fwd.hpp>
0020
0021 #include <range/v3/iterator/operations.hpp>
0022 #include <range/v3/utility/addressof.hpp>
0023
0024 #include <range/v3/detail/prologue.hpp>
0025
0026 namespace ranges
0027 {
0028
0029
0030 template<typename Container>
0031 struct back_insert_iterator
0032 {
0033 using container_type = Container;
0034 using difference_type = std::ptrdiff_t;
0035
0036 constexpr back_insert_iterator() = default;
0037 constexpr explicit back_insert_iterator(Container & x)
0038 : container_(detail::addressof(x))
0039 {}
0040 back_insert_iterator & operator=(typename Container::value_type const & value)
0041 {
0042 container_->push_back(value);
0043 return *this;
0044 }
0045 back_insert_iterator & operator=(typename Container::value_type && value)
0046 {
0047 container_->push_back(std::move(value));
0048 return *this;
0049 }
0050 back_insert_iterator & operator*()
0051 {
0052 return *this;
0053 }
0054 back_insert_iterator & operator++()
0055 {
0056 return *this;
0057 }
0058 back_insert_iterator operator++(int)
0059 {
0060 return *this;
0061 }
0062
0063 private:
0064 Container * container_ = nullptr;
0065 };
0066
0067 struct back_inserter_fn
0068 {
0069 template<typename Container>
0070 constexpr back_insert_iterator<Container> operator()(Container & x) const
0071 {
0072 return back_insert_iterator<Container>{x};
0073 }
0074 };
0075
0076
0077 RANGES_INLINE_VARIABLE(back_inserter_fn, back_inserter)
0078
0079 template<typename Container>
0080 struct front_insert_iterator
0081 {
0082 using container_type = Container;
0083 using difference_type = std::ptrdiff_t;
0084
0085 constexpr front_insert_iterator() = default;
0086 constexpr explicit front_insert_iterator(Container & x)
0087 : container_(detail::addressof(x))
0088 {}
0089 front_insert_iterator & operator=(typename Container::value_type const & value)
0090 {
0091 container_->push_front(value);
0092 return *this;
0093 }
0094 front_insert_iterator & operator=(typename Container::value_type && value)
0095 {
0096 container_->push_front(std::move(value));
0097 return *this;
0098 }
0099 front_insert_iterator & operator*()
0100 {
0101 return *this;
0102 }
0103 front_insert_iterator & operator++()
0104 {
0105 return *this;
0106 }
0107 front_insert_iterator operator++(int)
0108 {
0109 return *this;
0110 }
0111
0112 private:
0113 Container * container_ = nullptr;
0114 };
0115
0116 struct front_inserter_fn
0117 {
0118 template<typename Cont>
0119 constexpr front_insert_iterator<Cont> operator()(Cont & cont) const
0120 {
0121 return front_insert_iterator<Cont>{cont};
0122 }
0123 };
0124
0125
0126 RANGES_INLINE_VARIABLE(front_inserter_fn, front_inserter)
0127
0128 template<typename Container>
0129 struct insert_iterator
0130 {
0131 using container_type = Container;
0132 using difference_type = std::ptrdiff_t;
0133
0134 constexpr insert_iterator() = default;
0135 constexpr explicit insert_iterator(Container & x, typename Container::iterator w)
0136 : container_(detail::addressof(x))
0137 , where_(w)
0138 {}
0139 insert_iterator & operator=(typename Container::value_type const & value)
0140 {
0141 where_ = ranges::next(container_->insert(where_, value));
0142 return *this;
0143 }
0144 insert_iterator & operator=(typename Container::value_type && value)
0145 {
0146 where_ = ranges::next(container_->insert(where_, std::move(value)));
0147 return *this;
0148 }
0149 insert_iterator & operator*()
0150 {
0151 return *this;
0152 }
0153 insert_iterator & operator++()
0154 {
0155 return *this;
0156 }
0157 insert_iterator & operator++(int)
0158 {
0159 return *this;
0160 }
0161
0162 private:
0163 Container * container_ = nullptr;
0164 typename Container::iterator where_ = typename Container::iterator();
0165 };
0166
0167 struct inserter_fn
0168 {
0169 template<typename Cont>
0170 constexpr insert_iterator<Cont> operator()(Cont & cont,
0171 typename Cont::iterator where) const
0172 {
0173 return insert_iterator<Cont>{cont, std::move(where)};
0174 }
0175 };
0176
0177
0178 RANGES_INLINE_VARIABLE(inserter_fn, inserter)
0179
0180 namespace cpp20
0181 {
0182 using ranges::back_insert_iterator;
0183 using ranges::back_inserter;
0184 using ranges::front_insert_iterator;
0185 using ranges::front_inserter;
0186 using ranges::insert_iterator;
0187 using ranges::inserter;
0188 }
0189
0190 }
0191
0192
0193 RANGES_DIAGNOSTIC_PUSH
0194 RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
0195
0196 namespace std
0197 {
0198 template<typename Container>
0199 struct iterator_traits<::ranges::back_insert_iterator<Container>>
0200 : ::ranges::detail::std_output_iterator_traits<>
0201 {};
0202
0203 template<typename Container>
0204 struct iterator_traits<::ranges::front_insert_iterator<Container>>
0205 : ::ranges::detail::std_output_iterator_traits<>
0206 {};
0207
0208 template<typename Container>
0209 struct iterator_traits<::ranges::insert_iterator<Container>>
0210 : ::ranges::detail::std_output_iterator_traits<>
0211 {};
0212 }
0213
0214 RANGES_DIAGNOSTIC_POP
0215
0216
0217 #include <range/v3/detail/epilogue.hpp>
0218
0219 #endif