Skip to content

Instantly share code, notes, and snippets.

@kvk1920
Created May 14, 2018 16:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kvk1920/bfe95ef493a6644f8f45435d9c5be4c8 to your computer and use it in GitHub Desktop.
Save kvk1920/bfe95ef493a6644f8f45435d9c5be4c8 to your computer and use it in GitHub Desktop.
#include <iterator>
namespace Hard1 {
/**
* template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t,
* typename _Pointer = _Tp*, typename _Reference = _Tp&>
* Это шаблон std::iterator.
* Т.к. insert-итераторы не указывают на объект какого-то типа, то _Tp следует сделать
* void.
*/
template <typename Container>
class back_insert_iterator : std::iterator<std::output_iterator_tag, void, void, void, void> {
private:
Container* container_;
public:
typedef Container container_type;
back_insert_iterator(Container& container) :
container_(&container) {}
/**
* Итератор не предоставляет доступ к какому-либо значению,
* так же нет смысла его копировать, т.к. все итераторы на один контейнер будут одинаковые.
*/
back_insert_iterator& operator*() { return *this; }
back_insert_iterator& operator++() { return *this; }
back_insert_iterator operator++(int) { return *this; }
back_insert_iterator& operator=(const typename Container::value_type& x) {
container_->push_back(x);
return *this;
}
/**
* x - lvalue(т.к. x имеет имя), тип x - rvalue-ссылка на x
* Потому надо привести к value_type&&, т.е. сделать std::move.
*/
back_insert_iterator& operator=(typename Container::value_type&& x) {
container_->push_back(std::move(x));
return *this;
}
};
template <typename Container>
inline back_insert_iterator<Container> back_inserter(Container& container) {
return back_insert_iterator<Container>(container);
}
template <typename Container>
class front_insert_iterator : std::iterator<std::output_iterator_tag, void, void, void, void> {
private:
Container* container_;
public:
typedef Container container_type;
front_insert_iterator(Container& container) :
container_(&container) {}
front_insert_iterator& operator*() { return *this; }
front_insert_iterator& operator++() { return *this; }
front_insert_iterator operator++(int) { return *this; }
front_insert_iterator& operator=(const typename Container::value_type& x) {
container_->push_back(x);
return *this;
}
front_insert_iterator& operator=(typename Container::value_type&& x) {
container_->push_front(std::move(x));
return *this;
}
};
template <typename Container>
inline front_insert_iterator<Container> back_inserter(Container& container) {
return front_insert_iterator<Container>(container);
}
template <typename Container, typename Iterator>
class insert_iterator : std::iterator<std::output_iterator_tag, void, void, void, void> {
private:
Container* container_;
Iterator iterator_;
public:
typedef Container container_type;
typedef Iterator iterator_type;
insert_iterator(Container& container, Iterator iterator) :
container_(&container), iterator_(iterator) {}
insert_iterator& operator*() { return *this; }
insert_iterator& operator++() { return *this; }
insert_iterator operator++(int) { return *this; }
front_insert_iterator& operator=(const typename Container::value_type& x) {
container_->insert(iterator_, x);
return *this;
}
front_insert_iterator& operator=(typename Container::value_type&& x) {
container_->insert(iterator_, std::move(x));
return *this;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment