1 Колотаев А. В. Использование библиотеки Boost.Mpl для построения программной архитектуры.

Презентация:



Advertisements
Похожие презентации
Язык C++ Лекция 2. Недостатки enumов Засорение namespaceа, в котором находится enum Соответственно, члены enumа должны иметь уникальный префикс.
Advertisements

Объектно-ориентированное программирование С++. Лекция 8 Карпов В.Э.
Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться.
Лекция 22. Шаблоны (часть 2) Красс Александр СПбГУ ИТМО, 2008.
Saint Petersburg, 2012 Java Lecture 12 JSTL. JSP -> JSTL JSP – хорошо Что делать если хотим добавить условие? Итерирование по списку и вывод каждого элемента.
Объектно-ориентированное программирование С++. Лекция 6 Карпов В.Э.
Объектно-ориентированное программирование С++. Лекция 9 Карпов В.Э.
Высокоуровневые методы информатики и программирования Лекция 9 Делегаты.
Перегрузка операторов x = a + b результат 1-й операнд2-й операнд оператор По количеству операндов операторы делятся на: унарные (один операнд) бинарные.
Разработка на CUDA с использованием Thrust Михаил Смирнов.
Лекция 23. Шаблоны (часть 3) Красс Александр СПбГУ ИТМО, 2008.
САОД кафедра ОСУ 1 Основные абстрактные типы данных Схема процесса создания программ для решения прикладных задач ВУ.
Д.з Язык С++ - занятие 31. Задача 1: 1/1 + 1/3 + 1/5 … #include using namespace std; int main() { int n; cin >> n; double sum = 0;// Сумма for.
©Павловская Т.А. Язык С++ Курс «С++. Программирование на языке высокого уровня» Павловская Т.А.
Обработка исключительных ситуаций Исключительная ситуация (исключение) – это ошибка, возникающая во время выполнения программы. Например, ошибка работы.
Дружественные функции Дружественные функции – это функции, объявленные вне класса, но имеющие доступ к закрытым и защищенным полям данного класса Дружественная.
Учебный курс Объектно-ориентированный анализ и программирование Лекция 7 Методы как средство реализации операций Лекции читает кандидат технических наук.
Статические поля класса Статические поля хранят данные, общие для всех элементов класса. Статическое поле существует в единственном экземпляре для всех.
1 Переопределение операций Макаревич Л. Г.. 2 Зачем нужна перегрузка операций? class Complex { double re; double im; public: Complex(double r=0, double.
Лекция 25. Введение в STL (часть 2) Красс Александр СПбГУ ИТМО, 2009.
Транксрипт:

1 Колотаев А. В. Использование библиотеки Boost.Mpl для построения программной архитектуры

2 Содержание s Краткий обзор библиотеки Boost.Mpl l Понятие метафункции, placeholder expression, лямбда-выражение l Средства Boost.Mpl: последовательности (mpl::vector, mpl::list), алгоритмы (mpl::fold), виды (mpl::joint_view, mpl::filter_view) s Использование Boost.Mpl l Описание проекта l Поддержка приема CRTP l Реализация паттерна Состояние

3 Библиотека Boost.Mpl Доступна по адресу

4 Метафункция Def. Класс или шаблон класса с публично доступным типом-членом type. template struct add_pointer { typedef T * type; }; Вызов: typedef add_pointer ::type pInt; // pInt == int*

5 Специализация метафункции Первичный шаблон, предоставленный разработчиком библиотеки: template struct func { typedef generic_implementation type; }; Специализация пользователем библиотеки для своего типа: template struct func > { typedef specialisation_for_my_class type; };

6 // library code template struct sequence_tag { typedef typename T :: sequence_tag type; }; template struct library_func_impl; template struct library_func : library_func_impl ::type> // ::type {}; // user code struct my_sequence_tag; struct MySequenceA { typedef my_sequence_tag sequence_tag; /*...*/ }; struct MySequenceB { typedef my_sequence_tag sequence_tag; /*...*/ }; template struct library_func_impl { typedef my_implementation type; }; Tag dispatching

7 Класс метафункции Def. Класс метафункции – класс или шаблон класса с публично доступной вложенной метафункцией apply. #include namespace mpl = boost::mpl; struct add_pointer_f { template struct apply : add_pointer {}; }; template struct twice // twice(Func, T) == Func(Func(T)) : mpl::apply ::type> {}; int **p = twice ::type(0);

8 Placeholder expression Def. Placeholder expression – это либо заместитель, либо специализация шаблона класса, у которого хотя бы один аргумент placeholder expression. #include using namespace mpl::placeholders; typedef twice add_pointer_twice; int **p = mpl::apply ::type(0); Позволяет формировать новые метафункции, связывая с параметрами существующих метафункций некоторые значения Позволяет формировать новые метафункции как композицию существующих метафункций Превращение обычных шаблонов классов в placeholder expression typedef mpl::apply, T>::type vector_of_T; Легкая интеграция метапрограмм и существующих шаблонов

9 Лямбда-выражения Def. Лямбда-выражение – это метаданные, которые могут быть вызваны при помощи mpl::apply. Формы лямбда-выражения Класс метафункции Placeholder expression

10 Последовательности s Произвольного доступа l mpl::vector, mpl::deque, s Однонаправленные l mpl::list s Ассоциативные l mpl::map, mpl::set typedef mpl::vector types; // найти положение long в types typedef mpl::find ::type long_pos; // разыменовать итератор typedef mpl::deref ::type x; // проверяем, что получили ожидаемый результат BOOST_STATIC_ASSERT((boost::is_same ::value));

11 Алгоритм mpl::fold struct A{}; struct B{}; struct C{}; struct D{}; struct bases_for_X : mpl::vector {}; template struct inherit_2 : First, Second {}; struct X : mpl::fold< bases_for_X, mpl::empty_base, inherit_2 >::type {}; X inherit_2 D C B A empty_base

12 Задание цепочки действий struct empty_updator { void update(double){} }; template struct inherit_and_define_update : Tail, Head { void update(double time) { Tail::update(time); Head::update(time); } }; struct X : mpl::fold >::type {}; Вызов X::update сведется к вызову A::update, B::update, C::update, D::update.

13 Views – адаптеры последовательностей s «Ленивые» s Неизменяемые struct bases_for_X : mpl::joint_view, mpl::vector > {}; // bases_for_X ~ mpl::vector struct filtered_bases : mpl::filter_view > {}; // filtered_bases ~ mpl::vector struct transformed : mpl::transform_view > {}; // transformed ~ mpl::vector

14 Curiously Recurring Template Pattern Def. Наследование класса X от специализации шаблона класса, принимающей аргументом класс X. struct X : base { /*...*/ }; Доступ из базового класса к членам наследника осуществляется при помощи указателя this, приведенного к типу указателя на наследник. template struct BaseA { void method1() { self().baseB().method2(); } BaseA & baseA() { return *this; } private: Derived & self() { return static_cast (*this); } };

15 inherit_crtp struct MyComponent : BaseA, BaseB, BaseC { /*...*/ }; При таком подходе список базовых классов (BaseA, BaseB, BaseC ) трудно использовать в качестве базовых для другой компоненты. struct bases : mpl::vector, BaseB, BaseC > {}; struct MyComponent : inherit_crtp ::type { /*...*/ };

16 «Вложенные» цепочки базовых классов struct damage_listeners : mpl::vector< HitPoints, SmokeEmitter, HitPrints > {}; struct actions : mpl::vector< CheckValidPosition, ProcessTargets, UpdatePosition > {}; struct bases : mpl::vector< BaseA, OnDamage, OnUpdate > {};

17 Класс конфигурации Агрегирует параметры компоненты. Базовые классы для получения связанных типов обращаются в класс конфигурации компоненты. Классы конфигурации удобно наследовать друг от друга. Списки базовых классов объединяются, например, при помощи mpl::joint_view. Для того, чтобы в наследнике можно было переопределить некоторые метаданные, они должны быть представлены в виде лямбда- выражений, принимающих параметром класс конфигурации.

18 Пример: FSM (из Mpl Book) // concrete FSM implementation class player : public state_machine { private: // the list of FSM states enum states { Empty, Open, Stopped, Playing, Paused, initial_state = Empty }; // transition actions void start_playback(play const&); void open_drawer(open_close const&); void close_drawer(open_ close const&); void store_cd_info(cd_detected const&); void stop_playback(stop const&); void pause_playback(pause const&); void resume_playback(play const&); void stop_and_open(open_close const&); // continued on the next page

19 Пример: FSM (продолжение) // transition actions friend class state_machine ; typedef player p; // makes transition table cleaner // transition table struct transition_table : mpl::vector11< // Start Event Next Action // row, // row, // row, // row, // row, row // > {}; };

20 Использование реализованного State Pattern struct boat_cfg { struct states { // Идентификаторы состояний enum Id { ACTIVE, HIDING, HIDDEN, APPEARING }; // События, инициирующие переходы // self().processAction(actions::Appear()); struct actions { struct Appear{}; struct Hide{}; struct Leave{}; }; // базовые классы интерфейса абстрактного состояния struct bases : mpl::vector {}; // прокси-классы struct proxies : mpl::vector< proxy::PositionHolder, proxy::MustHave, proxy::ExplosionMaker > {}; // интерфейс абстрактного состояния struct IState base_type;

21 Использование реализованного State Pattern // описание состояния struct active { const static Id ID = ACTIVE; // метафункция, позволяющая описание состояния переопределять в //наследниках THE_STATE_IS_OVERRIDABLE(active) template struct apply { typedef typename T :: states :: active type; }; // базовые классы конкретного состояния struct bases : mpl::vector< CollisionTypeRobotGround, Active > {}; // класс конкретного состояния typedef State state_type; };

22 Использование реализованного State Pattern struct hiding { /*...*/ }; struct hidden { /*...*/ }; struct appearing { /*...*/ }; // начальное состояние typedef hidden initial; // таблица переходов struct Transitions : mpl::vector< fsm::row, fsm::row > {};

23 Диаграмма сгенерированного конкретного состояния

24 Возможности данной реализации паттерна s Независимость базовых классов, от того, являются ли они базовыми для класса состояния или основного объекта s Простая реализация вложенных состояний