1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
#include <iostream>
#include <initializer_list>
#include <string>
template < typename T > struct list {
list() noexcept = default ;
list( std::initializer_list<T> ilist ) { for( const T& v : ilist ) push_back(v) ; }
~list() { while( !empty() ) pop_back() ; }
// etc.
std::size_t size() const { return sz ; }
bool empty() const { return size() == 0 ; }
void push_back( const T& v ) {
if( empty() ) first = last = new node{ v, nullptr, nullptr } ;
else { last->next = new node{ v, last, nullptr } ; last = last->next ; }
++sz ;
}
void pop_back() { // invariant: !empty()
if( size() == 1 ) { delete first ; first = last = nullptr ; }
else { last = last->prev ; delete last->next ; last->next = nullptr ; }
--sz ;
}
// etc.
private: struct node ; public:
struct iterator {
// elided: type aliases to make it compatible with std::iterator_traits
T& operator* () { return current->value ; }
T* operator-> () { return &**this ; }
iterator& operator++ () { current = current->next ; return *this ; }
iterator operator++ (int) { const auto temp = *this ; ++*this ; return temp ; }
iterator& operator-- () { current = current ? current->prev : lst.last ; return *this ; }
iterator operator-- (int) { const auto temp = *this ; --*this ; return temp ; }
bool operator== ( const iterator& that ) const { return current == that.current ; }
bool operator!= ( const iterator& that ) const { return !( *this == that ) ; }
private:
node* current ;
list& lst ;
iterator( node* n, list& l ) : current(n), lst(l) {}
friend list ;
};
iterator begin() { return { first, *this } ; }
iterator end() { return { nullptr, *this } ; }
// ...
private:
struct node { T value ; node* prev ; node* next ; };
node* first = nullptr ;
node* last = nullptr ;
std::size_t sz = 0 ;
};
int main() {
list<std::string> lst { "abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx", "yz12" } ;
for( const auto& str : lst ) std::cout << str << '\n' ;
}
|