#pragma once

template <class T>
class ConnectedObject
{
private:

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// before this object
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	ConnectedObject<T>* m_prev;

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// after this object
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	ConnectedObject<T>* m_next;

public:

	virtual T* prev();
	virtual T* next();
	virtual T* get();

	virtual const T* const_prev();
	virtual const T* const_next();
	virtual const T* const_get();

	ConnectedObject();
	void connect(ConnectedObject<T>* prev, ConnectedObject<T>* next);
};

template<typename T>
const T* ConnectedObject<T>::const_prev()
{
	return static_cast<const T*>(m_prev);
}

template<typename T>
const T* ConnectedObject<T>::const_next()
{
	return static_cast<const T*>(m_next);
}

template<typename T>
const T* ConnectedObject<T>::const_get()
{
	return static_cast<const T*>(this);
}

template<typename T>
T* ConnectedObject<T>::get()
{
	return static_cast<T*>(this);
}

template<typename T>
T* ConnectedObject<T>::prev()
{
	return static_cast<T*>(m_prev);
}

template<typename T>
T* ConnectedObject<T>::next()
{
	return static_cast<T*>(m_next);
}

template<typename T>
ConnectedObject<T>::ConnectedObject()
	:
	m_prev(nullptr),
	m_next(nullptr)
{
}

template<typename T>
void ConnectedObject<T>::connect(ConnectedObject<T>* prev, ConnectedObject<T>* next)
{
	m_prev = prev;
	m_next = next;
}