Giter Club home page Giter Club logo

programming-with-cpp20's Introduction

Companion Source Code for "Programming with C++20 - Concepts, Coroutines, Ranges, and more" 2. Edition

Build Status License

Book cover

Code examples

This repository contains runnable source code examples from the 2. edition of Programming with C++20 - Concepts, Coroutines, Ranges, and more, by Andreas Fertig.

The layout of the examples

The examples are separated into different directories based on how they appear in the book.

Running the examples

The examples are in a single .cpp file that can be easily executed in any IDE. There is also an CMakeLists.txt which can generate IDE projects or be used to compile the example in a terminal. This repo contains a top-level CMakeLists.txt, which does build all the examples.

Building the examples

You can select the compiler by setting the CXX environment variable.

mkdir programming-with-cpp20
cd programming-with-cpp20
git clone https://github.com/andreasfertig/programming-with-cpp20
mkdir build
cd build
cmake ../
cmake --build . -j

After that, you find all the executables in programming-with-cpp20/build/bin.

Some examples use the latest C++ standard, so you will need a modern compiler to compile them. The latest stable versions of GCC or Clang are recommended. The code is not tested but is also expected to work with MSVC.

License

The source code is released under the MIT License.

programming-with-cpp20's People

Contributors

andreasfertig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

programming-with-cpp20's Issues

Coroutine set

Thanks for the coroutine set.

The evolution of samples from the first one(02.10) to the result is awesome and produces the expected results.
However, what if one would use it from the perspective to write something more generic:

For example the data for "sending coroutine" could be just:

    std::vector<byte> fakeBytes {
        'H'_B, 'e'_B, 'l'_B, 'l'_B, 'o'_B
    };

and the code in "parsing coroutine" is co-awaiting and just co-yielding (echoing):

    while (true) {
        byte b = co_await byte{};
        std::string frame{};
        frame.push_back(static_cast<char>(b));
        co_yield frame;
    }

And in this sense the modified (02.10) keeps working as expected, but already the next one doesn't (is crashed).
Of course, things were done with an eye to a specific version of the protocol, the outcomes in common seem not functionally equivalent. And I thought that the issues could be interesting.

cppcon2022 specch code example errors

hi, @andreasfertig , thanks for the talk about coroutine in cppcon2022, I profited greatly from your speech. but i find your example given have some running problem when i try to run it, could you pls explain it for me where i did wrong, code are here

#include <coroutine>
#include <list>
#include <iostream>

class Scheduler {
public:
    std::list<std::coroutine_handle<>> m_tasks{};

    bool schedule()
    {
        auto task = m_tasks.front();
        m_tasks.pop_front();

        if (not task.done()) {
            task.resume();
        }
        return not m_tasks.empty();
    }

    auto suspend()
    {
        struct awaiter : std::suspend_always {
            Scheduler &scheduler;

            explicit awaiter(Scheduler s) : scheduler(s)
            {}

            void await_suspend(std::coroutine_handle<> coro) const noexcept
            {
                scheduler.m_tasks.push_back(coro);
            }
        };
        return awaiter{*this};
    }

};

struct Task {
    struct promise_type {
        Task get_return_object()
        {
            return {};
        }

        std::suspend_never initial_suspend() noexcept
        { return {}; }

        std::suspend_never final_suspend() noexcept
        { return {}; }

        void unhandled_exception()
        {}
    };
};


Task taskA(Scheduler &scheduler)
{
    std::cout << "hello, from A" << std::endl;

    co_await scheduler.suspend();

    std::cout << "A is back to work" << std::endl;

    co_await scheduler.suspend();

    std::cout << "A is doing last work" << std::endl;
}

Task taskB(Scheduler &scheduler)
{
    std::cout << "hello, from B" << std::endl;

    co_await scheduler.suspend();

    std::cout << "B is back to work" << std::endl;

    co_await scheduler.suspend();

    std::cout << "B is doing last work" << std::endl;
}

void Use()
{

    Scheduler scheduler{};

    taskA(scheduler);
    taskB(scheduler);

    while (scheduler.schedule()) {}
}

int main()
{
    Use();
    return 0;
}

and my environment are following

➜  ~ uname -a
Darwin HelianthusdeMacBook-Pro.local 21.4.0 Darwin Kernel Version 21.4.0: Fri Mar 18 00:46:32 PDT 2022; root:xnu-8020.101.4~15/RELEASE_ARM64_T6000 arm64
➜  ~ /opt/homebrew/bin/g++-12 -v
Using built-in specs.
COLLECT_GCC=/opt/homebrew/bin/g++-12
COLLECT_LTO_WRAPPER=/opt/homebrew/Cellar/gcc@12/12.1.0_1/bin/../libexec/gcc/aarch64-apple-darwin21/12/lto-wrapper
Target: aarch64-apple-darwin21
Configured with: ../configure --prefix=/opt/homebrew/opt/gcc@12 --libdir=/opt/homebrew/opt/gcc@12/lib/gcc/12 --disable-nls --enable-checking=release --with-gcc-major-version-only --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-12 --with-gmp=/opt/homebrew/opt/gmp --with-mpfr=/opt/homebrew/opt/mpfr --with-mpc=/opt/homebrew/opt/libmpc --with-isl=/opt/homebrew/opt/isl --with-zstd=/opt/homebrew/opt/zstd --with-pkgversion='Homebrew GCC 12.1.0_1' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --with-system-zlib --build=aarch64-apple-darwin21 --with-native-system-header-dir=/usr/include --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.1.0 (Homebrew GCC 12.1.0_1)

and i got errors like:

hello, from A
hello, from B
module(19290,0x102e20580) malloc: *** error for object 0x16d4172b8: pointer being freed was not allocated
module(19290,0x102e20580) malloc: *** set a breakpoint in malloc_error_break to debug

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)

02.25-coroutineParsingDataStreamCustomAllocator1 compile error with Ubuntu-GCC 12.1

The error message is hard to understand.
It seems like type-cast related.
main.cpp:284:1: error: ‘static void promise_type_base<T, G, InitialSuspend>::operator delete(void*, size_t) [with T = std::__cxx11::basic_string<char>; G = generator<std::__cxx11::basic_string<char>, false>; bool InitialSuspend = false]’ called on pointer returned from a mismatched allocation function [-Werror=mismatched-new-delete] 284 | } | ^ 02.25-coroutineParsingDataStreamCustomAllocator1/main.cpp:284:1: note: returned from ‘static void* promise_type_base<T, G, InitialSuspend>::operator new(size_t, arena&, TheRest&& ...) [with TheRest = {DataStreamReader&}; T = std::__cxx11::basic_string<char>; G = generator<std::__cxx11::basic_string<char>, false>; bool InitialSuspend = false]’ /home/wps/cpp20/coro-study/02.25-coroutineParsingDataStreamCustomAllocator1/main.cpp: In function ‘generator<std::byte> sender(arena&, std::vector<std::byte>)’: 02.25-coroutineParsingDataStreamCustomAllocator1/main.cpp:292:1: error: ‘static void promise_type_base<T, G, InitialSuspend>::operator delete(void*, size_t) [with T = std::byte; G = generator<std::byte>; bool InitialSuspend = true]’ called on pointer returned from a mismatched allocation function [-Werror=mismatched-new-delete] 292 | } | ^ 02.25-coroutineParsingDataStreamCustomAllocator1/main.cpp:292:1: note: returned from ‘static void* promise_type_base<T, G, InitialSuspend>::operator new(size_t, arena&, TheRest&& ...) [with TheRest = {std::vector<std::byte, std::allocator<std::byte> >&}; T = std::byte; G = generator<std::byte>; bool InitialSuspend = true]’ cc1plus: all warnings being treated as errors

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.