coost: крошечная библиотека для ускорения разработки на C++11
coost — это кроссплатформенная базовая библиотека C++, которая сочетает в себе производительность и удобство использования. Её цель — создать инструмент для разработчиков на C++, который сделает программирование простым, лёгким и приятным.
coost также называют co, его иногда сравнивают с boost. В отличие от boost, coost небольшой и компактный, статическая библиотека, скомпилированная для Linux и Mac, имеет размер около 1 Мбайт. Однако она содержит множество мощных функций:
Развитие coost было бы невозможно без вашей поддержки. Если вы используете или вам нравится coost, рассмотрите возможность поддержать этот проект. Мы будем очень благодарны.
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?
}
flag — это библиотека для разбора командной строки и параметров конфигурации, аналогичная gflags, но более мощная:
// 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 # 与上同
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
В версии 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);
Для компиляции coost требуется поддержка C++11 компилятором:
Рекомендуется использовать xmake в качестве инструмента сборки для coost.
Все команды выполняются в корневом каталоге coost: xmake — сборка библиотеки libco по умолчанию. xmake -a — сборка всех проектов (libco, gen, test, unitest).
xmake f -k shared
xmake -v
xmake f -p mingw
xmake -v
xmake f --with_libcurl=true --with_openssl=true
xmake -v
xmake install -o pkg — установка в каталог pkg.
xmake i -o pkg — то же самое.
xmake install -o /usr/local — установка в /usr/local.
xrepo install -f "openssl=true,libcurl=true" coost
Извлеките выгоду из поддержки cmake, предоставленной izhengfan и SpaceIm.
Создайте каталог build и перейдите в него: mkdir build && cd build cmake .. make -j8
Создайте каталог build и перейдите в него: mkdir build && cd build cmake .. -DBUILD_ALL=ON -DCMAKE_INSTALL_PREFIX=/usr/local make -j8 make install
Создайте каталог build и перейдите в него: mkdir build && cd build cmake .. -DWITH_LIBCURL=ON -DWITH_OPENSSL=ON make -j8
Создайте каталог build и перейдите в него: cmake .. -DBUILD_SHARED_LIBS=ON make -j8
В файле cmake: find_package(coost REQUIRED CONFIG) target_link_libraries(userTarget coost::co)
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 )