#include <iostream>
#include <string>
class Book {
private:
std::string name;
public:
Book(){};
Book(std::string name);
~Book(){};
std::string getName();
friend std::ostream &operator<<(std::ostream &s, Book *b);
};
class BookShelfIterator;
class BookShelf {
private:
Book **books;
int maxsize;
int last;
public:
BookShelf(int maxsize);
~BookShelf();
Book *getBookAt(int index);
void appendBook(Book *book);
int getLength();
BookShelfIterator *iterator();
};
class BookShelfIterator {
private:
BookShelf *bookShelf;
int index;
public:
BookShelfIterator(BookShelf *bookShelf);
~BookShelfIterator(){};
bool hasNext();
Book *next();
};
/*-----------------------------------------------*/
Book::Book(std::string name) { this->name = name; }
std::string Book::getName() {return this->name; }
std::ostream &operator<<(std::ostream &s, Book *b) {
s << b->name;
return s;
}
/*-----------------------------------------------*/
BookShelf::BookShelf(int maxsize) {
this->books = new Book* [maxsize];
this->maxsize = maxsize;
this->last = 0;
}
BookShelf::~BookShelf() { delete [] (this->books); }
Book *BookShelf::getBookAt(int index) { return this->books[index]; }
void BookShelf::appendBook(Book *book) {
if (last < maxsize) {
this->books[last] = book;
this->last++;
}
}
int BookShelf::getLength() { return this->last; }
BookShelfIterator *BookShelf::iterator() { return new BookShelfIterator(this); }
/*-----------------------------------------------*/
BookShelfIterator::BookShelfIterator(BookShelf *bookShelf) {
this->bookShelf = bookShelf;
this->index = 0;
}
bool BookShelfIterator::hasNext() {
if (this->index < bookShelf->getLength()) return true;
else return false;
}
Book *BookShelfIterator::next() {
Book *book = bookShelf->getBookAt(index);
index++;
return book;
}
template<class T, class U>
void shelf_for_each(T& shelf, U func) {
auto it = shelf->iterator();
while (it->hasNext()) {
func(it->next());
}
delete it;
}
int main() {
BookShelf *bookShelf = new BookShelf(4);
bookShelf->appendBook(new Book("A"));
bookShelf->appendBook(new Book("BB"));
bookShelf->appendBook(new Book("CCC"));
bookShelf->appendBook(new Book("DDDD"));
shelf_for_each(bookShelf, [](Book* book){std::cout << book << std::endl;});
delete bookShelf;
return 0;
}