Logo

Blog


Book: Programming with C++20 - Writing finished

A while ago, I announced that I was writing a book about C++20 (Programming with C++20 - Concepts, Coroutines, Ranges, and more). A lot of you have already purchased an early copy available on Leanpub. Thank you! While I haven't made much visible progress, I did well in the background.

Programming with C++20 Cover

Today I proudly tell you that I have finished the writing process! All chapters are written, making it around 340 pages. A couple of them are still out for review, so it will take some time until they will be available on Leanpub.

I made it just in time for my upcoming Programming with C++20 class at CppCon. Of course, a virtual class. You can still register and will get a complimentary copy of the book.

My next steps are

  • incorporating all the feedback
  • looking at all the code listings ensuring that they are nicely formatted
  • creating the index
  • adding some images
  • preparing the paperback version for KDP

This is how the final table of contents most likely will look like (unless your feedback leads to a change):

  • 1 Concepts: Predicates for strongly typed generic code
    • 1.1 Programming before Concepts
      • 1.1.1 The enable_if requirement
      • 1.1.2 Long error messages from template errors
    • 1.2 What are Concepts
      • 1.2.1 Thinking in concepts
      • 1.2.2 Concepts and types
    • 1.3 The anatomy of a concept
    • 1.4 Existing Concepts
    • 1.5 The requires-clause: The runway for Concepts
    • 1.6 The requires-expression
      • 1.6.1 Simple requirement
      • 1.6.2 Nested requirement
      • 1.6.3 Compound requirement
      • 1.6.4 Type requirement
      • 1.6.5 Complete constrained version of add
    • 1.7 Adding Concepts to make requirements reusable
    • 1.8 Testing requirements
    • 1.9 Using a Concept
      • 1.9.1 Using a constexpr function in a concept
      • 1.9.2 Applying a concept with a requires-clause
      • 1.9.3 Applying a concept with a trailing requires-clause
      • 1.9.4 Applying a concept as a type-constraint
    • 1.10 Abbreviated function template with auto as generic parameter
      • 1.10.1 What does such a construct do?
      • 1.10.2 Exemplary use case: Requiring a parameter type to be an invocable
    • 1.11 Concepts and constrained auto types
      • 1.11.1 Constrained auto variables
      • 1.11.2 Constrained auto return-type
    • 1.12 The power of Concepts: requires instead of enable_if
      • 1.12.1 Call method based in requires
      • 1.12.2 Conditional copy operations
      • 1.12.3 Conditional destructor
      • 1.12.4 Conditional methods
    • 1.13 Concepts ordering
      • 1.13.1 Subsumption rules details
      • 1.13.2 One more thing, never say not
    • 1.14 Improved error message
  • 2 Coroutines
    • 2.1 Regular functions and their control flow
    • 2.2 What are Coroutines
      • 2.2.1 Generating a sequence with coroutines
    • 2.3 The elements of Coroutines in C++
      • 2.3.1 Stackless Coroutines in C++
      • 2.3.2 The new kids on the block: co_await, co_return and co_yield
      • 2.3.3 The generator
      • 2.3.4 The promise_type
      • 2.3.5 An iterator for generator
      • 2.3.6 Coroutine customization points
      • 2.3.7 Coroutines restrictions
    • 2.4 Writing a byte-stream parser the old way
    • 2.5 A byte-stream parser with Coroutines
      • 2.5.1 Writing the Parse function as coroutine
      • 2.5.2 Creating an Awaitable type
      • 2.5.3 A more flexible promise_type
      • 2.5.4 Another generator the FSM
      • 2.5.5 Simulating a network byte stream
      • 2.5.6 Plugging the pieces together
    • 2.6 A different strategy of the Parse generator
    • 2.7 Using a coroutine with custom new / delete
    • 2.8 Using a coroutine with a custom allocator
    • 2.9 Exceptions in coroutines
  • 3 Ranges: The next generation STL
    • 3.1 Motivation
      • 3.1.1 Avoid code duplication
      • 3.1.2 Consistency
      • 3.1.3 Safety
      • 3.1.4 Composability
    • 3.2 The who is who of ranges
    • 3.3 A range
      • 3.3.1 What is a common_range?
      • 3.3.2 A sized_range
    • 3.4 A range algorithm
      • 3.4.1 Projections for range algorithms
    • 3.5 A view into a range
    • 3.6 A range adaptor
      • 3.6.1 A custom range adaptor
    • 3.7 The new ranges namespaces
    • 3.8 Ranges Concepts
    • 3.9 Views
    • 3.10 Creating a custom range
      • 3.10.1 Implementing the view
      • 3.10.2 A range adaptor for custom_take_view
      • 3.10.3 Add the pipe-syntax to custom_take_view
      • 3.10.4 A more generalized pipe-syntax implementation
  • 4 Modules
    • 4.1 Background about why modules
      • 4.1.1 The include hell
      • 4.1.2 I like to have secrets
    • 4.2 Creating modules
      • 4.2.1 A header unit
      • 4.2.2 A named module
    • 4.3 Applying modules to an existing code base
      • 4.3.1 Down with namespace details
      • 4.3.2 Now I can hide my secrets from you...
      • 4.3.3 What you gain
      • 4.3.4 Templates in modules
      • 4.3.5 Down with DEBUG
      • 4.3.6 In-line definitions of class members
      • 4.3.7 There are some limits
  • 5 std::format: Modern & type-safe text formatting
    • 5.1 Formatting a string before C++20
      • 5.1.1 Formatting a stock index with iostreams
      • 5.1.2 Formatting a stock index with printf
    • 5.2 Formatting a string using std::format
      • 5.2.1 std::format specifiers
      • 5.2.2 Escaping
      • 5.2.3 Localization
      • 5.2.4 Formatting floating-point numbers
    • 5.3 Formatting a custom type
      • 5.3.1 Writing a custom formatter
      • 5.3.2 Parsing a custom format specifier
    • 5.4 Referring to a format argument
    • 5.5 Using a custom buffer
      • 5.5.1 Formatting into a dynamically sized buffer
      • 5.5.2 Formatting into a fixed sized buffer
    • 5.6 Writing our own logging function
      • 5.6.1 Prefer make_format_args when forwarding an argument pack
      • 5.6.2 Create the format specifier at compile-time
      • 5.6.3 Formatting the time
  • 6 Three-way comparisons: Simplify your comparisons
    • 6.1 Writing a class with equal comparison
      • 6.1.1 Comparing different types
      • 6.1.2 Less hand-written code with operator reverse, rewrite and =default
    • 6.2 Writing a class with ordering comparison, pre C++20
    • 6.3 Writing a class with ordering comparison in C++20
      • 6.3.1 Member-wise comparison with =default
    • 6.4 The different comparison categories
      • 6.4.1 The comparison categories
      • 6.4.2 The comparison strength: strong or weak
      • 6.4.3 Another comparison strength: partial ordering
      • 6.4.4 Named comparison functions
    • 6.5 Converting between comparison categories
    • 6.6 New operator abilities: reverse and rewrite
    • 6.7 The power of the default spaceship
    • 6.8 Applying a custom sort order
    • 6.9 Spaceship-operation interaction with existing code
  • 7 Lambdas in C++20: New features
    • 7.1 [=, this] as a lambda capture
    • 7.2 Default-constructible lambdas
    • 7.3 Captureless lambdas in unevaluated contexts
    • 7.4 Lambdas in generic code
      • 7.4.1 Lambdas with templated-head
      • 7.4.2 Variadic lambda arguments
      • 7.4.3 Forwarding variadic lambda arguments
    • 7.5 Pack expansions in lambda init-captures
    • 7.6 Restricting lambdas with Concepts
  • 8 Aggregate initialization
    • 8.1 What is an aggregate
    • 8.2 Designated initializers
      • 8.2.1 Designated initializers in C
      • 8.2.2 Designated initializers in C++20
      • 8.2.3 Initializing a subset of an aggregate with designated initializers
      • 8.2.4 Initialize a subset with designated initializers without in-class member initializers
      • 8.2.5 Named arguments in C++: Aggregates with designated initializers
      • 8.2.6 Overload resolution and designated initializers
    • 8.3 Direct-initialization for aggregates
      • 8.3.1 Initialization forms: Braced or parenthesis initialization
      • 8.3.2 Aggregates with user-declared constructors
    • 8.4 Class Template Argument Deduction for aggregates
  • 9 Class-types as non-type template parameters
    • 9.1 What are non-type template parameters again
    • 9.2 The requirements for class types as non-type template parameters
    • 9.3 Class types as non-type template parameters
      • 9.3.1 A first contact with class types as NTTP
      • 9.3.2 What compile-time data do we have
    • 9.4 Building a format function with specifier count check
      • 9.4.1 A first print function
      • 9.4.2 Optimizing the format string creation
      • 9.4.3 Checking the number of specifiers in a format string
      • 9.4.4 Checking if type and specifiers do match
      • 9.4.5 Enable more use-cases and prevent mistakes
  • 10 New STL elements
    • 10.1 bit_cast: Reinterpreting your objects
    • 10.2 endian: Endianess detection at compile time
    • 10.3 to_array
    • 10.4 span: A view of continuous memory
    • 10.5 source_location: The modern way of __FUNCTION__
      • 10.5.1 Writing a custom assert function
      • 10.5.2 Writing a custom assert function with C++20
      • 10.5.3 Writing a custom log function with C++20
    • 10.6 contains for all associative containers
    • 10.7 start_with ends_with for std::string
  • 11 Language Updates
    • 11.1 Range-based for-loops with initializers
      • 11.1.1 Using a counter-variable in a range-based for-loop
      • 11.1.2 A workaround for temporaries
    • 11.2 New Attributes
      • 11.2.1 likely / unlikely
      • 11.2.2 no_unique_address
    • 11.3 using enums
    • 11.4 conditional explicit
      • 11.4.1 Writing a well behaving wrapper
      • 11.4.2 Communicate your intention, explicitly
  • 12 Doing (more) things at compile-time
    • 12.1 The two worlds: compile- vs. run-time
      • 12.1.1 The benefit of compile-time execution
    • 12.2 is_constant_evaluated: Is this a constexpr-context?
      • 12.2.1 Different things at compile- and run-time
      • 12.2.2 is_constant_evaluated is a run-time value
    • 12.3 Less restrictive constexpr-function requirements
      • 12.3.1 new / delete: Dynamic allocations during compile-time
      • 12.3.2 A constexpr std::vector
    • 12.4 Utilizing the new compile-time world: Sketching a car racing game
    • 12.5 consteval: Do things guaranteed at compile-time
      • 12.5.1 as_constant a use-case for consteval
      • 12.5.2 Force compile-time evaluation for compile-time checks
      • 12.5.3 is_constant_evaluated doesn't make it compile-time
    • 12.6 constinit: Initialize a non- const object at compile-time
      • 12.6.1 The static initialization order problem
      • 12.6.2 Ensure compile-time initialization
  • Acronyms
  • Bibliography
  • Index

Andreas