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
|
#include <iostream>
#include <initializer_list>
#include <string>
#include <utility>
template < typename T > struct list
{
using value_type = T ;
// many more typedefs
list() = default ;
list( std::initializer_list<T> il ) { for( const auto& v : il ) push_back(v) ; }
// other foundation operators
bool empty() const { return sz == 0 ; }
// other inspectors
void push_back( const T& v )
{
if( empty() ) first = last = new node(v) ;
else
{
last->next = new node( v, last ) ;
last = last->next ;
}
++sz ;
}
template < typename CALLABLE > void for_each( CALLABLE fn ) const
{ for( auto p = first ; p ; p = p->next ) fn( const_cast<T&>(p->value) ) ; }
template < typename CALLABLE > void for_each( CALLABLE fn )
{ for( auto p = first ; p ; p = p->next ) fn(p->value) ; }
// many more member functions
private:
struct node
{
explicit node( const T& v ) : value(v) {}
explicit node( const T& v, node* p, node* n = nullptr ) : value(v), next(n), prev(p) {}
T value ;
node* next= nullptr ;
node* prev = nullptr ;
};
node* first = nullptr ;
node* last = nullptr ;
std::size_t sz = 0 ;
};
int main()
{
// class with three data types
struct A { int i ; std::string str ; double d ; /* more member variables */ };
list<A> lst { { 0, "zero", 0.12 }, { 1, "one", 1.23 }, { 2, "two", 2.34 } } ;
lst.push_back( { 3, "three", 3.45 } ) ;
lst.for_each( []( const A& a ) { std::cout << '{' << a.i << ',' << a.str << ',' << a.d << "} " ; } ) ;
std::cout << '\n' ;
list< std::pair< int, char > > another_list ; // list of template class with two data types
another_list.push_back( { 99, '*' } ) ;
// etc.
}
|