#include "double.h"
#include "debug.h"

/** \mainpage Задание: Библиотека отложенных вычислений LEva
 * \section leva Отложенные вычисления
 * Отложенные вычисления, ленивые вычисления или нестрогие вычисления (англ. lazy evaluation) — 
 * концепция, согласно которой вычисления следует откладывать до тех пор, 
 * пока не понадобится их результат.
 * Отложенные вычисления позволяют сократить общий объём вычислений за счёт тех вычислений, результаты которых 
 * не будут использованы. Программист может описывать зависимости функций друг от друга и не следить за тем, чтобы не осуществлялось «лишних вычислений».
 * 
 * \section task Задание
 * Реализовать на C++ идею отложенных вычислений для типа число с плавающей точкой (класс Double) на основании предоставленных <a href="leva.zip">заголовочных файлов</a>.
 * Задание предполагает реализацию отложенных вычислений:
 * \li с помощью деревьев абстрактных выражений (базовый класс Expression) - древовидных структур
 * данных, описывающих суперпозицию унарных (класс UnaryExpression, в составе + и -), бинарных (класс BinaryExpression, включая +, -) 
 * выражений и выражений-переменных (класс Variable),
 * вычисляющих свое значение (виртуальная функция Expression::eval) только при необходимости.
 * \li и с примением умных указателей на выражения - вспомогательного класса ExpPtr, обеспечивающего подсчет ссылок на выражение и его уничтожение при достижении 
 * числа ссылок значения 0.
 * 
 * Реализация подсчета значения выражения должна проводить журналирование своих действий в выходной поток dout в формате:
 * \li для переменной (Variable): (значение)
 * \li для унарной операции (UnaryExpression): (кодu,арг)
 * \li для бинарной операции (BinaryExpression): (кодb,арг1,арг2)
 * Примечание: считаем, что Variable "ленива" и осуществляет журналирование в виде "(значение)" только когда ее значение понадобилось.
 * 
 * Реализация умного указателя на выражение должна проводить журналирование своих действий в выходной поток dout:
 * \li '+' - увеличение числа ссылок на выражение на 1
 * \li '-' - уменьшение числа ссылок на выражение на 1
 * \li '~' - уничтожение выражение, связанного с умным указателем.
 * Примечание: уменьшение последней ссылки на 1, после которого число ссылок становится равным 0 и происходит удаление выражение, должно приводить
 * к отладочной печате в поток в виде "-~", а не только "~", т.е. сиганлизирование о последнем уменьшении числа указателей происходить должно.
 * 
 * \section sample Примеры выражений и ожидаемой отладочной печати.
 * \code
 * Double a(1), b(0.5);
 * Double c;
 * c = a + b;
 * cout << c;
 * \endcode
 * Содержимое dout: +++++++--~+-(+b,(1),(0.5))---~-~-~
 * 
 * \section requirements Требования
 * \li Отсутствие плагиата
 * \li Прохождение предоставленных тестов
 * \li Хороший код (хороший C++, модульность, именование, форматрирование)
 * \li Отсылка исходных архива со всеми отчетными материалами на адрес: <a href="mailto:prak@mlab.cs.msu.su">prak at mlab dot cs dot msu dot su</a>
 *
 * \section reports Отчетные материалы
 * \li Исходные тексты программы
 * \li Тестовые сценарии (допускается использование cppunit)
 * \li Файлы сборки (допускается использование make-фалов)
 * \li Отчет по реализации (допускается использование документирующих комментариев doxygen),
 *    детально описывающий Вашу реализацию (функции, данные, типы).
 * 
 * \section questions Вопросы, предложения, опечатки
 * Присылайте сюда: <a href="mailto:gerasimov@mlab.cs.msu.su">gerasimov at mlab dot cs dot msu dot su</a>
 */