// ==========================================================================
// $Id: sharedptr.cpp,v 1.1 2013/11/24 03:18:56 jlang Exp $
// CSI2372 example Code for lecture 15 - C++11
// ==========================================================================
// (C)opyright:
//
//   Jochen Lang
//   EECS, University of Ottawa
//   800 King Edward Ave.
//   Ottawa, On., K1N 6N5
//   Canada. 
//   http://www.site.uottawa.ca
// 
// Creator: jlang (Jochen Lang)
// Email:   jlang@site.uottawa.ca
// ==========================================================================
// $Log: sharedptr.cpp,v $
// Revision 1.1  2013/11/24 03:18:56  jlang
// Added sharedPtr example.
//
//
// ==========================================================================#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <memory>

using std::string;
using std::ostream;
using std::ifstream;
using std::cout;
using std::cerr;
using std::endl;


class Text {
  std::shared_ptr<std::vector<string> > d_text;
public:
  Text(std::shared_ptr<std::vector<string> > _in) : d_text(_in) {
    cout << "Text( _in )" << endl;
  }
  // synthesized cctor and destructor are fine
  int numWords() const {
  	return d_text->size();
  }
  Text& operator<<( string append ) {
  	d_text->push_back(append);
  	return *this;
  }
  friend ostream& operator<<(ostream& os, const Text& _obj ) {
    os << "Text: " << _obj.numWords() << " words" << endl;
		for ( auto word : *(_obj.d_text)) {
			os << word << " ";
		};
		os << endl;
    return os;
  }
};

// Read a file into a vector of strings
std::shared_ptr<std::vector<string> > fileIntoVector( string inFileName ) {
  ifstream inFile( inFileName.c_str());
  if ( !inFile ) {
    cerr << "Error: unable to open: " << inFileName << endl;
    return nullptr;
  }
  auto res = std::make_shared<std::vector<string> >();
  string word;
  while( !inFile.eof() ) { 
    inFile >> word;
    if (inFile) res->push_back(word);
  }  
  inFile.clear();
  inFile.close();
  return res;
}

// Pass by value but vector is shared!
void add( Text txt ) {
  txt << "A" << "bit" << "more" << "text.";
  cout << "Num of words in txt: " << txt.numWords() << endl;
	return;
}


int main( int argc, char** argv ) {
  string inFileName = "in.txt";
  if (argc>1) inFileName = argv[1];
  auto vecPtr = fileIntoVector( inFileName );
  if (!vecPtr) {
  	cerr << "File read produced empty vector" << endl;
  	return -1;
  }
  cout << "Number of shares (1): " << vecPtr.use_count() << endl;
  Text text(vecPtr);
  Text cpy(text);
	cout << "Number of shares (2): " << vecPtr.use_count() << endl;
  cout << text;
  add(text);
  cout << "Copy: ";
  cout << cpy;
  cout << "Num of words in text: " << text.numWords() << endl;
  return 0;
}
