// ==========================================================================
// $Id: const_pointer.cpp,v 1.3 2013/10/09 15:15:13 jlang Exp $
// CSI2372 example Code for lecture 6
// ==========================================================================
// (C)opyright:
//
//   Jochen Lang
//   EECS, University of Ottawa
//   800 King Edward Ave.
//   Ottawa, On., K1N 6N5
//   Canada. 
//   http://www.eecs.uottawa.ca
// 
// Creator: jlang (Jochen Lang)
// Email:   jlang@eecs.uottawa.ca
// ==========================================================================
// $Log: const_pointer.cpp,v $
// Revision 1.3  2013/10/09 15:15:13  jlang
// Corrected typo.
//
// Revision 1.1  2013/10/07 23:27:55  jlang
// Reverted to small caps filenaem
//
// Revision 1.1  2013/10/07 23:24:18  jlang
// Added const pointer example
//
//
// ==========================================================================
#include <iostream>
#include <iomanip>

void fun(const int* _iPtrToConst) {
#if 0
  *_iPtrToConst = 3; // illegal
  int *iPtr = _iPtrToConst; // illegal
#endif
  int *tiPtr = const_cast<int *>(_iPtrToConst);
  *tiPtr = 1;
  return;
}


void printArray( int _array[], int _size ) {
  for (int i=0;i<_size;++i) {
    std::cout << std::setw(6) << _array[i] << '\t';
  }
  std::cout << std::endl;
  return;
}


int main() {
  int i = 5;
  // pointer to const object can be (easily) circumvented
  std::cout << "Before: i = " << i << std::endl; 
  fun(&i);
  std::cout << "After: i = " << i << std::endl; 
  std::cout << std::endl; 
  
  // const pointer
  int array[] = { 0, 1, 2, 3 };


	std::cout << "const Pointer to array: " << std::endl;
  int* const ciPtr = &(array[0]);
  std::cout << "Before: array = ";
  printArray( array, 4 );
  // Legal assignment -- only pointer is const
  *ciPtr = -1;
  std::cout << "After: array = ";
  printArray( array, 4 );
#if 0
  ciPtr++; // Illegal: cannot change location pointed to
#endif
  std::cout << std::endl; 

	std::cout << "Pointer to const array: " << std::endl;
  const int * iPtrToConst = &(array[0]);
  std::cout << "Before:  *iPtrToConst = " << *iPtrToConst << std::endl; 
  printArray( array, 4 );
  // Legal: pointing to something else
  (iPtrToConst)++;
  std::cout << "After:  *iPtrToConst = " << *iPtrToConst << std::endl; 
  printArray( array, 4 );

#if 0
  *iPtrToConst = 10; // Illegal: cannot change what is pointed to
#endif
  
  return 0;
}
