[Из песочницы] Еще один Linq для С++
Введение После продолжительного перерыва мне пришлось вернуться к программированию на C++. После C# очень не хватало ключевого слова var и возможностей построения запросов linq. Однако как оказалось прогресс не стоит на месте и за время моего отсутствия вышла новая версия С++11, имеющая новые интересные возможности, к тому же реализованная в большинстве компиляторов. Я занимался кросс-платформенным проектом и меня интересовали компиляторы GCC для Linux, Visual Studio и mingw для мира Windows. Попытка найти linq-like библиотеку не увенчались успехом, все, что я находил, было нежизнеспособной поделкой на коленке. Смирившись, я бросил поиски, однако в апреле 2012 вышла обнадеживающая статья LINQ to Objects на языке C++, в которой описывалась библиотека, которая мне подходила. Попробовав ее в деле и разобравшись в ее устройстве, я был разочарован неэффективностью, но некоторые идеи я подчерпнул. Оставалось одно — написать такую же, только с блэк-джеком, что я и сделал github.com/drbasic/CppLinq, заодно разобравшись автоматическим выводом типа (auto) и лямбда выражениями. Проектировалась библиотека так, что бы с помощью fluent — синтаксиса и лямбда выражений пользователь мог построить граф преобразований. Эти графы можно копировать, достраивать, объединять, т.е. реализовать поведение максимально близкое к прообразу Linq to Objects из мира C#. Функционал библиотеки, недолго думая, я позаимствовал из C#, добавив, явный left join и full join. Важным ограничением библиотеки является перемещение по графу преобразования не копий, а указателей на элементы исходной последовательности. Это позволяет эффективно обходиться со сложными элементами коллекций, ведь теперь не происходит накладных расходов на копирование, но исходная последовательность из-за этого не должна быть «виртуальной». Т.е. к началу работы у каждого элемента исходной последовательности должен быть уникальный адрес и элементы не должны перемещаться в памяти во время работы linq-преобразований. В общем, для этого подходят массивы, контейнеры Qt, все стандартные контейнеры, кроме std: bitset. Сложности возникли лишь с константными последовательностями, которые так и не доделал, так как мне они были не особо нужны. Библиотека проверена и успешно компилируется Visual Studio 2010 и 2012, gcc 4.8, mingw 4.8. Проще всего совладать оказалось с компилятором Microsoft, сделать счастливыми gcc было куда сложнее, причем с внутренней ошибкой бывало падали все компиляторы, порой даже без вразумительных криков. Читать дальше →