#pragma once

class Expression;

/**
 * Умный указатель на Выражение (Expression).
 *
 * Реализует логику контроля ссылок при операциях копирования и уничтожение выражения при исчезновении последней ссылки на него.
 */
class ExpPtr
{
	/// Выражение.
	Expression * _exp;

	/// Счетчик ссылок.
	unsigned int * _refCount;
	
	/**
	 * Логика копирования одного умного указателя в другой.
	 *
	 * @param other другой умный указатель
	 */
	void _copy(const ExpPtr & other);

	/**
	 * Логика уничтожения ссылки.
	 *
	 * При уничтожении последней ссылки освобождаются ресурсы.
	 */
	void _release();

public:
	/**
	 * Коструктор из Выражения.
	 *
	 * @param exp выражение
	 */
	ExpPtr(Expression * exp);

	/**
	 * Конструктор копирования.
	 *
	 * @note Используем _copy.
	 */
	ExpPtr(const ExpPtr & other);

	/**
	 * Оператор присваивания.
	 *
	 * @note Используем _copy, _release.
	 */
	ExpPtr & operator=(const ExpPtr & other);

	/**
	 * Деструктор.
	 *
	 * @note Используем _release.
	 */
	~ExpPtr();

	/**
	 * Доступ к полям Выражения.
	 */
	Expression * operator->();
};
