Задание 5 (индивидуальное): метавычисления типов
Указания:
- Для реализации этого задания необходимо использовать библиотеку MPL.
- Задание необходимо выполнить в виде метафункции, принимающей входные данные в виде параметров (контейнеров MPL там, где требуется переменное количество типов).
Дана последовательность типов. Разделить её на две последовательности: одна должна состоять из базовых классов, вторая — из производных от них, стоящих на тех же позициях. Если это сделать невозможно, вывести сообщение об ошибке времени компиляции. Для первой последовательности сгенерировать интерфейс абстрактной фабрики, для второй — конкретной, создающей объекты в динамической памяти при помощи конструирования по умолчанию. Проверить работоспособность фабрики можно на следующем коде:
#define ABSTRACT(class) \ struct Abstract ## class \ { \ virtual ~Abstract ## class() {} \ virtual void print() = 0; \ }; \ \ struct class : public Abstract ## class \ { \ virtual void print() override \ { \ cout << #class << endl; \ } \ }; ABSTRACT(C1); ABSTRACT(C2); ABSTRACT(C3); typedef mpl::vector <C3, AbstractC1, AbstractC2, C1, AbstractC3, C2> Types; typedef factory <Types>::type FactoryPair; typedef FactoryPair::first AbstractFactory; typedef FactoryPair::second ConcreteFactory; void makeObjects(AbstractFactory &rFactory) { AbstractC1 *pC1 = rFactory.create <AbstractC1> (); AbstractC2 *pC2 = rFactory.create <AbstractC2> (); AbstractC3 *pC3 = rFactory.create <AbstractC3> (); pC1->print(); pC2->print(); pC3->print(); delete pC1; delete pC2; delete pC3; } int main() { ConcreteFactory factory; makeObjects(factory); }
Дана последовательность типов. Проверить, что все они являются объектными, найти максимальный размер среди них. Сгенерировать класс «интеллектуальное объединение», хранящий значение одного из перечисленных типов в области динамической памяти размера, достаточного для хранения максимального по размеру типа. Предусмотреть в классе конструктор, инициализирующий заданное значение, деструктор, операции получения и установки значения, семантику копирования и перемещения. Проверить работоспособность класса можно на следующем коде:
struct Test { int m_n; Test() : m_n(99) { cout << "Test()" << endl; } Test(const Test &rcT) : m_n(rcT.m_n) { cout << "Test(const Test &)" << endl; } ~Test() { cout << "~Test()" << endl; } }; int main() { typedef mpl::vector <int, float [10], std::string, Test> types; Test t; smart_union <types> u1(t); cout << u1.get <Test> ().m_n << endl; u1.set <std::string> ("abc"); cout << u1.get <std::string> () << endl; }
Дана последовательность типов. Проверить, что все они являются классами и упорядочить их так, чтобы производные классы находились раньше их базовых. Для полученной последовательности проверить, что все классы являются производными от последнего, и сгенерировать симметричный двойной линейный диспетчер.
Дана последовательность типов. Проверить, что все они являются классами и упорядочить их так, чтобы производные классы находились раньше их базовых. Для полученной последовательности проверить, что все классы являются производными от последнего, и сгенерировать симметричный тройной линейный диспетчер.
Дана последовательность типов. Проверить, что все они являются классами и удалить из них дубликаты. Для полученной последовательности сгенерировать циклический посетитель.
Дана последовательность типов. Проверить, что все они являются классами и удалить из них дубликаты. Для полученной последовательности сгенерировать ациклический посетитель.