coost README

The project's README from github.com/idealvin/coost. As one markdown file: README.md.

coost

简体中文 | English
Linux Mac Windows Windows-arm64 FreeBSD Release License: MIT

A tasteful, minimal C++ base library.

Introduction

coost is a lightweight, high-performance, easy-to-use C++ base library. It supports Linux, macOS, Windows, FreeBSD, and CPU architectures such as x86, x64, ARM, and ARM64.

coost, abbreviated as co, includes go-style coroutines, networking, logging, config parsing, unit testing, benchmarking, memory allocator, and other components. Its goal is to make C++ programming simple and enjoyable.

Commercial Support

coost remains open source. If you use coost in production and need in-depth support such as custom development, architecture adaptation (RISC-V / MIPS), coroutine hooks, performance optimization, or team training, the author offers paid commercial support to reduce risk and save time.

For service packages, pricing, and process, see:

👉 coost Commercial Support

Contact the author via GitHub Issues or email [email protected]. A free initial diagnosis is available to assess scope and feasibility.

Documentation

The documentation currently lags behind the latest version of coost. Please refer to the latest code and the include/co headers for the most accurate information.

Core Components

flag

flag is a command-line argument and config file parsing library. It supports flag aliases, automatic config file generation, and more.

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

DEF_bool(x, false, "Comment here");
DEF_int32(n, 0, "Comment here");
DEF_string(s, "hello world", "Comment here");

int main(int argc, char** argv) {
    flag::parse(argc, argv);
    co::println("x: ", FLG_x);
    co::println("n: ", FLG_n);
    co::println("s: ", FLG_s);
    return 0;
}

Coroutines

coost implements a coroutine mechanism similar to goroutine in Golang. It has the following features:

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

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

    co::wait_group wg(2);

    go([wg](){
        co::println("hello world");
        wg.done();
    });

    go([wg](){
        co::println("hello again");
        wg.done();
    });

    wg.wait();
    return 0;
}

Networking

coost provides a coroutine-based network programming framework:

Logging

log is a high-performance logging component. It supports printing stack traces when the program crashes.

#include "co/log.h"

int main(int argc, char** argv) {
    flag::parse(argc, argv);
    log::info("hello ", 23);   // info
    log::warn("hello ", 23);   // warning
    log::error("hello ", 23);  // error
    log::check(1+1==2, "xx");  // runtime assertion; prints stack trace and exits on failure
    return 0;
}

log is very fast. Here are some test results:

platform glog co/log speedup
win2012 HDD 1.6MB/s 180MB/s 112.5
win10 SSD 3.7MB/s 560MB/s 151.3
mac SSD 17MB/s 450MB/s 26.4
linux SSD 54MB/s 1023MB/s 18.9

The table above shows the write speed comparison between co/log and glog when continuously printing 1 million logs in a single thread. co/log is nearly two orders of magnitude faster than glog.

threads linux co/log linux spdlog win co/log win spdlog speedup
1 0.087235 2.076172 0.117704 0.461156 23.8/3.9
2 0.183160 3.729386 0.158122 0.511769 20.3/3.2
4 0.206712 4.764238 0.316607 0.743227 23.0/2.3
8 0.302088 3.963644 0.406025 1.417387 13.1/3.5

The table above shows the time consumed to print 1 million logs with 1, 2, 4, and 8 threads respectively, in seconds. speedup is the performance improvement factor of co/log over spdlog on Linux and Windows.

Unit Testing

unitest is a simple and easy-to-use unit testing framework. Many components in coost use it to write unit test code, providing important assurance for coost's stability.

#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);
    co::run_unitests();
    return 0;
}

The above is a simple example. The DEF_test macro defines a test unit, which is actually a function. The DEF_case macro defines a test case, and each test case is actually a code block.

The coost/unitest directory contains the unit test code in coost. Run the following commands to build and run:

xmake b unitest
xmake r unitest      # run all unit test cases
xmake r unitest -os  # run only test cases in the os unit; os is the unit test name

Benchmark

benchmark is a simple and easy-to-use performance benchmark framework.

#include "co/benchmark.h"
#include "co/atomic.h"

BM_group(atomic) {
    int i = 0;

    BM_add(atomic_inc) {
        co::atomic_inc(&i);
    }
    BM_use(i);

    BM_add(atomic_dec) {
        co::atomic_dec(&i);
    }
    BM_use(i);
}

The coost/benchmark directory contains some performance test code. Run the following commands to build and run:

xmake b benchmark
xmake r benchmark        # run all benchmark code by default
xmake r benchmark -mem   # run only benchmark code in BM_group(mem)

JSON

JSON adopts a fluent interface design, making it easier to use.

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

// equal to x
json::any 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

Below is the performance comparison between co/json and 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

The table above shows the average time for stringify and parse measured after minifying twitter.json, in microseconds (us). speedup is the performance improvement factor of co/json over rapidjson in stringify and parse.

Code Structure

Build

Compiler Requirements

The latest version of coost requires a compiler that supports C++17:

Build with xmake

coost recommends xmake as the build tool.

Quick Start

# All commands are executed in the coost root directory, and this will not be repeated below
xmake       # build libco by default
xmake -a    # build all projects (libco, benchmark, gen, test, unitest)

Enable backtrace

On Linux and macOS, printing stack traces on crashes requires libbacktrace. Newer versions of gcc on Linux already have a built-in backtrace library; on macOS it usually needs to be installed manually.

xmake f --with_backtrace=true
xmake b stack   # test/stack.cc
xmake r stack   # run stack test program

Install libco

xmake install -o pkg          # package and install to the pkg directory
xmake i -o pkg                # same as above
xmake install -o /usr/local   # install to /usr/local

Build with cmake

Build libco

mkdir cmakebuild && cd cmakebuild
cmake ..
make -j8

Build all projects

mkdir cmakebuild && cd cmakebuild
cmake .. -DBUILD_ALL=ON -DCMAKE_INSTALL_PREFIX=/usr/local
make -j8
cd bin
./unitest  # run unit test program

Enable backtrace

mkdir cmakebuild && cd cmakebuild
cmake .. -DWITH_BACKTRACE=ON
make -j8

License

The MIT license. coost includes code from some other projects, which may use different licenses. See LICENSE.md for details.

Special Thanks

coost (idealvin/coost)

Searching Database…

4.2K ·GitHub
What is this?coost (aka co) is a lightweight, high-performance, easy-to-use C++ base library whose stated goal is to make C++ programming simple and enjoyable.
What's inside the library?It is a base library (it builds into libco), not an app: it bundles go-style coroutines, networking, logging, config parsing, unit testing, benchmarking, a memory allocator and a JSON component.
How do I build it, and what compiler do I need?You need a compiler with C++17 support (gcc, clang or MSVC). The author recommends building with xmake; a cmake path is provided too, and the result installs as libco.
Is the documentation any good?Not fully — the docs currently lag behind the latest version, so the code and the include/co headers are the most accurate reference.
Does it work on Linux, macOS and Windows?Yes — it supports Linux, macOS, Windows and FreeBSD, on x86, x64, ARM and ARM64 CPUs.
Can I use it in commercial projects?Yes, it is under the MIT license, but coost includes code from other projects that may use different licenses, so check LICENSE.md. The author also sells optional paid commercial support.
How does its unit testing framework work?The unitest component uses macros: DEFtest defines a test unit, which is really a function, and DEFcase defines a test case, which is a code block. Coost uses it to test its own components, and there is a separate benchmark framework built the same way.
Why did the author build it?The stated goal is to make C++ programming simple and enjoyable — one tasteful, minimal base library that packs coroutines, networking, logging, JSON and testing tools into a single dependency.
What are similar projects?mars, zenc, spdlog, muduo, fasthttp, mimalloc, capnproto, conc
Creator
idealvin
Size
3.7 MB
Stars
4.2K
Age
6y
Commits · 90 Days