Возник на днях у нас вопрос: «Как спрятать от любителей hex-редаторов строчки текста в скомпилированном приложении?». Но спрятать так, чтобы это не требовало особых усилий, так, между прочим…
Задача состоит в том, что бы использовать в коде строки как обычно, но при этом в исполняемом файле эти строки в явном виде не хранились, возможности сторонних утилит, которые работают с уже скомпилированными бинарными файлами, задействовать так же не хочется, все нужно делать из обычного C++ кода.
Читать полностью »
Рубрика «метапрограммирование» - 4
Обфускация строк на этапе компиляции
2014-12-12 в 14:01, admin, рубрики: c++, C++14, метапрограммирование, обфускацияPipe matching в ЯП Clojure (метапрограммирование в Lisp для начинающих)
2014-11-19 в 16:05, admin, рубрики: clojure, pattern matching, метапрограммирование, функциональное программирование 
Введение
Несколько дней назад я открыл для себя замечательный ЯП Clojure — один из современных диалектов Lisp, особенностью которого является хорошая реализация средств многопоточности, компиляция в байткод jvm, соответственно возможность использования java — библиотек, jit-компиляция и т.д. Про Clojure можно почитать например тут. Но в этой статье речь пойдёт о метапрограммировании. Lisp устроен таким образом, что данные и код в нём — одно и то же. Объявления функций, макросов, вызовы функций, развёртывание макросов — в Lisp это всё просто списки, возможно вложенные друг в друга.
(defn square [foo] (* foo foo))
(defmacro show-it [foo] `(println ~foo))
Такое единство кода и данных предоставляет мощные возможности для метапрограммирования — код который пишет код, который пишет код, который пишет код и т.д. — это самое обычное дело для программирования на Lisp. В compile-time нам полностью доступен весь функционал языка, мы можем вызывать функции, развёртывать макросы, возможно рекурсивно. Например, если мы определим вот такой макрос:
Читать полностью »
Мой велосипед к reflection в c++
2014-11-18 в 16:07, admin, рубрики: c++, c++11, метапрограммирование, ПрограммированиеВдохновившись публикацией «Logger с функциями-членами, которых нет», решил выдать на всеобщее обозрение свой мета-велосипед для рефлекшена, которым вполне успешно пользуюсь, и не только для логгирования. Но начнем всё же с простого логгирования, продолжая вышеупомянутую публикацию.
При реализации логгирования, задачи для себя были поставлены следующие:
- Решить задачу на «мета-уровне», чтобы быть отвязанным от конечной реализации
- Фронтенд апи для логгирования должен быть простым и прозрачным
- Иметь возможность выключать ненужные уровни логгирования на этапе компиляции одной константой; например: все что выше LOG_NOTICE не должно попасть в результирующий бинари
Фронтенд выглядит так:
1. В конструкторе CConnection мы логгируем:
TestLog::Log<LOG_NOTICE>() << *this << "connection created";
2. Где CConnection унаследован от
public TLogHeader<'c', CConnection>
3.Который, используя CRTP, знает, что в CConnection есть такое:
using this_t = CConnection;
int m_id; using m_id_t = TParamAccessor<this_t, decltype(this_t::m_id), &this_t::m_id>;
std::string m_name; using m_name_t = TParamAccessor<this_t, decltype(this_t::m_name), &this_t::m_name>;
char m_state; using m_state_t = TParamAccessor<this_t, decltype(this_t::m_state), &this_t::m_state>;
using log_header_param_list_t = std::tuple<m_id_t, m_name_t, m_state_t>;
3. И превращает эти данные в строчку лога:
c:23:test_conn 1:a:connection created
Где через двоеточие перечислены: с — первый параметр шаблона TLogHeader, и далее значения m_id, m_name, m_state
В моем случае все это дальше пишется в rsyslog и там разбирается в соответствующие поля для MongoDB (в зависимости от типа заголовка, т.е. первый параметр до двоеточия).
Сейчас этот подход у меня в продакшене на высоконагруженной системе, так что любые конструктивные камни будут в пику, или лучше под кат. А если лень, то вот работающий пример на http://coliru.stacked-crooked.com/ т.к. по катом кода на 250 строк, но очень много букв в описании.
Читать полностью »
Pattern matching с помощью макросов
2014-11-03 в 8:49, admin, рубрики: Julia, pattern matching, Компиляторы, макросы, метапрограммирование, функуиональное программирование, функциональное программированиеЯзык Julia не поддерживает такую технику программирования, хорошо зарекомендовавшую себя в языках Haskell, Prolog, Erlang, Scala, Mathematica, как pattern matching. Но разрешает писать макросы, которые позволяют исправить этот фатальный недостаток. Выглядит это примерно так:
julia> immutable X a end
julia> immutable Y a ; b end
julia> @case(Y(X(9),2), Y(4,3)-> 55, Y(X(k),2)->1+k)
10
Исходный код доступен на github.
Похожую (но гораздо более развитую и готовую для использования) можно взять здесь, но она слишком большая, что бы разбирать ее как пример в статье.
Читать полностью »
Инстанциирование шаблонов функций по списку типов (Часть 2)
2014-09-06 в 21:44, admin, рубрики: c++, метапрограммирование, ненормальное программирование В первой части мы обсудили, как добиться переноса определения шаблона фунции из заголовочного файла в исходник, если набор типов, для которых должен быть инстанциирован шаблон известен заранее. В этой части мы посмотрим, как добиться этого красиво.
Читать полностью »
Метаобъектный протокол Common Lisp на примере реализации прототипной объектной системы
2014-07-21 в 20:33, admin, рубрики: common lisp, метапрограммирование, ооп, Программирование, метки: common lispВведение
Common Lisp, а точнее, его объектная система, CLOS, предоставляет пользователю языка совершенно замечательный механизм, а именно, метаобъектный протокол.
К сожалению, очень часто этот компонент языка незаслуженно обходится без должного внимания, и в данной статье я постараюсь это несколько компенсировать.
Вообще, что такое метаобъектный протокол? Очевидно, это слой объектной системы, который, судя по названию, каким-либо образом оперирует над ней самой, и управляет ей.
Для чего он нужен? На самом деле, в зависимости от языка и объектной системы, список применений может быть практически безграничен. Это как добавление коду декларативности(аннотации в Java и аттрибуты в C#), так и разнообразная генерация кода и классов в рантайме(здесь можно вспомнить разнообразные persistance и ORM фреймворки), так и многое другое.
С моей лично точки зрения, лучше всего метаобъектные протоколы себя зарекомендовали со стороны закрепления паттернов проектирования на уровне объектной системы. Такие паттерны, как, скажем, синглтон, которые в языках без достаточно развитого ООП приходится снова и снова реализовывать методом copy-n-paste, в моем любимом Common Lisp создаются буквально из пары десятков строчек кода и переиспользуются в дальнейшем исключительно указанием метакласса[1].
Тем не менее, в нижеследующем тексте я хочу сосредоточиться на кое-чем более интересном, а именно — на изменении правил работы самой объектной системы, самих ее основ. Именно добавление возможностей подобного изменения и было ключевой целью разработчиков метаобъектного протокола для Common Lisp.
Итак, дальнейший текст будет посвящен созданию прототипной объектной системы, подобной JavaScript, в Common Lisp, с использованием метаобъектного протокола и интеграцией ее в CLOS. Полный код проекта доступен на github[2].
Метапрограммирование (с примерами на JavaScript)
2014-07-04 в 14:16, admin, рубрики: javascript, абстракция, анализ, Анализ и проектирование систем, динамическое связывание, замыкания, индивидуация, интерпретация, метаданные, метамодель, метапрограммирование, позднее связывание, примеси, Программирование, проектирование
Эта статья, еще одна попытка переосмысления метапрограммирования, которые я периодически предпринимаю. Идея каждый раз уточняется, но в этот раз удалось подобрать достаточно простых и понятных примеров, которые одновременно очень компактны и иллюстративны, имеют реальное полезное применение и не тянут за собой библиотек и зависимостей. В момент публикации я буду докладывать эту тему на ОдессаJS, поэтому, статью можно использовать, как место для вопросов и комментариев к докладу. Формат статьи дает возможность более полно изложить материал, чем в докладе, слушатели которого, не освобождаются от прочтения.
Популярное понимание метапрограммирования обычно очень размытое, и чаще всего, заканчивается такими вариантами:
- Шаблоны и макросы, используемые при компиляции
- Программа, которая изменяет саму себя
- Программа, генерирующая другую программу
Предлагаю следующее определение:
Метапрограммирование — это парадигма программирования, построенная на программном изменении структуры и поведения программ.
И дальше мы разберем как это работает, зачем это нужно и какие преимущества и недостатки мы получаем в итоге.
SFINAE — это просто
2013-12-13 в 5:51, admin, рубрики: c++, c++11, sfinae, template, метапрограммирование, метки: c++, c++11, sfinae, template, метапрограммированиеTLDR: как определять, есть ли в типе метод с данным именем и сигнатурой, а также узнавать другие свойства типов, не сойдя при этом с ума.

Здравствуйте, коллеги.
Хочу рассказать о SFINAE, интересном и очень полезном (к сожалению*) механизме языка C++, который, однако, может представляться неподготовленному человеку весьма мозгоразрывающим. В действительности принцип его использования достаточно прост и ясен, будучи сформулирован в виде нескольких чётких положений. Эта заметка рассчитана на читателей, обладающих базовыми знаниями о шаблонах в C++ и знакомых, хотя бы шапочно, с C++11.
* Почему к сожалению? Хотя использование SFINAE — интересный и красивый приём, переросший в широко используемую идиому языка, гораздо лучше было бы иметь средства, явно описывающие работу с типами.Читать полностью »
Динамическая интерпретация метамоделей
2012-10-15 в 18:18, admin, рубрики: Анализ и проектирование систем, метамодель, метапрограммирование, моделирование, предметная область, Программирование, Проектирование и рефакторинг, метки: model, метамодель, метапрограммирование, моделирование, предметная область
Продолжая серию статей по метапрограммированию, подготовил выжимку из достаточно объемной своей работы о повышении уровня абстракций в информационных системах. Хабр конечно любит практические решения, и их таки есть у меня, но материала много и я вынужден разделить его на несколько статей. А для иллюстрации эффективности подхода, могу сказать, что внедрение его во множестве живых проектов позволило повысить эффективность разработки в десятки раз, например, создавать приложения баз данных со структурой в несколько сотен таблиц за неделю и портировать решения между платформами за считанные часы. Эта статья носит характер теоретический и наполнена специфической терминологией, без которой, к сожалению, она была бы значительно объемнее.
Читать полностью »
Как я Boost.Any с Boost.MPL дружил
2012-10-10 в 9:57, admin, рубрики: boost, c++, mpl, метапрограммирование, ненормальное программирование, Песочница, метки: boost, c++, mpl, метапрограммирование Недавно мне пришлось работать с кодом, в котором задача передачи параметров произвольных типов решена с использованием стандартных STL контейнеров, параметризованных типом boost::any.
Например:
void foo (std::vector<boost::any>& args) {
// do smth.
}
Предыдущий разработчик был не очень аккуратен и внутри функции работа с содержимым boost::any основывалась на предположении об исходном типе данных, то есть если преобразование boost::any_cast не проходило, то параметр пропускался. В определенных случаях такой способ обработки приемлем и примеры этой методики работы можно посмотреть тут.
Однако, мне хотелось несколько обобщить исходные предположения о типе данных.
Читать полностью »
