/* Generated by Together */

#ifndef ENUMERATOR_H
#define ENUMERATOR_H

namespace KasperskyLicensing {

namespace Implementation { void Deallocate(void*); }

template <class T> class Enumerator
{
public:

	/**
	 * client should implement this interface
	 */
	class Implement
	{
	public:

		virtual ~Implement() {}

		/**
		 * clones object
		 */
		virtual Implement* Clone() const = 0;

		/**
		 * returns current item reference
		 */
		virtual T Item() const = 0;

		/**
		 * returns true if iterator is at the end of collection
		 */
		virtual bool IsDone() const = 0;

		/**
		 * advances iterator
		 */
		virtual void Next() = 0;
	};

	typedef T ValueType;

	/**
	 * creates iterator by given implementation class
	 */
	explicit Enumerator(Implement* i)
		: impl(i) {}

	/**
	 * copy constructor
	 */
	Enumerator(const Enumerator& e)
		: impl(e.impl ? e.impl->Clone() : 0) {}

	~Enumerator()
	{ 
		if (impl)
		{
			impl->~Implement();
			Implementation::Deallocate(impl);
		}
	}

	Enumerator& operator = (const Enumerator& e)
	{
		if (impl)
		{
			impl->~Implement();
			Implementation::Deallocate(impl);
		}
		impl = (e.impl ? e.impl->Clone() : 0);
		return *this;
	}

	bool IsValid() const
		{ return (impl != 0); }

	/**
	 * dereferences iterator
	 */
	T Item() const
		{ return impl->Item(); }

	/**
	 * returns true if iterator is at the end of collection
	 */
	bool IsDone() const
	{ return impl ? impl->IsDone() : true; }

	/**
	 * advances iterator
	 */
	Enumerator& Next()
	{ 
		impl->Next(); 
		return *this;
	}
private:

	/**
	 * iterator implementation
	 */
	Implement* impl;
};

} // namespace KasperskyLicensing

#endif // ENUMERATOR_H
