#include <cstdlib>
using namespace std;
#include <vector>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <type_traits>
template <typename T>
class List {
public:
template <typename L>
class Iterator : public std::iterator<std::forward_iterator_tag, L> {
typename std::vector<L>::iterator index;
friend class List<T>;
explicit Iterator(typename std::vector<L>::iterator it);
public:
Iterator();
Iterator(Iterator<typename std::remove_const<L>::type > const & other);
L & operator*();
Iterator<L> & operator++(); // prefix
Iterator<L> operator++(int); //postfix
bool operator !=(const Iterator<L> & other) const;
bool operator ==(const Iterator<L> & other) const;
Iterator<L> operator=(const Iterator<L> & other);
Iterator<L> operator+(const unsigned int position);
Iterator<L> operator-(const unsigned int position);
};
typedef Iterator<T> iterator;
typedef Iterator<const T> const_iterator;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
List();
List(const List & orig);
virtual ~List();
List & add(const T & t);
List & add(const List<T> & tList);
List & add(const T* tArray, size_t laenge);
List & add(const std::vector<T> t);
void clear();
size_t size() const;
bool contains(const T & a) const;
typename List::iterator remove(const T & a);
void remove(const List<T> & tList);
List<T> & unify(List<T> & tList);
T & get(size_t index);
T const & get(size_t index) const;
void sort();
void pop();
T & first();
T first() const;
T & last();
T last() const;
bool operator==(const List<T> & other) const;
std::vector<T> & getInternal();
const std::vector<T> & getInternal() const;
T & getMinElem();
protected:
typedef std::vector<T> TList;
TList queue;
};
template <typename T>
template <typename L>
List<T>::Iterator<L>
::Iterator() : index(queue.begin()) {
}
template <typename T>
template <typename L>
List<T>::Iterator<L>
::Iterator(typename std::vector<L>::iterator it) : index(it) {
}
template <typename T>
template <typename L>
List<T>::Iterator<L>
::Iterator(Iterator< typename std::remove_const<L>::type > const & other) : index(other.index) {
}
template <typename T>
template <typename L>
L &
List<T>::Iterator<L>::operator*() {
return *index;
}
template <typename T>
template <typename L>
typename List<T>::template Iterator<L> &
List<T>::Iterator<L>::operator++() { // prefix
++index;
return *this;
}
template <typename T>
template <typename L>
typename List<T>::template Iterator<L>
List<T>::Iterator<L>::operator++(int) { //postfix
Iterator<L> tmp = *this;
++(*this);
return tmp;
}
template <typename T>
template <typename L>
bool
List<T>::Iterator<L>::operator !=(const List<T>::Iterator<L> & other) const {
return index != other.index;
}
template <typename T>
template <typename L>
bool
List<T>::Iterator<L>::operator ==(const List<T>::Iterator<L> & other) const {
return index == other.index;
}
template <typename T>
template <typename L>
List<T>::Iterator<L>
List<T>::Iterator<L>::operator=(const List<T>::Iterator<L> & other) {
if (this != &other) {
std::iterator<std::forward_iterator_tag, L>::operator=(other);
index = other.index;
}
return *this;
}
template <typename T>
template <typename L>
List<T>::Iterator<L>
List<T>::Iterator<L>::operator+(const unsigned int value) {
index += value;
return *this;
}
template <typename T>
template <typename L>
List<T>::Iterator<L>
List<T>::Iterator<L>::operator-(const unsigned int value) {
index -= value;
return *this;
}
template <typename T>
typename List<T>::iterator
List<T>::begin() {
return iterator(queue.begin());
}
template <typename T>
typename List<T>::iterator
List<T>::end() {
std::cerr << "end ";
return iterator(queue.end());
}
template <typename T>
typename List<T>::const_iterator
List<T>::begin() const {
return iterator(queue.begin());
}
template <typename T>
typename List<T>::const_iterator
List<T>::end() const {
return iterator(queue.end());
}
template <typename T>
std::ostream&
operator<<(std::ostream & out, const List<T> & l) {
std::stringstream buf;
buf << "[";
for (auto e = l.begin(); e != l.end(); e++) {
buf << (*e);
}
buf << "]";
return out << buf.str();
}
template <typename T>
List<T>::List() {
}
template <typename T>
List<T>::List(const List & orig) : queue(orig.queue) {
}
template <typename T>
List<T>::~List() {
clear();
}
template <typename T>
void
List<T>::clear() {
queue.clear();
}
template <typename T>
List<T> &
List<T>::add(const T & t) {
queue.push_back(t);
return *this;
}
template <typename T>
List<T> &
List<T>::add(const List<T> & tList) {
queue.insert(queue.end(), tList.begin(), tList.end());
return *this;
}
template <typename T>
List<T> &
List<T>::add(const std::vector<T> t) {
queue.insert(queue.end(), t.begin(), t.end());
return *this;
}
template <typename T>
List<T> &
List<T>::add(const T* tArray, size_t length) {
queue.insert(queue.begin(), std::begin(tArray), std::end(tArray));
return *this;
}
template <typename T>
List<T> &
List<T>::unify(List<T> & tList) {
add(tList);
sort();
typename TList::iterator it;
it = std::unique(queue.begin(), queue.end());
queue.resize(std::distance(queue.begin(), it));
return *this;
}
template <typename T>
size_t
List<T>::size() const {
return queue.size();
}
template <typename T>
bool
List<T>::contains(const T & a) const {
return std::find(queue.begin(), queue.end(), a) != queue.end();
}
template <typename T>
T &
List<T>::get(size_t index) {
if (index > queue.size()) {
//throw IndexOutOfBounceException("index out of bounce");
throw 1;
}//End if
return queue[index];
}
template <typename T>
T const &
List<T>::get(size_t index) const {
if (index > queue.size()) {
//throw IndexOutOfBounceException("index out of bounce");
throw 2;
}//End if
return queue[index];
}
template <typename T>
typename List<T>::iterator
List<T>::remove(const T & a) {
//List<T>::iterator it;
//it =
return iterator( queue.erase(std::remove(queue.begin(),
queue.end(),
a),
queue.end()));
//return iterator(it);
}
template <typename T>
void
List<T>::remove(const List<T> & tList) {
for (size_t i = 0; i < tList.size(); i++) {
remove(tList.get(i));
}
}
template <typename T>
void
List<T>::sort() {
std::sort(queue.begin(), queue.end());
}
template <typename T>
bool
List<T>::operator ==(const List<T>& other) const {
TList localQueue(queue);
TList foreignQueue(other.queue);
std::sort(localQueue.begin(), localQueue.end());
std::sort(foreignQueue.begin(), foreignQueue.end());
return (localQueue == foreignQueue);
}
template <typename T>
void
List<T>::pop() {
queue.erase(queue.begin());
}
template <typename T>
T
List<T>::first() const {
return queue.front();
}
template <typename T>
T &
List<T>::first() {
return queue.front();
}
template <typename T>
T
List<T>::last() const {
return queue.back();
}
template <typename T>
T &
List<T>::last() {
return queue.back();
}
template <typename T>
T &
List<T>::getMinElem() {
return * std::min_element(queue.begin(), queue.end());
}
/*
*
*/
int
main(int argc, char** argv) {
List<int> tempList;
tempList.add(99);
List<int>::iterator it = tempList.begin();
//for (List<int>::iterator it = tempList.begin(); it != tempList.end(); ) {
while (it != tempList.end()) {
std::cerr << *it << "\n";
if (*it == 99) {
it = tempList.remove(*it);
std::cerr << "deleted size: " << tempList.size() << "\n";
for (size_t i = 0; i < tempList.size(); i++) {
std::cerr << tempList.get(i) << "\n";
}
std::cerr << "new round\n";
}//End if
else{
it++;
}
}//End for
for (size_t i = 0; i < tempList.size(); i++) {
std::cerr << "--"<<tempList.get(i) << "\n";
}
return 0;
}