CppCon 2019:From STL to Ranges

Jeff Garland

Intro

  • The beginning of the end – for begin and end

Basics

std::sort(a.begin(), a.end())

Instead:

ranges::sort(a);

Example with find_if

the ranges way: filter_view

for (int i : rng::filter_view (a, is_six)) { std::cout << i << “ “; }

Tristan Brindel NanoRange

Godbolt

  • supports several
  • range: something that can be iterator over
  • range algo: algorithm that takes range
  • view: lazy range thats cheap top copy
  • ranger adapter: turn range into a view

mechanics

  • 3 new names ranges, ranges::views, views = ranges::views

Why new namespaces

  • behavior and guaranteed of some algorithms are changed

What’s a range

  • iterator pair is simplest
  • sentinel and iterator can be different types
  • ranges can be infinite
  • any container with begin()/end() can be used in a range

Views are ranged with lazy evaluation

  • non-owning of elements
  • all methods
    O(1)

    for copy and assignment

range adaptors -> views from ranges

  • pipeline syntax

filter_view adaptor

for (int i = range_filter_view (vi, is_event))

No more for loops

Range Algorithm details

  • list of range algorithms

Projection parameters

  • provides first class filtering predicate
  • comes from the Adobe Source Libraries (ASL)

ranges::sort(vistuff, std::less<>{}, [](auto const &i) {return i.value;})

Views and View Adaptor details

How do ranges perform

  • Compile time: no noticeable difference
  • runtime: nothing expected over stl algorithms

Resources

wg21.link/n4810

CppCon 2019:Dawn of a new Error

Phil Nash

Exceptions

P0709 R2 Zero-overhead deterministic exceptions (static exceptions)

Swift has best error handler

Exploding return types

p03w3R7 std::expected

p0798R4 Monadic operations for std::optional

What is std::error

p1028R1

GitHub.com/ned14/status-code

error code always represent an error

p1029R1 [[move relocates]

p1144 object relocation in terms of move plus destroy

With compiler optimizations no extra overhead compared to regular return

error_code fits in two registers

auto result = try add_one (divide (42, parse_int(input));

levelofindirection.com/refs/dawn.html

boost::outcome

Question

  • What is
    intptr_t

    ?

CppCon start

CppCon 2019: Some photos

CppCon moved to Denver, Colorado (technically Aurora, CO) just a few miles from Denver Airport. 1400 people attended from Sept 16-20 and a 150 talks over the 5 days. Additionally, there were 1 and 2 day training classes the weekends before and after the conference.

The Gaylord Rocky Mountain Resort hosted CppCon. It’s a huge place that’s very conference oriented though there are some nice pools and rec areas. You are pretty isolated so plan on eating at the nice but overpriced restaurants.

CppCon 2019: Getting Allocators out of Our Way

Alisdair Meredith and Pablo Halpern

Allocators are great

std::pmr::monotoic_buffer_resource src(buffer, sizeof (buffer);
pmr::set. uniq(&src);

What if we could reduce the cost

goal: reduce cost of developign an allocator aware

What’s our problem?

Allocators bloat class interfaces

Performance in practice

  • Memory hiearchy: Cache; main, virtual
  • objects used together should be together

C++ allocatros

allocator_traits simplify allocators; mostly for users. Containers now have problems in their face

What about nested containers

  • In a vector<string> vector has one and each string potentiallly different allocator
  • scoped allocator model: container passes allocator into each item. Solves memory diffisuion
  • scoped_allocator_adapter
  • Allocator template policies interfere with vocabulary types

C++17: PMR: a simpler allocator model

  • Non-template std::pmr::memoryresource
  • The wrapper
  • class memory_resource
  • polomorphic_allocator
  • polymorphic_allocator<byte>
    • “One true” allocator vocabulary type
    • Only a template to be compatible for C++11
  • std::pmr::new_delete_resource()
    • Uses new/delete
    • always availabel
    • thread safe
  • unsynchronized_pool_resource
    • Pools of similar sized objects
    • good for dynamic data strucures
    • Single-threaded
    • avoids concurrency lock overhead
  • monootonic_buffer_resource
    • Ultra fast; single threaded, contiguous
    • for containers that grow monotonically
  • test resource
    • GitHub bloomberg/p1160

How to use allocators

class Student {
  pmr::string d_name;
pmr::string d_email
pmr::vector<int d_grades;

using allocator_type = pmr::polymovic_allocator<>; // Important

}

  • Overload each constructor having default_arguments
  • Variadic argument lists: allocator goes at the beginning

Rewriting std::unordered_map to use pmr allocators

  • Example with copying constructors. Lots of duplicated code

What about a language solution

  • Build on a strong foundation built up to C++17

HashMap<int,int> x {} using myAllocator;

  • using myAllocator

Bloomberg

  • Bloomberg vision 2020

CppCon 2019: Converting to C++20 Modules

Nathan Sidwell

Background

gcc.gnu.org/wiki/cxx-modules

g++ -fmodules-ts <a href="http://foo.cc">foo.cc</a>

  • Using timyxml2 library as example
  • On header, one .cpp, one makefile, one test program
  • When you compile a module you get a compiled module interface (CMI)
  • CME filenames related to module names is implementation defined as is where they are placed

A header unit

  • step through telling bild system: mapping file with rules for .h.gcm

CppCon 2019: Maintainability and Refactoring Impact of Higher-Level Design Features

Titus Winter

Multi-step refactoring

  • Basic atoms of refactoring

Rename a type

namespace oldns {class StringPiece ...}
namespace absl {class string_view ...copy StringPiece }
problems

or

namespace oldns {using StringPiece = absl::string_view}


break with forward declaration. forward declarations no real performance improement

also, ADL causes it to break

instead

namespace oldns {class StringPiece...}
namespace absl { using string_view = oldns::StringPiece;}

then deal with ADL problems

Find a way tso pre/post syntax/semancs can co-exist

Can we change functions?

  • small atoms: weaken preconditions; stregthen postconditions
  • large atomes: opposite

Changing return types

  • void to anything is doable
  • into to int64_t?

Can we change templates

Can we change concepts

  • Single-step: sure
  • Multi-step: No

CppCon 2019: Speed Is Found In The Minds of People

Andrei Alexandrescu

This was the best talk I saw at CppCon 2019

Sorting

  • What is quick-select?

Naive Implementations

  • qsort()

Better

  • qsort() with fallback to small_sort()

Investigating small_sort

  • Challenge: increase the THRESHOLD so sorting for 1000 elements work
  • binary search is slower. Branch prediction is reader
  • branchless even slower than binary
  • middle-out insertion support: better comparison and better moves (13%) but no performance change
  • stupid_small_sort(): make_heap(); insertion_sort(). Improvment in comparison, swaps; 9% slower
  • Blended cost: (C(N) + M(n) + k(D(n))/n. (compares + swaps + distance)

Timeline

  • 1990’s OOP
    • Inheritance and virtuals
  • 2000’s Generic Programing
    • Iterators and algos
  • 2020’s: design by introspection
    • Inspect and customize everything
    • We can’t implement the best sort with generic programming

Questions

  • Parametric complexity theory???