#pragma once

#include <exception>


namespace util
{


template <typename T>
class Optional
{
public:
	Optional<T>() :
		m_Valid(false),
		m_Value(T())
	{
	}

	Optional<T>(const T& val) :
		m_Valid(true),
		m_Value(val)
	{
	}

	operator const T&(void) const
	{
		ThrowOnInvalid();
		return m_Value;
	}

	const T& Get(void) const
	{
		ThrowOnInvalid();
		return m_Value;
	}

	bool IsValid(void) const
	{
		return m_Valid;
	}

	void SetValue(const T& value)
	{
		m_Value = value;
		m_Valid = true;
	}

	void Reset(void)
	{
		m_Valid = false;
	}

private:
	void ThrowOnInvalid(void) const
	{
		if (!IsValid())
			throw std::exception();
	}


private:
	bool m_Valid;
	T    m_Value;
};


}
