/***************************************************************************
 * This program illustrates the generic algorithms 'remove' and 
 * 'transform'.
 ***************************************************************************/
#include <iostream>
#include <list>
#include<vector>
#include<string>
#include <cctype>
#include <algorithm>

using std::cin;           
using std::cout;            
using std::endl;            
using std::list;
using std::vector;
using std::string;
using std::remove; using std::transform;
using std::toupper;

typedef list<string> seq;/* This could be replaced with a vector.
			 */

void show_seq(const seq& s);// Display s.
bool notalnum(char c);// Return 'true' if c is not alphanumeric.
string make_upper(const string & orig);//Put 'orig' in all upper case.



int main()
{

	seq custom, upper_version, cleaned;
	string x, query;
	string stop_string;
	cout<<"\nPlease enter space-separated alphanumeric words,"<<
	       " and '#' to stop:";
	while(cin>>x)
	{
		/* Check that the string is all alphanumeric before loading.*/
		if(find_if(x.begin(),x.end(),notalnum)==x.end())
			custom.push_back(x);
	
		else
			break;
	}
	cin.clear();
	cout<<"The sequence 'custom' contains\n";
	show_seq(custom);
	cout<<endl;
	
	transform(custom.begin(), custom.end(), back_inserter(upper_version),
		       	make_upper);
	cout<<"In all uppercase, that's \n";
	show_seq(upper_version);

	cout<<"\nPlease enter the string you would like to remove: ";
	cin>>x;
	cout<<"The elements remaining are \n";
	seq::iterator it=remove(custom.begin(), custom.end(), x);
	cleaned.insert(cleaned.end(),custom.begin(), it);
	show_seq(cleaned);
/* Note that the effect of 'remove' is effectively to copy all other 
 * elements to the beginning of the container, leaving the contents 
 * from the returned iterator to the end untouched.
 */
	cout<<"\nThe original sequence, from start to finish, "
		<<"now contains\n";
	show_seq(custom);
	

	return 0;
	

	
}

void show_seq(const seq& s)
{
	for(seq::const_iterator iter=s.begin(); iter!=s.end();++iter)
		cout<<*iter<<" ";
	
	return;
}

bool notalnum(char c)
{
	return !isalnum(c);
}

string make_upper(const string & orig)
{
	string ret;
	for(string::const_iterator i=orig.begin(); i!=orig.end(); i++)
		ret.push_back(toupper(*i));
	
	return ret;
}
			
	

