#pragma once
#ifndef LIST_H
#define LIST_H
#include "common/Defines.h"
#include "common/Exception.h"
#include <type_traits>
namespace A {
namespace B {
template <typename T>
class List {
public:
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;
void remove(const T & a);
void remove(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();
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;
public:
template <typename L>
class Iterator : public std::iterator<std::forward_iterator_tag, L> {
L * pos;
friend class List<T>;
explicit Iterator(L * aPos);
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);
};
typedef Iterator<T> iterator;
typedef Iterator<const T> const_iterator;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
};
template <typename T>
template <typename L>
List<T>::Iterator<L>::Iterator() : pos(NULL) {
}
template <typename T>
template <typename L>
List<T>::Iterator<L>::Iterator(L * aPos) : pos(aPos) {
}
template <typename T>
template <typename L>
List<T>::Iterator<L>::Iterator(Iterator< typename std::remove_const<L>::type > const & other) : pos(other.pos) {
}
template <typename T>
template <typename L>
L &
List<T>::Iterator<L>::operator*() {
return * pos;
}
template <typename T>
template <typename L>
typename List<T>::template Iterator<L> &
List<T>::Iterator<L>::operator++() { // prefix
++pos;
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 pos != other.pos;
}
template <typename T>
template <typename L>
bool
List<T>::Iterator<L>::operator ==(const List<T>::Iterator<L> & other) const {
return pos == other.pos;
}
template <typename T>
template <typename L>
List<T>::Iterator<L>
List<T>::Iterator<L>::operator=(const List<T>::Iterator<L> & other) {
if(this != &other){
pos = other.pos;
}
return *this;
}
template <typename T>
typename List<T>::iterator
List<T>::begin() {
return iterator(&queue[0]);
}
template <typename T>
typename List<T>::iterator
List<T>::end() {
return iterator(&queue[queue.size()]);
}
template <typename T>
typename List<T>::const_iterator
List<T>::begin() const {
return iterator(const_cast<T*>(&queue[0]));
}
template <typename T>
typename List<T>::const_iterator
List<T>::end() const {
return iterator(const_cast<T*>(&queue[queue.size()]));
}
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)); //C++11
queue.insert(tArray, tArray + sizeof(tArray)/sizeof(tArray[0]));
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");
}//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");
}//End if
return queue[index];
}
template <typename T>
void
List<T>::remove(const T & a) {
T b = a;
remove(b);
}
template <typename T>
void
List<T>::remove(T & a) {
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));
}
}
//BAUSTELLE, geht nicht
template <typename T>
typename List<T>::iterator
List<T>::erase (typename List<T>::const_iterator position){
return queue.erase((queue.begin()+position));
}
//BAUSTELLE, geht nicht
template <typename T>
typename List<T>::iterator
List<T>::erase (typename List<T>::const_iterator first, typename List<T>::const_iterator last){
return queue.erase(first, last);
}
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() {
return queue.front();
}
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());
}
}
}
#endif /* LIST_H */