Re[3]: Метапрограммирование в примерах
От: Abyx Россия  
Дата: 07.05.15 10:18
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Я не хочу читать 2000+ файлов и анализировать их, [...] Я же хочу некий труд: заметку, статью, которая покажет на примерах полезные практики и варианты использования.


то есть сам ты трудиться не хочешь, а хочешь чтобы кто-то потрудился за тебя. понятно.
In Zen We Trust
Re[5]: Метапрограммирование в примерах
От: Evgeny.Panasyuk Россия  
Дата: 07.05.15 10:30
Оценка: 2 (1)
Здравствуйте, kaa.python, Вы писали:

EP>>Шаблоны используются не только для метапрограммирования. А метапрограммирование возможно и без MPL/Fusion/Hana.

EP>>Топик же называется "Метапрограммирование в примерах", а не "MPL/Fusion/Hana в примерах" — поэтому и уточняю.
KP>Ты прав, переименовал.

Ок, несколько примеров:
1. Сериализация
Автор: Evgeny.Panasyuk
Дата: 06.10.14
на базе Boost.Fusion — описываем структуры через BOOST_FUSION_DEFINE_STRUCT и автоматом получаем serialize, operator<, operator==, hash_value, и любой другой необходимый обход этих структур. Например понадобилось при реализации паука обходящего P2P сеть Bitcoin, причём когда понадобился текстовый dump сообщений — достаточно было только написать соответствующий код рекурсивного обхода структур.
2. MPL используется внутри Boost.Variant — мне он часто требуется в реальных проектах.
3. MPL и Fusion используются внутри Boost.Spirit, который например мне понадобился для парсинга грамматики в реальном проекте — более удобной альтернативы я не знаю.
4. MPL используется внутри Boost.TypeErasure, который помогает делать штуки типа std::function и any_iterator (практичность и полезность которых думаю сомнений не вызывает).
5. Товарищ jazzer подробно описывал
Автор: jazzer
Дата: 02.04.08
конкретный пример использования MPL и Variant в реальном проекте.

Книжек фокусирующихся на примерах использования MPL и Fusion — я не видел.
Но например по Fusion мне вполне хватило примеров из документации к библиотеке — это библиотека для работы с гетерогенными структурами данных, в том числе позволяющая эмулировать compile-time reflection/introspection/reification. Опять таки, думаю полезность reflection не вызывает никаких сомнений.

EP>>Это считается примером или нет?

KP>Этот текст? Думаю, очевидно что нет.

Нет, не текст, а Eigen. Мне в реальном проекте понадобился Eigen, внутри которого много template metaprogramming.
Re: MPL/Fusion/Hana в примерах
От: OlegMax  
Дата: 07.05.15 10:31
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>"была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили"


Попробую свой пример изложить. Есть стандарт SVG.
В SVG много элементов, у каждого элемента свой набор атрибутов (пересекающийся с другими эл-тами). У каждого атрибута есть тип.
Эту часть спецификации можно реализовать рантайм возможностями языка (виртуальные ф-ции или свичи) или в compile-time, тогда то и начинается метапрограммирование и, местами, MPL. Кстати, эл-тами MPL контейнеров у меня всегда были не "настоящие" типы, а тэги (пустые классы), возможно это характерно для MPL.

Программист должен иметь возможность выбрать, какие элементы и атрибуты SVG обрабатывать. Это опять же можно сделать в рантайме, но тогда нет compile-time проверки, что программист готов принять данные, которые он выбрал для обработки — только рантайм ассерты. Или же предлагаем ему передать MPL контейнер с тэгами эл-тов и атрибутов, которые он хочет обрабатывать. В последнем случае получаем zero overhead, "not pay for what you don't use" и код пользователя, соответствующий заказанным фичам. И никакого неиспользуемого кода в бинарниках.

Вобщем, если спецификация SVG понятна, можете прикинуть архитектуру такой библиотечки и там автоматически должен возникнуть MPL.
Re: MPL/Fusion/Hana в примерах
От: niXman Ниоткуда https://github.com/niXman
Дата: 07.05.15 18:27
Оценка: -1
Здравствуйте, kaa.python, Вы писали:

KP>MPL/Fusion/Hana

в рамках некоторого проекта появились восточные коллеги, которые много рассказывают про SPROUT.
выглядит очень солидно
дока, правда, недописана... та и без нее вроде все понятно.

непременно опробую, когда появится подходящая задача.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: MPL/Fusion/Hana в примерах
От: jazzer Россия Skype: enerjazzer
Дата: 08.05.15 04:03
Оценка: 12 (1)
Здравствуйте, kaa.python, Вы писали:

KP>Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек? Ну, так что бы десяток-другой примеров, хотя бы, в духе "была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили". Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы


Вот старый боевой пример: http://rsdn.ru/forum/cpp/2899831
Автор: jazzer
Дата: 02.04.08

Вот еще пример: http://rsdn.ru/forum/cpp/3722136
Автор: jazzer
Дата: 02.03.10

Подход родился при решении реальной задачи на работе (и именно поэтому он такой, какой есть, а не проще — потому что в реальной задаче все сильно развесистей и MPL очень помогает с этой развесистостью справиться — у меня в реальном коде условия генерятся через MPL, а не запиываются сразу все целиком, как в статье).

Вот еще: http://rsdn.ru/forum/cpp/4544930.1
Автор: jazzer
Дата: 16.12.11
(посмотри там на скрытую секцию про макрос PYTHON_DECL — это, опять же, мой рабочий код с кучей (реально кучей, несколько файлов) метапрограммирования внутри, как на препроцессоре, так и на MPL)

Вот еще топик был небольшой: http://rsdn.ru/forum/cpp/4530248
Автор: jazzer
Дата: 07.12.11

и еще один, еще более старый: http://rsdn.ru/forum/cpp.applied/1258144
Автор: Anton V. Kolotaev
Дата: 06.07.05
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: MPL/Fusion/Hana в примерах
От: zaufi Земля  
Дата: 13.05.15 20:21
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Очень часто слышу мнение о невероятной полезности MPL (было дело, пару раз нашел ей применение) подобный библиотек. Сейчас вот Hana подоспела, которая тоже невероятно полезна. Так вот, а не видел ли кто некого труда, можно по аналогии с творением от GoF о реальных или более-менее похожих на реальность вариантах использования этих библиотек? Ну, так что бы десяток-другой примеров, хотя бы, в духе "была пробелема Ы, в при помощи замечательной MPL/Hana мы её очень эффективно решили". Лично я, когда читаю приложенную документацию и/или тесты, понимаю что "все очень круто", но вопрос "а нахрена?" меня никак не покидает уже многие годы


мои 5¢ -- http://rsdn.ru/forum/cpp.applied/4429917.1
Автор: zaufi
Дата: 21.09.11

в этом качестве использовал MPL не раз! возможность не допускать недопустимое использование библиотеки/класса на этапе компиляции бесценна!

MPL вообще часто нужен^W незаменим там, где есть необходимость что-то сделать для множества типов (масло маслянное %) ... сообщений, например, или типов которыми можно (разрешено) инстанциировать что-то (т.е. всеми остальными нельзя). или вот доводилось делать вектор MPLных пар, в котором first это compile time predicate для типа, а second это функтор, который умеет "обрабатывать" данный тип.

до появления variadic templates boost::fusion выручал когда нужно было в зависимости от параметров шаблона генерить в классе методы с непонятным (до компиляции) числом параметров и хранить их до момента вызова или "постепенно" (по очереди) отдавать во внутренние функции вызываемые из "главной"...
Re[6]: Метапрограммирование в примерах
От: Tilir Россия http://tilir.livejournal.com
Дата: 14.05.15 11:20
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>3. MPL и Fusion используются внутри Boost.Spirit, который например мне понадобился для парсинга грамматики в реальном проекте — более удобной альтернативы я не знаю.


Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны. У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст.

Так что для масштабируемости лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов.

Что относится и ко всему прочему MP. Оно должно быть маленьким и очень локальным, если вы не хотите собирать свой проект годами.
Re[7]: Метапрограммирование в примерах
От: jazzer Россия Skype: enerjazzer
Дата: 14.05.15 11:55
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны. У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст.


Вообще странно — у них что, парсинг прям везде?
Потому что обычно парсинг — это один файл, который почти не меняется. Ну скомпилируется он один раз долго — ну и хрен бы с ним
Работа основная (и перекомпиляция) в других файлах идет, не в парсилке же (я надеюсь).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[7]: Метапрограммирование в примерах
От: swingus  
Дата: 14.05.15 12:17
Оценка:
Не знаю. У меня сложилось такое впечатление, что основной ограничитель компиляции сложных конструкций — память. Добавил до 10 GB и перешёл на x64 (target executable x32), такое ощущение, что время компиляции растёт более-менее линейно от сложности (VC++).

Здравствуйте, Tilir, Вы писали:

T>Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>>3. MPL и Fusion используются внутри Boost.Spirit, который например мне понадобился для парсинга грамматики в реальном проекте — более удобной альтернативы я не знаю.


T>Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны. У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст.


T>Так что для масштабируемости лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов.


T>Что относится и ко всему прочему MP. Оно должно быть маленьким и очень локальным, если вы не хотите собирать свой проект годами.
Re[7]: Метапрограммирование в примерах
От: Evgeny.Panasyuk Россия  
Дата: 14.05.15 12:52
Оценка:
Здравствуйте, Tilir, Вы писали:

EP>>3. MPL и Fusion используются внутри Boost.Spirit, который например мне понадобился для парсинга грамматики в реальном проекте — более удобной альтернативы я не знаю.

T>Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны.

Что значит "потому что шаблоны"? Шаблоны сами по себе не увеличивают время компиляции экспоненциально. Экспоненциальная сложность может быть у конкретной метапрограммы, но не у шаблонов в общем.

По поводу Spirit — да, компилируется медленно, PCH / Unity Builds помогают только отчасти.
Но я видел в открытых проектах грамматики, которые больше моих на порядки. Если бы рост действительно был бы экспоненциальным — то компиляция занимала бы какое-то нереальное время.

T>У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст.

T>Так что для масштабируемости

Я использовал Spirit для небольших грамматик, которые даже в самой пессимистичной перспективе не могли вырасти до больших размеров — вполне себе пример для сабж.

T>лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов.


Если наткнулись на баг в Spirit'е (экспоненциальная сложность там где её быть не должно) — то нужно открыть ticket в их trac'е.

T>Что относится и ко всему прочему MP. Оно должно быть маленьким и очень локальным, если вы не хотите собирать свой проект годами.


Оно может быть большим и глобальным, и при этом проект будет собираться быстро. Оно также может быть "маленьким и очень локальным" — но проект будет собираться годами
Re[8]: Метапрограммирование в примерах
От: Evgeny.Panasyuk Россия  
Дата: 14.05.15 12:56
Оценка:
Здравствуйте, swingus, Вы писали:

S>Не знаю. У меня сложилось такое впечатление, что основной ограничитель компиляции сложных конструкций — память. Добавил до 10 GB и перешёл на x64 (target executable x32), такое ощущение, что время компиляции растёт более-менее линейно от сложности (VC++).


Насколько я знаю, у VS до сих пор 32-битный компилятор C++. Тем не менее, добавленная память может использоваться например под дисковый кэш.
Re[7]: Метапрограммирование в примерах
От: AndrewJD США  
Дата: 14.05.15 14:24
Оценка: -1
Здравствуйте, Tilir, Вы писали:

T>Boost.Spirit штука очень коварная -- оно сначала кажется няшным и все такое, а потом вы добавляете ещё фичу и ещё и замечаете, что у вас время компиляции выросло экспоненциально при линейном вроде добавлении фич. Потому что шаблоны. У нас в соседнем отделе ребята с таким столкнулись, теперь больно и тоскливо, а сделать уже нечего -- переписывать все с нуля никто не даст.


Время компиляции — это одна сторона. Boost.Spirit жуткий тормоз в рантайме. Если хоть немного важна скорость парсинга, то лучше сразу смотреть на альтернативы.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[8]: Метапрограммирование в примерах
От: Tilir Россия http://tilir.livejournal.com
Дата: 14.05.15 15:24
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

T>>лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов.


EP>Если наткнулись на баг в Spirit'е (экспоненциальная сложность там где её быть не должно) — то нужно открыть ticket в их trac'е.


Такого рода "баг" это очень часто "споткнулись на неявном неправильном использовании". Свести к простому примеру? Часто не сводится. Выкладывать полностью? Очень много проприетарного кода который не хочется открывать даже примерно.

И, кстати, локализация "где именно взорвались" для шаблонов это праздник. Потому что раскрывалки шаблонов (аналог -E для макросов) не существует, насколько мне известно. Я в таких случаях смотрю гимпл (это такой IR в GCC) и даю ценные советы на уровне "ну вот тут же у вас 100500 экземпляров создалось" после чего люди действительно могут (иногда и очень примерно) найти у себя проблему.

Вот кстати интересно -- а кто что использует для получения "препроцессированных" исходников после всех шаблонных подстановок? Может уже все давно спасены и я один во мраке?
Re[9]: Метапрограммирование в примерах
От: Evgeny.Panasyuk Россия  
Дата: 14.05.15 17:13
Оценка: 8 (1)
Здравствуйте, Tilir, Вы писали:

T>>>лучше flex/bison они хоть и хардкорны, но не таят гнилых сюрпризов.

EP>>Если наткнулись на баг в Spirit'е (экспоненциальная сложность там где её быть не должно) — то нужно открыть ticket в их trac'е.
T>Такого рода "баг" это очень часто "споткнулись на неявном неправильном использовании". Свести к простому примеру? Часто не сводится. Выкладывать полностью? Очень много проприетарного кода который не хочется открывать даже примерно.

По моему опыту часто всё локализуется через банальное "разделяй и властвуй" — причём это относится не только к шаблонному мета-программированию.
И только в редких случаях важны какие-то сайд-эффекты влияния под-частей друг на друга (так что при удалении/выключении одной из них исследуемый эффект пропадает).

T>Вот кстати интересно -- а кто что использует для получения "препроцессированных" исходников после всех шаблонных подстановок?


Что конкретно имеется в виду? Для какой цели?
Если для выявления самой долгой instantiation — то тут нужно не раскрытие, а замеры времени.
Если для тестирования — то здесь нужны unit-test'ы, а не результирующие подстановки.
По большому счёту для макросов (или для кодогенерации) результирующие подстановки полезны потому что манипуляция происходит на уровне конкатенации незаконченных текстовых фрагментов кода (которые могут комбинироваться причудливыми способами), в случае же шаблонов картина принципиально иная.
Если же речь идёт не про результирующие подстановки, а про своего рода backtrace воплощений с промежуточными аргументами — то каждый современный компилятор C++ умеет его выводить (при compile error; которую при необходимости можно спровоцировать вручную).
Если же для оценки оптимальности результирующего кода — то тут естественно нужно смотреть в результирующий ASM.

T>Может уже все давно спасены и я один во мраке?


Для отладки и профилирования шаблонного кода создаются разные утилиты, например: Metashell, Templight. Но я пока обхожусь без их помощи.
Re[8]: Метапрограммирование в примерах
От: alex_public  
Дата: 14.05.15 21:02
Оценка: +1
Здравствуйте, AndrewJD, Вы писали:

AJD>Время компиляции — это одна сторона. Boost.Spirit жуткий тормоз в рантайме. Если хоть немного важна скорость парсинга, то лучше сразу смотреть на альтернативы.


Эээ что? ) Как раз Boost.Spirit один из самых быстрых парсеров. У него скорее другие проблемы. Ориентация на не особо сложные грамматики и проблематичные ошибки (общая проблема всего метапрограммирования на шаблонах). А уж со скоростью там всё отлично. )
Re[9]: Метапрограммирование в примерах
От: swingus  
Дата: 14.05.15 21:12
Оценка:
Там у виндов ограничение на кол-во памяти. Кроме какой-то серверной версии и ключей запуска, все они юзают максимум 4GB.

Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, swingus, Вы писали:


S>>Не знаю. У меня сложилось такое впечатление, что основной ограничитель компиляции сложных конструкций — память. Добавил до 10 GB и перешёл на x64 (target executable x32), такое ощущение, что время компиляции растёт более-менее линейно от сложности (VC++).


EP>Насколько я знаю, у VS до сих пор 32-битный компилятор C++. Тем не менее, добавленная память может использоваться например под дисковый кэш.
Re[10]: Метапрограммирование в примерах
От: Evgeny.Panasyuk Россия  
Дата: 14.05.15 21:22
Оценка:
Здравствуйте, swingus, Вы писали:

S>>>Не знаю. У меня сложилось такое впечатление, что основной ограничитель компиляции сложных конструкций — память. Добавил до 10 GB и перешёл на x64 (target executable x32), такое ощущение, что время компиляции растёт более-менее линейно от сложности (VC++).

EP>>Насколько я знаю, у VS до сих пор 32-битный компилятор C++. Тем не менее, добавленная память может использоваться например под дисковый кэш.
S>Там у виндов ограничение на кол-во памяти. Кроме какой-то серверной версии и ключей запуска, все они юзают максимум 4GB.

Ты о чём? Если бы компилятор (cl.exe) был x64 — то он мог бы спокойно использовать больше 4GiB.
4GiB это ограничение для x32 процессов в x64 Windows.
Отредактировано 14.05.2015 21:23 Evgeny.Panasyuk . Предыдущая версия .
Re[8]: Метапрограммирование в примерах
От: Tilir Россия http://tilir.livejournal.com
Дата: 15.05.15 04:13
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Потому что обычно парсинг — это один файл, который почти не меняется. Ну скомпилируется он один раз долго — ну и хрен бы с ним


Если что-то можно унести в один файл и забыть, никакого метапрограммирования там вообще не нужно. MP удобно как раз для мест, где нечто расползлось по всему коду и генерировать это одним файлом сложно или неудобно.
Re[10]: Метапрограммирование в примерах
От: Tilir Россия http://tilir.livejournal.com
Дата: 15.05.15 04:26
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>По моему опыту часто всё локализуется через банальное "разделяй и властвуй" — причём это относится не только к шаблонному мета-программированию.

EP>И только в редких случаях важны какие-то сайд-эффекты влияния под-частей друг на друга (так что при удалении/выключении одной из них исследуемый эффект пропадает).

Комбинаторные взрывы при MP по моему опыту не локализуются: вы что-то убираете у вас все хорошо, добавляете снова у вас все плохо. Это что-то само является какой-то мрачной запутанной фигней из сторонней библиотеки вроде boost::spirit и отлично работает если вы его вставляете в hello world. "Ну и всё, приехали".

EP>Что конкретно имеется в виду? Для какой цели?


Посмотреть на плюсовый код после всех шаблонных подстановок. На уровне: "сколько раз раскрылся вот этот вот шаблон и с какими параметрами".
Цели в основном: оценка оверхеда по размеру кода, поиск узких мест по времени компиляции.

EP>Если же для оценки оптимальности результирующего кода — то тут естественно нужно смотреть в результирующий ASM.


Ассемблер после оптимизирующего компилятора с LTO это мелко рубленная каша, лучше уж IR на начальных фазах.

T>>Может уже все давно спасены и я один во мраке?


EP>Для отладки и профилирования шаблонного кода создаются разные утилиты, например: Metashell, Templight. Но я пока обхожусь без их помощи.


mdb забавная штука, спасибо, не знал.
Re[9]: Метапрограммирование в примерах
От: jazzer Россия Skype: enerjazzer
Дата: 15.05.15 04:47
Оценка: +1
Здравствуйте, Tilir, Вы писали:

T>Здравствуйте, jazzer, Вы писали:


J>>Потому что обычно парсинг — это один файл, который почти не меняется. Ну скомпилируется он один раз долго — ну и хрен бы с ним


T>Если что-то можно унести в один файл и забыть, никакого метапрограммирования там вообще не нужно. MP удобно как раз для мест, где нечто расползлось по всему коду и генерировать это одним файлом сложно или неудобно.


Почему же не нужно? Вот спирит — сплошное МП, но в реальном проекте он используется в одном-двух файлах, когда надо что-то парсить.
Не много же проектов, где парсинг — главная часть приложения.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.