1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/idealvin-coost

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
readme_cn.md 17 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 27.11.2024 18:23 9bf4b61

coost: крошечная библиотека для ускорения разработки на C++11

coost — это кроссплатформенная базовая библиотека C++, которая сочетает в себе производительность и удобство использования. Её цель — создать инструмент для разработчиков на C++, который сделает программирование простым, лёгким и приятным.

coost также называют co, его иногда сравнивают с boost. В отличие от boost, coost небольшой и компактный, статическая библиотека, скомпилированная для Linux и Mac, имеет размер около 1 Мбайт. Однако она содержит множество мощных функций:

  • разбор командной строки и конфигурационных файлов (flag);
  • высокопроизводительная библиотека журналов (log);
  • фреймворк для модульного тестирования;
  • фреймворк для сравнительного тестирования;
  • go-style сопрограммы;
  • сетевая структура программирования на основе сопрограмм;
  • RPC-фреймворк на основе JSON;
  • атомарные операции (atomic);
  • высокоэффективный поток символов (fastream);
  • эффективные строки (fastring);
  • строковые операции (str);
  • библиотека времени (time);
  • потоковая библиотека (thread);
  • планировщик задач по расписанию;
  • эзотерическое программирование;
  • эффективная библиотека JSON;
  • хеш-библиотека;
  • библиотека путей (path);
  • файловые операции (fs);
  • системные операции (os);
  • эффективный распределитель памяти;

1. Поддержка

Развитие coost было бы невозможно без вашей поддержки. Если вы используете или вам нравится coost, рассмотрите возможность поддержать этот проект. Мы будем очень благодарны.

2. Документация

3. Основные компоненты

3.0 Эзотерическое программирование

co/god.h предоставляет некоторые функции, связанные с шаблонами. Некоторые программисты на C++ называют это эзотерическим программированием.

#include "co/god.h"

void f() {
    god::bless_no_bugs();
    god::is_same<T, int, bool>(); // T is int or bool?
}

3.1 flag

flag — это библиотека для разбора командной строки и параметров конфигурации, аналогичная gflags, но более мощная:

  • поддерживает передачу параметров из командной строки и файла конфигурации;
  • автоматически генерирует файлы конфигурации;
  • поддерживает псевдонимы флагов;
  • целые числа во флагах могут иметь единицы измерения k, m, g, t, p, независимо от регистра.
// xx.cc
#include "co/flag.h"
#include "co/cout.h"

DEF_bool(x, false, "x");
DEF_bool(y, true, "y");
DEF_bool(debug, false, "dbg", d);
DEF_uint32(u, 0, "xxx");
DEF_string(s, "", "xx");

int main(int argc, char** argv) {
    flag::parse(argc, argv);
    cout << "x: " << FLG_x << '\n';
    cout << "y: " << FLG_y << '\n';
    cout << "debug: " << FLG_debug << '\n';
    cout << "u: " << FLG_u << '\n';
    cout << FLG_s << "|" << FLG_s.size() << '\n';
    return 0;
}

В приведённом выше коде макросы DEF_ определяют 4 флага, каждый из которых соответствует глобальной переменной, имя которой начинается с FLG_. Флаг debug также имеет псевдоним d. После компиляции этого кода его можно запустить следующим образом:

./xx                  # 按默认配置运行
./xx -x -s good       # x -> true, s -> "good"
./xx -debug           # debug -> true
./xx -xd              # x -> true, debug -> true
./xx -u 8k            # u -> 8192, 整数可带单位(k,m,g,t,p), 不分大小写

./xx -mkconf          # 自动生成配置文件 xx.conf
./xx xx.conf          # 从配置文件传入参数
./xx -conf xx.conf    # 与上同

3.2 log

log — это высокопроизводительный компонент журнала, используемый некоторыми компонентами coost для вывода журналов.

log поддерживает два типа журналов: один — уровень журнала, разделенный на debug, info, warning, error и fatal, пять уровней, вывод журнала уровня fatal приведёт к завершению работы программы; другой — журнал тем, журналы классифицируются по темам и записываются в разные файлы.

#include "co/log.h"

int main(int argc, char** argv) {
    flag::parse(argc, argv);

    TLOG("xx") << "s" << 23; // topic log
    DLOG << "hello " << 23;  // debug
    LOG << "hello " << 23;   // info
    WLOG << "hello " << 23;  // warning
    ELOG << "hello " << 23;  // error
    FLOG << "hello " << 23;  // fatal

    return 0;
}

log также предоставляет ряд макросов CHECK, которые можно рассматривать как усиленную версию assert, они не будут удалены в режиме отладки. При сбое утверждения CHECK log будет выводить информацию о стеке вызовов функций, а затем завершать работу программы. ### 3.3 unitest

Unitest — это простой в использовании фреймворк для модульного тестирования, который обеспечивает важную гарантию стабильности coost.

#include "co/unitest.h"
#include "co/os.h"

DEF_test(os) {
    DEF_case(homedir) {
        EXPECT_NE(os::homedir(), "");
    }

    DEF_case(cpunum) {
        EXPECT_GT(os::cpunum(), 0);
    }
}

int main(int argc, char** argv) {
    flag::parse(argc, argv);
    unitest::run_tests();
    return 0;
}

Приведённый выше пример представляет собой простой случай использования Unitest. DEF_test — это макрос, определяющий тестовый модуль, который фактически является функцией (методом класса). DEF_case — это макрос, который определяет тестовый пример, и каждый тестовый пример фактически представляет собой блок кода.

Каталог unitest в репозитории coost содержит код модульных тестов для coost, которые можно скомпилировать и запустить с помощью следующих команд:

xmake r unitest      # Запустить все тестовые примеры
xmake r unitest -os  # Запустить только тестовые случаи в os

3.4 JSON

В версии coost 3.0 JSON использует плавный интерфейс, что делает его более удобным в использовании.

// {"a":23,"b":false,"s":"123","v":[1,2,3],"o":{"xx":0}}
co::Json x = {
    { "a", 23 },
    { "b", false },
    { "s", "123" },
    { "v", {1,2,3} },
    { "o", {
        {"xx", 0}
    }},
};

// equal to x
co::Json y = Json()
    .add_member("a", 23)
    .add_member("b", false)
    .add_member("s", "123")
    .add_member("v", Json().push_back(1).push_back(2).push_back(3))
    .add_member("o", Json().add_member("xx", 0));

x.get("a").as_int();       // 23
x.get("s").as_string();    // "123"
x.get("s").as_int();       // 123, string -> int
x.get("v", 0).as_int();    // 1
x.get("v", 2).as_int();    // 3
x.get("o", "xx").as_int(); // 0

x["a"] == 23;          // true
x["s"] == "123";       // true
x.get("o", "xx") != 0; // false

Ниже приводится сравнение производительности co/json и rapidjson:

os co/json stringify co/json parse rapidjson stringify rapidjson parse speedup
win 569 924 2089 2495 3.6/2.7
mac 783 1097 1289 1658 1.6/1.5
linux 468 764 1359 1070 2.9/1.4

Таблица выше показывает среднее время, затраченное на stringify и parse для twitter.json, после минимизации. Единица измерения — микросекунды (us), а speedup — это коэффициент повышения производительности co/json по сравнению с rapidjson в аспектах stringify и parse. TCP, HTTP и RPC — это высокоуровневые компоненты для сетевого программирования, совместимые с IPv6 и одновременно поддерживающие SSL. Они более удобны в использовании по сравнению с socket API.

RPC server

#include "co/co.h"
#include "co/rpc.h"
#include "co/time.h"

int main(int argc, char** argv) {
    flag::parse(argc, argv);

    rpc::Server()
        .add_service(new xx::HelloWorldImpl)
        .start("127.0.0.1", 7788, "/xx");

    for (;;) sleep::sec(80000);
    return 0;
}

RPC-сервер также поддерживает протокол HTTP, и его можно вызвать с помощью метода POST:

curl http://127.0.0.1:7788/xx --request POST --data '{"api":"ping"}'

Статический веб-сервер

#include "co/flag.h"
#include "co/http.h"

DEF_string(d, ".", "root dir"); // docroot for the web server

int main(int argc, char** argv) {
    flag::parse(argc, argv);
    so::easy(FLG_d.c_str()); // mum never have to worry again
    return 0;
}

HTTP-сервер

void cb(const http::Req& req, http::Res& res) {
    if (req.is_method_get()) {
        if (req.url() == "/hello") {
            res.set_status(200);
            res.set_body("hello world");
        } else {
            res.set_status(404);
        }
    } else {
        res.set_status(405); // method not allowed
    }
}

// http
http::Server().on_req(cb).start("0.0.0.0", 80);

// https
http::Server().on_req(cb).start(
    "0.0.0.0", 443, "privkey.pem", "certificate.pem"
);

HTTP-клиент

void f() {
    http::Client c("https://github.com");

    c.get("/");
    LOG << "response code: "<< c.status();
    LOG << "body size: "<< c.body().size();
    LOG << "Content-Length: "<< c.header("Content-Length");
    LOG << c.header();

    c.post("/hello", "data xxx");
    LOG << "response code: "<< c.status();
}

go(f);

4. Структура кода

  • include — папка с заголовочными файлами coost.
  • src — исходные файлы coost, которые компилируются в библиотеку libco.
  • test — тестовый код, каждый файл .cc компилируется в отдельный тестовый исполняемый файл.
  • unitest — код модульного тестирования, каждый файл .cc соответствует отдельному модулю тестирования, все коды компилируются в один исполняемый файл тестирования.
  • gen — инструменты генерации кода.

5. Сборка

5.1 Требования к компилятору

Для компиляции coost требуется поддержка C++11 компилятором:

  • Linux: gcc 4.8+.
  • Mac: clang 3.3+.
  • Windows: vs2015+.

5.2 Сборка с использованием xmake

Рекомендуется использовать xmake в качестве инструмента сборки для coost.

5.2.1 Быстрый старт

Все команды выполняются в корневом каталоге coost: xmake — сборка библиотеки libco по умолчанию. xmake -a — сборка всех проектов (libco, gen, test, unitest).

5.2.2 Создание динамической библиотеки

xmake f -k shared
xmake -v

5.2.3 Сборка на основе mingw

xmake f -p mingw
xmake -v

5.2.4 Включение поддержки HTTP/SSL

xmake f --with_libcurl=true --with_openssl=true
xmake -v

5.2.5 Установка libco

xmake install -o pkg — установка в каталог pkg.
xmake i -o pkg — то же самое.
xmake install -o /usr/local — установка в /usr/local.

5.2.6 Установка из xrepo

xrepo install -f "openssl=true,libcurl=true" coost

5.3 Использование cmake

Извлеките выгоду из поддержки cmake, предоставленной izhengfan и SpaceIm.

5.3.1 Сборка libco

Создайте каталог build и перейдите в него: mkdir build && cd build cmake .. make -j8

5.3.2 Сборка всех проектов

Создайте каталог build и перейдите в него: mkdir build && cd build cmake .. -DBUILD_ALL=ON -DCMAKE_INSTALL_PREFIX=/usr/local make -j8 make install

5.3.3 Включение поддержки HTTP/SSL

Создайте каталог build и перейдите в него: mkdir build && cd build cmake .. -DWITH_LIBCURL=ON -DWITH_OPENSSL=ON make -j8

5.3.4 Создание динамической библиотеки

Создайте каталог build и перейдите в него: cmake .. -DBUILD_SHARED_LIBS=ON make -j8

5.3.5 Поиск coost в cmake

В файле cmake: find_package(coost REQUIRED CONFIG) target_link_libraries(userTarget coost::co)

5.3.6 vcpkg & conan

vcpkg install coost:x64-windows

# Включение HTTP & SSL
vcpkg install coost[libcurl,openssl]:x64-windows

conan install coost
``` ## 7. Особая благодарность

- Соответствующий код в [context](https://github.com/idealvin/coost/tree/master/src/co/context) взят из [tbox](https://github.com/tboox/tbox) от [ruki](https://github.com/waruqi), особая благодарность!
- [Leedehai](https://github.com/Leedehai) и [daidai21](https://github.com/daidai21) на ранних этапах помогли перевести китайскую справочную документацию coost на английский язык, особая благодарность!
- [ruki](https://github.com/waruqi) помог улучшить скрипт сборки xmake, особая благодарность!
- [izhengfan](https://github.com/izhengfan) предоставил скрипт сборки cmake, особая благодарность!
- [SpaceIm](https://github.com/SpaceIm) доработал скрипт сборки cmake и обеспечил поддержку `find_package`, особая благодарность!

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/idealvin-coost.git
git@api.gitlife.ru:oschina-mirror/idealvin-coost.git
oschina-mirror
idealvin-coost
idealvin-coost
master