Всегда хотел иметь под рукой определённый «джентельменский набор» библиотечных классов, с малой зависимостью, которые можно легко совмещать с другими библиотеками и фреймворками и легко переносить в другие проекты. Как говориться — включил и забыл. И самое главное — «не плати за то, что не используешь» (С) С++
nstd::
Мне нравятся библиотеки состоящие только из заголовочных файлов. Тем более, что грядут модули в C++! :) Сразу оговорюсь, библиотека nstd ни в коем случае не претендует на место великих и могучих библиотек и фреймворков типа boost, Qt, POCO и т.д. и т.п. Скорее, она является дополнением к ним.
Моя библиотека использует возможности C++17 и состоит из нескольких слабо-зависимых друг от друга функциональных классов. Сразу предупрежу, что библиотека активно дополняется и меняется, и, возможно, на момент чтения вами этой статьи она уже изменилась настолько, что за актуальной информацией лучше обратиться к исходным кодам здесь.
Библиотека содержит несколько примеров по использованию классов. Для них, я включил проекты CodeBlocks (для Windows). Однако, примеры также содержат конфигурационный файл GENie для генерации других типов проектов. Например, можно легко сгенерировать Makefile для этих целей. C++17 поддерживается GCC 7.1 и последними версиями Clang. К сожалению, Visual Studio 2017 пока поддерживает не все возможности нового стандарта, в частности не поддерживается inline для data members и упрощённый способ объявления nested namespaces. Поэтому, в принципе, вы можете сгенерировать проект для VS 2017 через GENie, но он пока не скомпилируется. Хотя, если очень нужно, то можете сами подправить исходники для компиляции в VS 2017, там не сложно.
Если у вас нет CodeBlocks или Вы не хотите его устанавливать, тогда, на примере MinGW-w64 GCC 7.1 для Windows, я опишу как быстро сгенерировать и скомпилировать примеры при помощи GENie и Makefile-ов.
- Качаем MinGW-w64 с GCC 7.1, например отсюда. Распаковываем в удобную для вас папку и прописываем в переменную PATH путь к папке MinGW/bin.
- Качаем исполняемый файл GENie для Windows (там же есть и для других ОС) отсюда.
- Копируем genie.exe в папку с примерами, туда, где лежит файл genie.lua.
- Для генерации Makefile-ов, запускаем из папки примеров команду: «genie.exe gmake»
- В папке с примерами появятся главный Makefile и sub-мейкфайлы для каждого проекта.
- Например, чтобы собрать все примеры в Release конфигурации, запускаем там-же: «mingw32-make.exe config=release». Если хотите собрать только один из примеров, тогда просто нужно добавить имя примера, например: «mingw32-make.exe config=release relinx_example».
Библиотека nstd распространяется под лицензией MIT и содержит не только классы моей разработки, но и сторонние наработки. В описании проекта на Github я указываю, какие именно сторонние классы я включил в проект. В репозитории они лежат в отдельной папке external.
Коротко о текущем содержании nstd:
Класс Relinx я уже представлял на Хабрахабре здесь. Попросту говоря, это LINQ для C++. Поддерживаются «ленивые» вычисления и реализованы почти все методы .NET LINQ. Я решил включить Relinx в nstd. Не пропадать же добру :).
signal_slot классы удобны в том плане, что позволяют сигналам и слотам автоматически отключаться друг от друга при разрушении соединения между ними. Каждая связь слота с сигналом любого типа представлена классом connection, при разрушении которого происходит разрыв связки signal-slot. Важно то, что connection, в отличии от сигналов и слотов, не является template-ом, что позволяет сохранять его в любой контейнер, независимо от типов сигнала и слота. Соответственно, при разрушении этого контейнера, все связи с сигналами будут разорваны. Это удобно, когда объект, содержащий данный контейнер, разрушается, при этом не нужно специально отсоединяться от сигналов — это произойдёт автоматически.
live_property построен на базе signal_slot классов. Это обвязка над типами, которая позволяет отслеживать изменения над ними и, при желании, можно управлять поведением: изменять значение или нет.
expiry_cache это template контейнер, который хранит данные только определённое время и оповещает сигналом об истечении срока годности данных. Работает в двух режимах: продлевает жизнь данным, если к ним было обращение в течении времени хранения, и режим без продления жизни данных. Также, есть режим автоматической очистки в фоновом режиме через отдельный поток (auto vacuum).
json — сторонняя библиотека работы с форматом данных JSON.
asio — сторонняя библиотека работы с сетевыми подключениями. Возможно, скоро войдёт в стандарт C++.
urdl — сторонняя библиотека от автора asio, но форкнутая и развиваемая другими разработчиками. Она позволяет удобно загружать данные из сети.
sqlite — это сторонняя обёртка над sqlite3. Очень интересная реализация.
quantum random number provider — это класс-генератор случайных чисел с использованием бесплатного сервиса QRNG (http://qrng.anu.edu.au), который возвращает случайные числа, сгенерированные на квантовом оборудовании.
За примерами использования этих классов (и некоторых других, которые я здесь не упомянул), обращайтесь к репозиторию на Github здесь. Если останутся вопросы или возникнут хорошие предложения — обращайтесь!
Я активно пытаюсь дополнять библиотеку nstd полезными классами. Предлагаю всем желающим принять участие в развитии nstd библиотеки. Если есть хорошие и полезные классы, то присылайте мне. Постараюсь адаптировать и включить в библиотеку.
///TODO:
В ближайших планах хочу реализовать remote signals, работающие через TCP или UDP соединение. Эти сигналы хочу использовать для связи между процессами и связи по сети.
Есть ещё задумка реализовать GUI классы на основе Blend2D или AGG и с использованием своей реализации signals slots. Пока не определился, какую из графических библиотек взять за основу. Буду рад выслушать ваше мнение по этому вопросу.
Поделиться с друзьями
Комментарии (7)
Whiteha
29.06.2017 00:01+1Автор молодец, что-то делает для себя и поделился без лишнего гонора, минусы мне тут не очень понятны.
AndreySu
К сожалению, не нашел для себя ни одного полезного решения в nstd, исключая библиотеки чужих авторов, таких как nlohmann::json.
Думал посмотреть в сторону expiry_cache, но опять же использую более гибкое решение со своим шедулером для разных типов данных и с разным временем истечения, работающем в одном потоке.
arlen_albert
Ну ничего. Может со временем появятся и для Вас интересные решения в nstd.
А можете дать ссылку на более гибкий шедулер?
arlen_albert
Кстати, мой expiry_cache поддерживает разное время хранения для данных. Да и разные типы в одном контейнере можно держать при помощи std::any или std::variant. Хотя, Вам решать, что и как использовать :)
AndreySu
Исходный код этого шедулера не в open source. Но сделан он без any, а variadic templates и метапрограммировании.
arlen_albert
Ну можно использовать и void* и union :)
Как говориться, на вкус и цвет :)
arlen_albert
… и кстати auto vacuum опциональный и его можно не включать. В этом случае, проверка на expiry и удаление данных будет происходить только при доступе к ним. И, как-раз в этом случае, expiry_cache будет работать в один поток :)