News

On Writing Loops in PPL and Continuation-passing Style, Part 2 -- Raymond Chen

RaymondChen_5in-150x150.jpgIn our previous discussion, we explored a task-based while loop employing custom callables that passed copies of themselves to the next iteration, which follows the continuation-passing style used in the Parallel Patterns Library (PPL). In this session, we will implement the same function using a more traditional recursive approach, aiming to simplify the sharing of state between lambda callables in PPL-style programming.

On Writing Loops in PPL and Continuation-passing Style, Part 2

By Raymond Chen

From the article:

Last time, we came up with task-based while loop that involved creating a custom callable that passed copies of itself to the next iteration.

This time, we’ll implement the function in terms of a more traditional recursion.

template<typename Callable>
task<void> do_while_task(
    std::shared_ptr<Callable> const& f)
{
    return (*f)().then([f](bool loop) {
        return loop ? do_while_task(f) :
                      task_from_result();
    });
}

template<typename Callable, typename =
    std::enable_if_t<std::is_invocable_v<Callable>>>
task<void> do_while_task(Callable&& callable)
{
    using Decayed = std::decay_t<Callable>;
    return do_while_task(
        std::make_shared<Decayed>(
            std::forward<Callable>(callable)));
}

The real work happens in the first overload, which takes a ready-made shared_ptr. The second overload is a convenience method that lets you pass a callable, and it will wrap it in a shared_ptr for you.

Meeting C++ 2023 is streaming all tracks from Berlin

Meeting C++ 2023 will stream all keynotes and talks from Berlin to the online world. After the conference all livestreams will be available in the online platform to all attendees.

Streaming all talks from Berlin

by Jens Weller

From the article:

Quickly announcing that you can see all the talks at Meeting C++ 2023!

You still have this and next week to get your tickets for Meeting C++ 2023, which enables you to either see the talks live in Berlin or watch online! This has been an important goal for this year: make all tracks available to the online conference once we return to be onsite again. Last year has shown that the online conference adds great value to the C++ community in giving folks access to talk that other wise would be only seen by a small group in Berlin.

On Writing Loops in PPL and Continuation-passing Style, Part 1 -- Raymond Chen

RaymondChen_5in-150x150.jpgThe Parallel Patterns Library (PPL) relies on a continuation-passing style for asynchronous programming, where tasks are invoked and then linked to callable objects that process their results. This approach was the primary method for handling asynchronous operations before the introduction of await and co_await keywords in C#, JavaScript, and C++, making it essential to understand for developers working with older code or scenarios that still employ this style.

On Writing Loops in PPL and Continuation-passing Style, Part 1

By Raymond Chen

From the article:

The Parallel Patterns Library (PPL) is based on a continuation-passing style, where you invoke a task, and then attach a callable object that will be given the result. Prior to the introduction of the await and co_await keywords to C#, JavaScript, and C++, this was your only real choice for asynchronous programming.

Sequential calculations are fairly straightforward in continuation-passing style because you just pass the next step as the continuation.

// Synchronous version
auto widget = find_widget(name);
auto success = widget.toggle();
if (!success) report_failure();

// Asynchronous version
find_widget(name).then([=](auto widget) {
    return widget.toggle();
}).then([=](auto success) {
    if (!success) report_failure();
});

Iteration is harder to convert to continuation-passing style because you need to restart the task chain, which means you have recursion.

2023-10 Mailing Available

The 2023-10 mailing of new standards papers is now available.

 

WG21 Number Title Author Document Date Mailing Date Previous Version Subgroup
N4961 2024-03 Tokyo meeting information JF Bastien 2023-10-02 2023-10   All of WG21
N4962 WG21 agenda: 6-11 November 2023, Kona, HI John Spicer 2023-10-07 2023-10   All of WG21
N4963 2023 WG21 admin telecon meetings, rev. 2 Herb Sutter 2023-09-30 2023-10   All of WG21
N4964 Working Draft, Programming Languages -- C++ Thomas Köppe 2023-10-14 2023-10   All of WG21
N4965 Editors' Report, Programming Languages -- C++ Thomas Köppe 2023-10-14 2023-10   All of WG21
P0447R23 Introduction of std::hive to the standard library Matt Bentley 2023-10-14 2023-10 P0447R22 SG14 Low Latency,LEWG Library Evolution,All of WG21
P0876R14 fiber_context - fibers without scheduler Oliver Kowalke 2023-10-13 2023-10 P0876R13 LWG Library
P0952R1 A new specification for std::generate_canonical Thomas Koeppe 2023-09-20 2023-10 P0952R0 LWG Library
P1144R9 std::is_trivially_relocatable Arthur O'Dwyer 2023-10-12 2023-10 P1144R8 EWG Evolution,LEWG Library Evolution
P1729R3 Text Parsing Elias Kosunen 2023-10-12 2023-10 P1729R2 SG9 Ranges,SG16 Unicode,LEWG Library Evolution
P1928R7 std::simd - Merge data-parallel types from the Parallelism TS 2 Matthias Kretz 2023-10-15 2023-10 P1928R6 LEWG Library Evolution,LWG Library
P2019R4 Thread attributes Corentin Jabot 2023-10-15 2023-10 P2019R3 LEWG Library Evolution
P2075R3 Philox as an extension of the C++ RNG engines Ilya Burylov 2023-10-13 2023-10 P2075R2 LEWG Library Evolution
P2267R0 Library Evolution Policies Inbal Levi 2023-10-15 2023-10   LEWG Library Evolution
P2447R5 std::span over an initializer list Arthur O'Dwyer 2023-10-11 2023-10 P2447R4 LWG Library
P2500R2 C++ parallel algorithms and P2300 Ruslan Arutyunyan 2023-10-15 2023-10 P2500R1 SG1 Concurrency and Parallelism,LEWG Library Evolution
P2542R6 views::concat Hui Xie 2023-10-01 2023-10 P2542R5 SG9 Ranges,LEWG Library Evolution,LWG Library
P2642R4 Padded mdspan layouts Christian Trott 2023-10-15 2023-10 P2642R3 LEWG Library Evolution
P2663R4 Proposal to support interleaved complex values in std::simd Daniel Towner 2023-10-13 2023-10 P2663R3 LEWG Library Evolution
P2664R4 Proposal to extend std::simd with permutation API Daniel Towner 2023-10-13 2023-10 P2664R3 SG1 Concurrency and Parallelism,LEWG Library Evolution
P2717R3 Tool Introspection René Ferdinand Rivera Morell 2023-10-14 2023-10 P2717R2 SG15 Tooling
P2762R2 Sender/Receiver Interface For Networking Dietmar Kuhl 2023-10-12 2023-10 P2762R1 SG4 Networking,LEWG Library Evolution
P2774R1 Concurrent object pool (was: Scoped thread-local storage) Michael Florian Hava 2023-09-30 2023-10 P2774R0 SG1 Concurrency and Parallelism
P2786R3 Trivial Relocatability For C++26 Mungo Gill 2023-10-14 2023-10 P2786R2 EWG Evolution,LEWG Library Evolution
P2800R0 Dependency flag soup needs some fiber Ben Boeckel 2023-09-20 2023-10   SG15 Tooling
P2809R2 Trivial infinite loops are not Undefined Behavior JF Bastien 2023-10-14 2023-10 P2809R1 SG1 Concurrency and Parallelism,SG22 Compatability,EWG Evolution,LEWG Library Evolution
P2841R1 Concept Template Parameters Corentin Jabot 2023-10-14 2023-10 P2841R0 EWG Evolution
P2845R3 Formatting of std::filesystem::path Victor Zverovich 2023-10-01 2023-10 P2845R2 LEWG Library Evolution
P2845R4 Formatting of std::filesystem::path Victor Zverovich 2023-10-07 2023-10 P2845R3 LEWG Library Evolution
P2862R1 text_encoding::name() should never return null values Daniel Krügler 2023-09-24 2023-10 P2862R0 LEWG Library Evolution,LWG Library
P2863R2 Review Annex D for C++26 Alisdair Meredith 2023-10-15 2023-10 P2863R1 EWG Evolution,LEWG Library Evolution
P2885R3 Requirements for a Contracts syntax Timur Doumler 2023-10-05 2023-10 P2885R2 SG21 Contracts
P2893R1 Variadic Friends Jody Hagins 2023-10-09 2023-10 P2893R0 EWG Evolution
P2897R1 aligned_accessor: An mdspan accessor expressing pointer overalignment Mark Hoemmen 2023-10-13 2023-10 P2897R0 LEWG Library Evolution
P2900R0 Contracts for C++ Joshua Berne 2023-10-12 2023-10   SG21 Contracts
P2900R1 Contracts for C++ Joshua Berne 2023-10-09 2023-10 P2900R0 SG21 Contracts
P2911R1 Python Bindings with Value-Based Reflection Adam Lach 2023-10-13 2023-10 P2911R0 SG7 Reflection
P2927R0 Observing exceptions stored in exception_ptr Gor Nishanov 2023-10-14 2023-10   LEWGI SG18: LEWG Incubator,EWG Evolution,LEWG Library Evolution
P2932R1 A Principled Approach to Open Design Questions for Contracts Joshua Berne 2023-10-04 2023-10 P2932R0 SG21 Contracts
P2935R3 An Attribute-Like Syntax for Contracts Joshua Berne 2023-10-05 2023-10 P2935R2 SG21 Contracts
P2959R0 Container Relocation Alisdair Meredith 2023-10-15 2023-10   LEWG Library Evolution
P2961R1 A natural syntax for Contracts Timur Doumler 2023-10-12 2023-10 P2961R0 SG21 Contracts
P2962R0 Communicating the Baseline Compile Command for C++ Modules support Daniel Ruoso 2023-10-13 2023-10   SG15 Tooling
P2967R0 Relocation Is A Library Interface Alisdair Meredith 2023-10-15 2023-10   LEWG Library Evolution
P2971R1 Implication for C++ Walter E Brown 2023-10-14 2023-10 P2971R0 EWG Evolution
P2978R0 A New Approach For Compiling C++ Hassan Sajjad 2023-09-26 2023-10   SG15 Tooling
P2979R0 The Need for Design Policies in WG21 Alisdair Meredith 2023-10-13 2023-10   EWG Evolution,LEWG Library Evolution
P2980R0 A motivation, scope, and plan for a physical quantities and units library Mateusz Pusz 2023-10-15 2023-10   SG6 Numerics,LEWGI SG18: LEWG Incubator,SG23 Safety and Security,LEWG Library Evolution
P2981R0 Improving our safety with a physical quantities and units library Mateusz Pusz 2023-10-15 2023-10   SG23 Safety and Security,LEWG Library Evolution
P2982R0 `std::quantity` as a numeric type Mateusz Pusz 2023-10-15 2023-10   SG6 Numerics,LEWG Library Evolution
P2984R0 Reconsider Redeclaring static constexpr Data Members Alisdair Meredith 2023-10-15 2023-10   EWG Evolution
P2985R0 A type trait for detecting virtual base classes Giuseppe D'Angelo 2023-10-09 2023-10   LEWG Library Evolution
P2986R0 Generic Function Pointer Lauri Vasama 2023-10-14 2023-10   EWG Evolution
P2988R0 std::optional<T&> Steve Downey 2023-10-15 2023-10   LEWG Library Evolution
P2989R0 A Simple Approach to Universal Template Parameters Corentin Jabot 2023-10-14 2023-10   EWG Evolution
P2990R0 C++ Modules Roadmap Daniel Ruoso 2023-10-14 2023-10   SG15 Tooling
P2991R0 Stop Forcing std::move to Pessimize Brian Bi 2023-10-11 2023-10   SG20 Education
P2992R0 Attribute [[discard]] and attributes on expressions Giuseppe D'Angelo 2023-10-10 2023-10   EWGI SG17: EWG Incubator,SG22 Compatability,EWG Evolution
P2994R0 On the Naming of Packs Barry Revzin 2023-10-13 2023-10   EWG Evolution
P2995R0 SG16: Unicode meeting summaries 2023-05-24 through 2023-09-27 Tom Honermann 2023-10-08 2023-10   SG16 Unicode
P2996R0 Reflection for C++26 Barry Revzin 2023-10-15 2023-10   EWG Evolution
P2997R0 Removing the common reference requirement from the indirectly invocable concepts Barry Revzin 2023-10-13 2023-10   SG9 Ranges,LEWG Library Evolution
P2999R0 Sender Algorithm Customization Eric Niebler 2023-10-14 2023-10   LEWG Library Evolution
P3001R0 std::hive and containers like it are not a good fit for the standard library Jonathan Müller 2023-10-15 2023-10   LEWG Library Evolution
P3002R0 Guidelines for allocators in new library classes Pablo Halpern 2023-10-15 2023-10   LEWG Library Evolution
P3003R0 The design of a library of number concepts Johel Ernesto Guerrero Peña 2023-10-14 2023-10   SG6 Numerics
P3008R0 Atomic floating-point min/max Gonzalo Brito Gadeschi 2023-10-15 2023-10   SG1 Concurrency and Parallelism,LEWG Library Evolution
P3009R0 Injected class name in the base specifier list Joe Jevnik 2023-10-12 2023-10   EWG Evolution
P3010R0 Using Reflection to Replace a Metalanguage for Generating JS Bindings Dan Katz 2023-10-13 2023-10   SG7 Reflection
P3011R0 Supporting document for Hive proposal #1: outreach for evidence of container-style use in industry Matt Bentley 2023-10-15 2023-10   SG14 Low Latency,LEWG Library Evolution
P3012R0 Supporting document for Hive proposal #2: use of std::list in open source codebases Matt Bentley 2023-10-14 2023-10   SG14 Low Latency,SG20 Education,LEWG Library Evolution
P3014R0 Customizing std::expected's exception Jonathan Müller 2023-10-14 2023-10   LEWG Library Evolution
P3015R0 Rebuttal to Additional format specifiers for time_point Howard Hinnant 2023-10-13 2023-10   LEWG Library Evolution
P3016R0 Resolve inconsistencies in begin/end for valarray and braced initializer lists Arthur O'Dwyer 2023-10-15 2023-10   EWGI SG17: EWG Incubator,LEWGI SG18: LEWG Incubator,EWG Evolution,LEWG Library Evolution
P3018R0 Low-Level Integer Arithmetic Andreas Weis 2023-10-15 2023-10   SG6 Numerics,LEWGI SG18: LEWG Incubator,LEWG Library Evolution
P3019R0 Vocabulary Types for Composite Class Design Jonathan Coe 2023-10-14 2023-10   LEWG Library Evolution,LWG Library
P3020R0 2023-09 Library Evolution Poll Outcomes Inbal Levi 2023-10-15 2023-10   All of WG21
P3021R0 Unified function call syntax (UFCS) Herb Sutter 2023-10-14 2023-10   EWG Evolution
P3022R0 A Boring Thread Attributes Interface David Sankel 2023-10-14 2023-10   LEWG Library Evolution
P3023R0 C++ Should Be C++ David Sankel 2023-10-14 2023-10   EWG Evolution,LEWG Library Evolution

Inside STL: The Different Types of Shared Pointer Control Blocks -- Raymond Chen

RaymondChen_5in-150x150.jpgIn the realm of C++ standard library shared pointers, a crucial component for managing object lifetime is the control block, which contains reference count information and instructions for disposal and deletion. Depending on whether you use make_shared, allocate_shared, or manually assign an already-constructed pointer, different types of control blocks come into play, each with its own characteristics and optimizations for efficiently handling object management.

Inside STL: The Different Types of Shared Pointer Control Blocks

By Raymond Chen

From the article:

We saw earlier that C++ standard library shared pointers use a control block to manage the object lifetime.

struct control_block
{
    virtual void Dispose() = 0;
    virtual void Delete() = 0;
    std::atomic<unsigned long> shareds;
    std::atomic<unsigned long> refs;
};

The control block has pure virtual methods, so it is up to derived classes to establish how to dispose and delete the control block.

If you ask a shared_ptr to take responsibility for an already-constructed pointer, then you get this:

template<typename T>
struct separate_control_block : control_block
{
    virtual void Destroy() noexcept override
    {
        delete ptr;
    }
    virtual void Delete() noexcept override
    {
        delete this;
    }
    T* ptr;
};

SObjectizer Tales – 2. Can you call me back?--Marco Arena

A new episode of the series about SObjectizer and message passing:

SObjectizer Tales – 2. Can you call me back

by Marco Arena

From the article:

A camera vendor has just released a new SDK that works through callbacks. Basically, the user sets a function that will get called by the SDK on every new available frame. How can we integrate this into a producer agent?

How to Use Monadic Operations for `std::optional` in C++23 -- Bartlomiej Filipek

monadic_optional.pngIn this post we’ll have a look at new operations added to std::optional in C++23. These operations, inspired by functional programming concepts, offer a more concise and expressive way to work with optional values, reducing boilerplate and improving code readability.

How to Use Monadic Operations for `std::optional` in C++23

By Bartlomiej Filipek

From the article:

Let’s meet and_then()transform() and or_else(), new member functions.

Traditional Approach with if/else and optional C++20  

In C++20 when you work with std::optional you have to rely heavily on conditional checks to ensure safe access to the contained values. This often led to nested if/else code blocks, which could make the code verbose and harder to follow.

Consider the task of fetching a user profile. The profile might be available in a cache, or it might need to be fetched from a server. Once retrieved, we want to extract the user’s age and then calculate their age for the next year. 

Phantom and Indulgent Shared Pointers -- Raymond Chen

RaymondChen_5in-150x150.jpgIn our exploration of shared_ptr variations, we've previously covered cases where the stored pointer was either empty or pointed to a managed object. Now, we delve into the intriguing cases of phantom shared pointers, where the stored pointer is null but secretly manages an object, and indulgent shared pointers, which point to something but own nothing, offering unique utility for scenarios like static storage duration, with methods like use_count() and get() aiding in their detection.

Phantom and Indulgent Shared Pointers

By Raymond Chen

From the article:

Last time, we looked at various ways to convert among different shared_ptrs. We finished with this diagram:

2023-10-02_14-15-23.png

 

 

 

You are familiar with an empty shared pointer, which manages no object and has no stored pointer. You are also familiar with a full shared pointer, which manages an object and has a non-null stored pointer (to the managed object, or something whose lifetime is controlled by the managed object). But what about those other two guys?

In the upper right corner, you have the case of a shared pointer that manages an object but whose stored pointer is null, which I’ve called a phantom shared pointer. If you convert the shared pointer to a bool, it produces false, because you can’t use it to access anything. The phantom shared pointer looks empty at a casual glance, but it secretly manages an object behind the scenes. That secretly-managed object remains alive for no visible reason. There is no way to access that secretly-managed object, but it’s still there. It’s a phantom which follows you around.

SObjectizer Tales - 1. Producing Images--Marco Arena

A new episode of the series about SObjectizer and message passing:

SObjectizer Tales - 1. Producing Images

by Marco Arena

From the article:

Since using any real camera drivers is out of scope, we’ll use OpenCV to open our default camera (e.g. the webcam) and grab frames one by one. In case you don’t have any available camera on your machine, we’ll provide a simple “virtual producer” that replays some images from a directory...