/* file insertionSort.h */
          // code by bds, 9/99

#include <stl.h>

/* Insertion Sort is written to take a pointer to the beginning of
the array to be sorted and a pointer to the position just beyond
the last item in the array to be sorted.  This convention is used
throughout the C++ Standard Template Library and applies to other
"containers" than arrays as well.  This is generic programming,
because the type of elements in the array can be any type for which
the operator "<=" is defined.

To achieve the generic property, the pointer type is a template
parameter to the function.  We use the name Iterator for the 
pointer type to be consistent with STL usage.  All we actually
assume about this type is that the pointer arithmetic operations
are valid on objects of type Iterator and that the unknown class 
pointed to by dereferencing iterators has <= defined.
*/

template<class Iterator> // think "pointer"
void insertionSort(Iterator b, Iterator e)
// The items in positions [b .. e) to be permuted into sorted order.
{ Iterator j;
  for (j = b+1; j < e; j++) 
             // invariant: range [b .. j) is sorted.
  { Iterator i;
    iterator_traits<Iterator>::value_type key;

    key = *j;
    i = j-1;
    while ( i >= b && ( key <= *i  ) )
    {  
      *(i+1) = *i;
                 // invariant: 
                 // 1. [*b .. *i) is still sorted and no larger than *i 
                 // 2. [*(i+1) .. *j] is sorted and greater than key 
                 // 3. key is missing from the array 
                 // 4. *i is a copy of *(i+1)
      i--;
    } 
    *(i+1) = key;
  }
          // Now [*b .. *j) is in order and j = e.  
          // thus [*b .. *e) is sorted as required.

}

////////////////////////////////////////////////////////////////////////
/* file main.cc using insertion sort */
             // code by bds, 9/99
//#include "insertionSort.h"
#include <iostream.h>

main()
{
  const int n = 20;
  int B[n];

  // get input data
  cout << 7 << " ints, please: "; 
  for (int* p = B; p < B+7; p++) 
    cin >> *p;
  cout << "Thank you, unsorted that'd be: ";
  for (int* p = B; p < B+7; p++) 
    cout << *p << " ";
  cout << endl;

  // sort
  insertionSort(B, B+7);

  // put output
  cout << "Thank you, sorted that'd be: ";
  for (int* p = B; p < B+7; p++) 
    cout << *p << " ";
  cout << endl;

  char A[n];

  // get input data
  cout << n << " chars, please: "; 
  for (char* p = A; p < A+n; p++) 
    cin >> *p;

  // sort
  insertionSort(A, A+n);

  // put output
  cout << "Thank you, sorted that'd be: ";
  for (char* p = A; p < A+n; p++) 
    cout << *p << " ";
  cout << endl;
}
