Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 10 лет назад пользователемspiiras.nw.ru
1 1 Колотаев А. В. Использование библиотеки Boost.Mpl для построения программной архитектуры
2 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 3 Библиотека Boost.Mpl Доступна по адресу
4 4 Метафункция Def. Класс или шаблон класса с публично доступным типом-членом type. template struct add_pointer { typedef T * type; }; Вызов: typedef add_pointer ::type pInt; // pInt == int*
5 5 Специализация метафункции Первичный шаблон, предоставленный разработчиком библиотеки: template struct func { typedef generic_implementation type; }; Специализация пользователем библиотеки для своего типа: template struct func > { typedef specialisation_for_my_class type; };
6 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 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 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 9 Лямбда-выражения Def. Лямбда-выражение – это метаданные, которые могут быть вызваны при помощи mpl::apply. Формы лямбда-выражения Класс метафункции Placeholder expression
10 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 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 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 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 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 15 inherit_crtp struct MyComponent : BaseA, BaseB, BaseC { /*...*/ }; При таком подходе список базовых классов (BaseA, BaseB, BaseC ) трудно использовать в качестве базовых для другой компоненты. struct bases : mpl::vector, BaseB, BaseC > {}; struct MyComponent : inherit_crtp ::type { /*...*/ };
16 16 «Вложенные» цепочки базовых классов struct damage_listeners : mpl::vector< HitPoints, SmokeEmitter, HitPrints > {}; struct actions : mpl::vector< CheckValidPosition, ProcessTargets, UpdatePosition > {}; struct bases : mpl::vector< BaseA, OnDamage, OnUpdate > {};
17 17 Класс конфигурации Агрегирует параметры компоненты. Базовые классы для получения связанных типов обращаются в класс конфигурации компоненты. Классы конфигурации удобно наследовать друг от друга. Списки базовых классов объединяются, например, при помощи mpl::joint_view. Для того, чтобы в наследнике можно было переопределить некоторые метаданные, они должны быть представлены в виде лямбда- выражений, принимающих параметром класс конфигурации.
18 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 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 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 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 22 Использование реализованного State Pattern struct hiding { /*...*/ }; struct hidden { /*...*/ }; struct appearing { /*...*/ }; // начальное состояние typedef hidden initial; // таблица переходов struct Transitions : mpl::vector< fsm::row, fsm::row > {};
23 23 Диаграмма сгенерированного конкретного состояния
24 24 Возможности данной реализации паттерна s Независимость базовых классов, от того, являются ли они базовыми для класса состояния или основного объекта s Простая реализация вложенных состояний
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.