#include <cstdlib>
using namespace std;
#include <vector>
#include <iostream>
#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<typename std::remove_const<L>::type>::iterator index;
friend class List<T>;
explicit Iterator(typename std::vector<typename std::remove_const<L>::type>::iterator it);
public:
// Iterator();
Iterator(Iterator<typename std::remove_const<L>::type > const & other);
L & operator*();
Iterator & operator++(); // prefix
Iterator operator++(int); //postfix
bool operator !=(const Iterator & other) const;
bool operator ==(const Iterator & other) const;
Iterator operator=(Iterator<typename std::remove_const<L>::type > & other) {
if (this != &other) {
std::iterator<std::forward_iterator_tag, L>::operator=(other);
index = other.index;
}
return *this;
}
Iterator operator=(Iterator< const typename std::remove_const<L>::type > & other){
if (this != &other) {
std::iterator<std::forward_iterator_tag, L>::operator=(other);
index = other.index;
}
return *this;
}
Iterator operator=(const Iterator & other);
Iterator operator+(const unsigned int position);
Iterator 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 & add(const T & t);
List & add(const iterator start, const iterator end);
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); //per iterator?
List<T> & unify(List<T> & tList); //per iterator?
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<typename std::remove_const<L>::type>::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() {
return iterator(queue.end());
}
template <typename T>
typename List<T>::const_iterator
List<T>::begin() const {
return iterator(queue, queue.begin());
}
template <typename T>
typename List<T>::const_iterator
List<T>::end() const {
return iterator(queue, queue.end());
}
template <typename T>
std::ostream&
operator<<(std::ostream & out, const List<T> & l) {
out << "[";
for (auto e = l.begin(); e != l.end(); e++) {
out << (*e);
}
out << "]";
return out;
}
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 iterator start, const iterator end){
queue.insert(queue.begin(), start, end);
return *this;
}
template <typename T>
List<T> &
List<T>::unify(List<T> & tList) {
add(tList.begin(), tList.end());
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 1;//IndexOutOfBoundsException("index out of bounds");
}//End if
return queue[index];
}
template <typename T>
T const &
List<T>::get(size_t index) const {
if (index > queue.size()) {
throw 1;//IndexOutOfBoundsException("index out of bounds");
}//End if
return queue[index];
}
template <typename T>
typename List<T>::iterator
List<T>::remove(const T & a) {
return iterator(
queue.erase(std::remove(queue.begin(),
queue.end(),
a),
queue.end()));
}
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>
//std::vector<T>&
//List<T>::getInternal() {
// return queue;
//}
//
//template <typename T>
//const std::vector<T>&
//List<T>::getInternal() const {
// return queue;
//}
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();
//
// 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";
// }
List<int>::const_iterator cit = tempList.begin();
std::cerr<<tempList<<"\n";
return 0;
}