#include <boost/stl_interfaces/iterator_interface.hpp>
#include <algorithm>
#include <array>
#include <cassert>
struct simple_random_access_iterator
: boost::stl_interfaces::iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
simple_random_access_iterator,
#endif
std::random_access_iterator_tag,
int>
{
simple_random_access_iterator() noexcept {}
simple_random_access_iterator(int * it) noexcept : it_(it) {}
int & operator*() const noexcept { return *it_; }
simple_random_access_iterator & operator+=(std::ptrdiff_t i) noexcept
{
it_ += i;
return *this;
}
auto operator-(simple_random_access_iterator other) const noexcept
{
return it_ - other.it_;
}
private:
int * it_;
};
int main()
{
std::array<int, 10> ints = {{0, 2, 1, 3, 4, 5, 7, 6, 8, 9}};
simple_random_access_iterator first(ints.data());
simple_random_access_iterator last(ints.data() + ints.size());
std::sort(first, last);
assert(ints == (std::array<int, 10>{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}));
}
#include <boost/stl_interfaces/iterator_interface.hpp>
#include <algorithm>
#include <array>
#include <numeric>
#include <cassert>
template<typename ValueType>
struct random_access_iterator : boost::stl_interfaces::iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
random_access_iterator<ValueType>,
#endif
std::random_access_iterator_tag,
ValueType>
{
static_assert(std::is_object<ValueType>::value, "");
constexpr random_access_iterator() noexcept {}
constexpr random_access_iterator(ValueType * it) noexcept : it_(it) {}
template<
typename ValueType2,
typename E = std::enable_if_t<
std::is_convertible<ValueType2 *, ValueType *>::value>>
constexpr random_access_iterator(
random_access_iterator<ValueType2> other) noexcept :
it_(other.it_)
{}
constexpr ValueType & operator*() const noexcept { return *it_; }
constexpr random_access_iterator & operator+=(std::ptrdiff_t i) noexcept
{
it_ += i;
return *this;
}
constexpr auto operator-(random_access_iterator other) const noexcept
{
return it_ - other.it_;
}
private:
ValueType * it_;
template<typename ValueType2>
friend struct random_access_iterator;
};
using iterator = random_access_iterator<int>;
using const_iterator = random_access_iterator<int const>;
int main()
{
std::array<int, 10> ints = {{0, 2, 1, 3, 4, 5, 7, 6, 8, 9}};
iterator first(ints.data());
iterator last(ints.data() + ints.size());
std::sort(first, last);
assert(ints == (std::array<int, 10>{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}));
std::array<int, 10> int_sums;
const_iterator cfirst(ints.data());
const_iterator clast = last;
std::partial_sum(cfirst, clast, int_sums.begin());
assert(int_sums == (std::array<int, 10>{{0, 1, 3, 6, 10, 15, 21, 28, 36, 45}}));
}
#include <boost/stl_interfaces/iterator_interface.hpp>
#include <algorithm>
#include <array>
#include <tuple>
#include <cassert>
struct zip_iterator : boost::stl_interfaces::proxy_iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
zip_iterator,
#endif
std::random_access_iterator_tag,
std::tuple<int, int>,
std::tuple<int &, int &>>
{
constexpr zip_iterator() noexcept : it1_(), it2_() {}
constexpr zip_iterator(int * it1, int * it2) noexcept : it1_(it1), it2_(it2)
{}
constexpr std::tuple<int &, int &> operator*() const noexcept
{
return std::tuple<int &, int &>{*it1_, *it2_};
}
constexpr zip_iterator & operator += (std::ptrdiff_t i) noexcept
{
it1_ += i;
it2_ += i;
return *this;
}
constexpr auto operator-(zip_iterator other) const noexcept
{
return it1_ - other.it1_;
}
private:
int * it1_;
int * it2_;
};
namespace std {
void swap(zip_iterator::reference && lhs, zip_iterator::reference && rhs)
{
using std::swap;
swap(std::get<0>(lhs), std::get<0>(rhs));
swap(std::get<1>(lhs), std::get<1>(rhs));
}
}
int main()
{
std::array<int, 10> ints = {{2, 0, 1, 5, 3, 6, 8, 4, 9, 7}};
std::array<int, 10> ones = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
{
std::array<std::tuple<int, int>, 10> const result = {{
{2, 1},
{0, 1},
{1, 1},
{5, 1},
{3, 1},
{6, 1},
{8, 1},
{4, 1},
{9, 1},
{7, 1},
}};
zip_iterator first(ints.data(), ones.data());
zip_iterator last(ints.data() + ints.size(), ones.data() + ones.size());
assert(std::equal(first, last, result.begin(), result.end()));
}
{
std::array<std::tuple<int, int>, 10> const result = {{
{0, 1},
{1, 1},
{2, 1},
{3, 1},
{4, 1},
{5, 1},
{6, 1},
{7, 1},
{8, 1},
{9, 1},
}};
zip_iterator first(ints.data(), ones.data());
zip_iterator last(ints.data() + ints.size(), ones.data() + ones.size());
assert(!std::equal(first, last, result.begin(), result.end()));
std::sort(first, last);
assert(std::equal(first, last, result.begin(), result.end()));
}
}
#include <boost/stl_interfaces/iterator_interface.hpp>
#include <algorithm>
#include <vector>
#include <cassert>
template<typename Container>
struct back_insert_iterator : boost::stl_interfaces::iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
back_insert_iterator<Container>,
#endif
std::output_iterator_tag,
typename Container::value_type,
back_insert_iterator<Container> &>
{
back_insert_iterator() : c_(nullptr) {}
explicit back_insert_iterator(Container & c) : c_(std::addressof(c)) {}
back_insert_iterator & operator=(typename Container::value_type const & v)
{
c_->push_back(v);
return *this;
}
back_insert_iterator & operator=(typename Container::value_type && v)
{
c_->push_back(std::move(v));
return *this;
}
back_insert_iterator & operator*() { return *this; }
back_insert_iterator & operator++() { return *this; }
using base_type = boost::stl_interfaces::iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
back_insert_iterator<Container>,
#endif
std::output_iterator_tag,
typename Container::value_type,
back_insert_iterator<Container> &>;
using base_type::operator++;
private:
Container * c_;
};
template<typename Container>
back_insert_iterator<Container> back_inserter(Container & c)
{
return back_insert_iterator<Container>(c);
}
int main()
{
std::vector<int> ints = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
std::vector<int> ints_copy;
std::copy(ints.begin(), ints.end(), ::back_inserter(ints_copy));
assert(ints_copy == ints);
}
#include <boost/stl_interfaces/iterator_interface.hpp>
#include <algorithm>
#include <list>
#include <vector>
#include <cassert>
template<typename BidiIter>
struct reverse_iterator
: boost::stl_interfaces::iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
reverse_iterator<BidiIter>,
#endif
#if 201703L < __cplusplus && defined(__cpp_lib_ranges)
boost::stl_interfaces::v2::v2_dtl::iter_concept_t<BidiIter>,
#else
typename std::iterator_traits<BidiIter>::iterator_category,
#endif
typename std::iterator_traits<BidiIter>::value_type>
{
reverse_iterator() : it_() {}
reverse_iterator(BidiIter it) : it_(it) {}
using ref_t = typename std::iterator_traits<BidiIter>::reference;
using diff_t = typename std::iterator_traits<BidiIter>::difference_type;
ref_t operator*() const { return *std::prev(it_); }
bool operator==(reverse_iterator other) const { return it_ == other.it_; }
diff_t operator-(reverse_iterator other) const
{
return -std::distance(other.it_, it_);
}
reverse_iterator & operator+=(diff_t n)
{
std::advance(it_, -n);
return *this;
}
private:
BidiIter it_;
};
using rev_bidi_iter = reverse_iterator<std::list<int>::iterator>;
using rev_ra_iter = reverse_iterator<std::vector<int>::iterator>;
int main()
{
{
std::list<int> ints = {4, 3, 2};
std::list<int> ints_copy;
std::copy(
rev_bidi_iter(ints.end()),
rev_bidi_iter(ints.begin()),
std::back_inserter(ints_copy));
std::reverse(ints.begin(), ints.end());
assert(ints_copy == ints);
}
{
std::vector<int> ints = {4, 3, 2};
std::vector<int> ints_copy(ints.size());
std::copy(
rev_ra_iter(ints.end()),
rev_ra_iter(ints.begin()),
ints_copy.begin());
std::reverse(ints.begin(), ints.end());
assert(ints_copy == ints);
}
{
using rev_ptr_iter = reverse_iterator<int *>;
int ints[3] = {4, 3, 2};
int ints_copy[3];
std::copy(
rev_ptr_iter(std::end(ints)),
rev_ptr_iter(std::begin(ints)),
std::begin(ints_copy));
std::reverse(std::begin(ints), std::end(ints));
assert(std::equal(
std::begin(ints_copy),
std::end(ints_copy),
std::begin(ints),
std::end(ints)));
}
}