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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
#include <iostream>
#include <iterator>
template < typename T > struct list
{
using value_type = T ;
private: struct iterator ; public:
iterator begin() { return { first, last } ; }
iterator end() { return { nullptr, last } ; }
bool empty() const noexcept { return first == nullptr ; }
void push_back( const T& v )
{
if( empty() ) first = last = new node { v, nullptr, nullptr } ;
else
{
last->next = new node { v, nullptr, last } ;
last = last->next ;
}
}
void print() // note: not const since we haven't (yet) implemented const_iterators
{
for( const auto& v : *this ) std::cout << v << " => " ;
std::cout << " nullptr\n" ;
}
void debug_dump() const
{
std::cout << "nodes:\n" ;
for( const node* n = first ; n != nullptr ; n = n->next ) dump_node(n) ;
std::cout << "\n----------------------\n" ;
}
iterator find( const T& v ) // note: not const since we haven't (yet) implemented const_iterators
{
for( auto iter = begin() ; iter != end() ; ++iter ) if( iter.current->value == v ) return iter ;
return end() ; // not found
}
void swap_nodes( iterator a, iterator b ) { do_swap_nodes( a.current, b.current ) ; }
private:
struct node
{
T value ;
node* next ;
node* prev ;
};
node* first = nullptr ;
node* last = nullptr ;
struct iterator
{
using value_type = T ;
using iterator_category = std::bidirectional_iterator_tag ;
using reference = T& ;
using pointer = T* ;
using difference_type = std::ptrdiff_t ;
reference operator*() { return current->value ; }
pointer operator&() { return std::addressof( **this ) ; }
iterator& operator++ () { current = current->next ; return *this ; }
iterator operator++ (int) { const auto oldv = *this ; ++*this ; return oldv ; }
iterator& operator-- () { current = current ? current->prev : last ; return *this ; }
iterator operator-- (int) { const auto oldv = *this ; --*this ; return oldv ; }
bool operator== ( const iterator& that ) const noexcept { return current == that.current ; }
bool operator!= ( const iterator& that ) const noexcept { return !( *this == that ) ; }
node* current ;
node* last ;
};
static void dump_node( const node* n )
{
std::cout << "node at address: " << n << " value: " << n->value
<< " next: " << n->next << " prev: " << n->prev << '\n' ;
}
void do_swap_nodes( [[maybe_unused]] node* a, [[maybe_unused]] node* b ) // unused as of now
{
// TO DO: implement, test, debug this function
// use debug_dump() to aid in the debugging
}
};
int main()
{
list<int> lst ;
for( int v = 0 ; v < 10 ; ++v )
{
lst.push_back(v) ;
// lst.print() ;
// lst.debug_dump() ;
}
lst.print() ;
lst.debug_dump() ;
// uncomment after implementing swap_nodes
/*
const auto iter_three = lst.find(3) ;
const auto iter_seven = lst.find(7) ;
lst.swap_nodes( iter_three, iter_seven ) ;
std::cout << "after swap\n" ;
lst.print() ;
lst.debug_dump() ;
*/
}
| |