/* Lecture code 15.0
 *
 * count_if plus a LessThan functor.
 */

#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <string>
#include <sstream>
using namespace std;

/* Reads a line from the console and returns it. */
string GetLine()
{
	string result;
	getline(cin, result);
	return result;
}

/* Read an integer, prompting until the user enters valid data. */
int GetInteger()
{
	while(true)
	{
		stringstream converter;
		converter << GetLine(); // Read data and load into the stream.
		
		/* Try to read an int. */
		int result;
		converter >> result;
		
		/* If we read an int successfully, see if anything's left over. */
		if(!converter.fail())
		{
			/* Try to read a single char.  In class we used a string, but
			 * this approach works as well.
			 */
			char remaining;
			converter >> remaining;
			
			/* If the stream broke, we ran out of characters and are done. */
			if(converter.fail())
				return result;
			else
				cout << "Unexpected character: " << remaining << endl;
		}
		else
			cout << "Please enter an integer." << endl;
		
		cout << "Retry: ";
	}
}

/* A comparison functor that returns if its parameter is less than a
 * stored value.
 */
class LessThan
{
public:
	/* Constructor just stores values. */
	explicit LessThan(int maxValue): upperBound(maxValue)
	{
	}

	/* Functor operation compares the value to the stored value. */
	bool operator() (int value) const
	{
		return value < upperBound;
	}
private:
	const int upperBound;
};

int main()
{
	cout << "Enter upper bound: ";
	const int maxValue = GetInteger();

	ifstream input("numbers.txt");
	
	/* Read in from an ifstream using iterators, and compare using a temporary LessThan object. */
	cout << count_if(istream_iterator<int>(input), istream_iterator<int>(), LessThan(maxValue)) << endl;
	return 0;
}