/* Generic Programming, Templates, STL */ #include using namespace std; /* Generic Programming - methodology for enhancing code reuse. There are 3 main methods in C++: 1. Inheritance : Allows us to define data types with constructing special relationships with existing classes. 2. Generic Pointers: This method takes a further step and allows existing code to be written generically, that is type independent. 3. Templates : A C++ feature to write type independent code more efficiently than generic pointers. */ /* Generic Pointers example: write a function that copies every element from a source array to a destination array. This has to work regardless of the type of the array */ /* // type known directly copy from one array to another void transfer1( int from[], int to[], int size ){ for ( int i=0; i(to)[i] = static_cast(from)[i]; } int main(){ int a[10], b[10]; double c[10], d[10]; // initialize a and c arrays for(int i=0; i<10; i++){ a[i] = i ; c[i] = i*0.1; } transfer1(a, b, 10) ; // transfer1(c, d, 10) ; // won't compile! tranfer1 only works with int cout << "b array after transfer: " ; for(int i=0; i<10; i++) cout << b[i] << " " ; cout << endl; transfer2(a, b, 10, sizeof(int)) ; // b is a char array of size 10 * sizeof(int) int* bt = reinterpret_cast(b); cout << "b array after transfer: " ; for(int i=0; i<10; i++) cout << bt[i] << " " ; cout << endl; // d is a double array of size = 10 * sizeof(double) double* dt = reinterpret_cast(d); transfer2(c, d, 10, sizeof(double)) ; cout << "d array after transfer: " ; for(int i=0; i<10; i++) cout << dt[i] << " " ; cout << endl; return 0; } */ /* More elegant way-> Template function Syntax : template ... function definition -> contains TEMPLATE_NAME everywhere a type name is required. */ /* template void transfer3( T* from, T* to, int size ) { for(int i=0; i write a stack class independent of type */ /* #include template class stack{ private: enum { EMPTY= -1 }; TYPE* s; int max_len; int top; public: explicit stack( int size=100 ) : max_len(size), top(EMPTY), s( new TYPE[size]) { assert( s != 0 ); } ~stack() { delete[] s; } void reset() { top = EMPTY; } void push( TYPE c ) { s[++top] = c; } TYPE pop() { return s[top--]; } TYPE top_of() { return s[top]; } bool empty() { return ( top == EMPTY ); } bool full() { return ( top = max_len - 1 ); } }; // create a temporary stack and use it to first push elements from an array and pop back to it. void reverse( char* str[], int n ){ stack stk(n); for( int i=0; i stk_int; stack stk_str(200); //stack stk_pt(10); // won't compile! point class definition is not in this document int i; cout << "before: \n" ; for(int i=0; i void stack::push(TYPE c){ s[++top] = c; } template TYPE stack::pop() { return s[top--]; } etc. */ /* Standard Template Library (STL) This is a collection of useful templates that are a part of standard namespace It contains a variety of containers and algorithms that provides various means to store, access and search the data. A handy online reference : http://www.cppreference.com/cppstl.html There are two main types of containers in STL 1. Sequence containers: vector, list, deque 2. Associative containers: map, multimap, set, multiset All containers have a shared interface (public functions): 1. C'tors and D'tors 2. functions to access, insert and delete elements 3. iterators 4. algorithms ( useful functions e.g. sort, search etc. ) */ /* Sequence Container: Vector example Dynamically expanding array. Allows random access with an index or sequentially with iterators. Provides fast access to elements but adding or deleting is slow. */ /* #include int main() { vector V(10); for( int i=0; i<10; i++ ) V[i] = i * 10 ; V.push_back(100); vector::iterator p; for( p=V.begin(); p != V.end(); p++ ) cout << *p << " " ; cout << endl; // OR vector V2; for( int i=0; i<10; i++ ) V2.push_back(i*10); for( p=V2.begin(); p != V2.end(); p++ ) cout << *p << " " ; cout << endl; return 0; } */ /* Sequence Container: List example Underlying data structure is a linked list. Addition or deletion of data is fast but random access is slow. Doesn't allow index for access, use iterators instead. */ /* #include int main() { list L; for( int i=0; i<10; i++ ) L.push_back(i*10); L.push_front(100); list::iterator p; for( p=L.begin(); p != L.end(); p++ ) cout << *p << " " ; cout << endl; return 0; } */ /* Sequence Container: Deque Double ended queue They are like vectors but efficient at inserting and deleting elements from both back and front of the queue. Also access is fast. */ /* Associative Container: Set and Multiset A set is similar to mathematical set where all values are unique and sorted using a key associated with each value and a sorting function. Multiset differs from set by allowing duplicate values. */ /* #include int main() { set S; for( int i=0; i<10; i++ ) S.insert(i*10); set::iterator p; for( p=S.begin(); p != S.end(); p++ ) cout << *p << " " ; cout << endl; return 0; } */ /* Associative Containers: Map and Multimap Map stores elements in key, value pairs, where each pair is unique. To access any value key is used as an index. Multimap differs from Map by allowing duplicate key value pairs. */ /* Container Adaptors: These are useful containers provided by STL but they are adapted from existing containers and don't observe the requirements of an STL container. These are: - stack - queue - priority-queue */