Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_CONTAINERS_READER_H
Toshihiro Shimizu 890ddd
#define TCG_CONTAINERS_READER_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <stack></stack>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tcg
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
//    Generic Reader declaration
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename val=""></typename>
Toshihiro Shimizu 890ddd
class generic_containers_reader
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef Val value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	virtual void openContainer() = 0;
Toshihiro Shimizu 890ddd
	virtual void addElement(const value_type &value) = 0;
Toshihiro Shimizu 890ddd
	virtual void closeContainer() = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// NOTE: Algorithms may require the openContainer() function to accept the
Toshihiro Shimizu 890ddd
	// container's header data. Check the algorithms description if necessary.
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
//    Some Actual Container Readers
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename container,="" container::value_type="" typename="" val="typename"></typename>
Toshihiro Shimizu 890ddd
class sequential_reader
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Container *m_values;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef Container container_type;
Toshihiro Shimizu 890ddd
	typedef Val value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	sequential_reader(Container *container)
Toshihiro Shimizu 890ddd
		: m_values(container) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void openContainer() { m_values->clear(); }
Toshihiro Shimizu 890ddd
	void addElement(const value_type &val) { m_values->push_back(val); }
Toshihiro Shimizu 890ddd
	void closeContainer() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const container_type *values() const { return m_values; }
Toshihiro Shimizu 890ddd
	container_type *values() { return m_values; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename container,="" container::value_type="" typename="" val="typename"></typename>
Toshihiro Shimizu 890ddd
class ordered_reader
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Container *m_values;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef Container container_type;
Toshihiro Shimizu 890ddd
	typedef Val value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	ordered_reader(Container &container)
Toshihiro Shimizu 890ddd
		: m_values(container) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void openContainer() { m_values->clear(); }
Toshihiro Shimizu 890ddd
	void addElement(const value_type &val) { m_values->insert(val); }
Toshihiro Shimizu 890ddd
	void closeContainer() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const container_type *values() const { return m_values; }
Toshihiro Shimizu 890ddd
	container_type *values() { return m_values; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename container,="" readertype,="" readertype::value_type="" typename="" val="typename"></typename>
Toshihiro Shimizu 890ddd
class multiple_reader
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef Container container_type;
Toshihiro Shimizu 890ddd
	typedef ReaderType reader_type;
Toshihiro Shimizu 890ddd
	typedef Val value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Toshihiro Shimizu 890ddd
	Container *m_storage;
Toshihiro Shimizu 890ddd
	std::stack<reader_type> m_stack;</reader_type>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	multiple_reader(Container *storage)
Toshihiro Shimizu 890ddd
		: m_storage(storage) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	reader_type &reader() { return m_stack.top(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void openContainer() { m_stack.push(reader_type(new typename reader_type::container_type)); }
Toshihiro Shimizu 890ddd
	void addElement(const value_type &val) { reader().addElement(val); }
Toshihiro Shimizu 890ddd
	void closeContainer()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (reader().values()->empty())
Toshihiro Shimizu 890ddd
			delete reader().values();
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			m_storage->push_back(reader().values());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_stack.pop();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const container_type &storage() const { return m_storage; }
Toshihiro Shimizu 890ddd
	container_type &storage() { return m_storage; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace tcg
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif //TCG_CONTAINERS_READER_H