nstd — C++ библиотека — «джентельменский набор» полезных классов


    Всегда хотел иметь под рукой определённый «джентельменский набор» библиотечных классов, с малой зависимостью, которые можно легко совмещать с другими библиотеками и фреймворками и легко переносить в другие проекты. Как говориться — включил и забыл. И самое главное — «не плати за то, что не используешь» (С) С++



    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-ов.

    1. Качаем MinGW-w64 с GCC 7.1, например отсюда. Распаковываем в удобную для вас папку и прописываем в переменную PATH путь к папке MinGW/bin.
    2. Качаем исполняемый файл GENie для Windows (там же есть и для других ОС) отсюда.
    3. Копируем genie.exe в папку с примерами, туда, где лежит файл genie.lua.
    4. Для генерации Makefile-ов, запускаем из папки примеров команду: «genie.exe gmake»
    5. В папке с примерами появятся главный Makefile и sub-мейкфайлы для каждого проекта.
    6. Например, чтобы собрать все примеры в 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

      +1
      К сожалению, не нашел для себя ни одного полезного решения в nstd, исключая библиотеки чужих авторов, таких как nlohmann::json.
      Думал посмотреть в сторону expiry_cache, но опять же использую более гибкое решение со своим шедулером для разных типов данных и с разным временем истечения, работающем в одном потоке.
        0

        Ну ничего. Может со временем появятся и для Вас интересные решения в nstd.
        А можете дать ссылку на более гибкий шедулер?

          0

          Кстати, мой expiry_cache поддерживает разное время хранения для данных. Да и разные типы в одном контейнере можно держать при помощи std::any или std::variant. Хотя, Вам решать, что и как использовать :)

            0
            Исходный код этого шедулера не в open source. Но сделан он без any, а variadic templates и метапрограммировании.
              0

              Ну можно использовать и void* и union :)
              Как говориться, на вкус и цвет :)

            0

            … и кстати auto vacuum опциональный и его можно не включать. В этом случае, проверка на expiry и удаление данных будет происходить только при доступе к ним. И, как-раз в этом случае, expiry_cache будет работать в один поток :)

            +1
            Автор молодец, что-то делает для себя и поделился без лишнего гонора, минусы мне тут не очень понятны.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое