C++17 Library Papers for Cologne

published at 13.02.2015 16:12 by Jens Weller

Last fall I did the last series about the Standardization papers for C++. I didn't had the time to finish the last part for the Library subgroup, as Meeting C++ 2014 was getting close too. I'll be attending the next meeting of the Library Working Group in Cologne, which is just a few days away, so I'll do a miniseries for the LWG papers I have to read anyways in order to prepare for the meeting starting at the 23rd. So, this series will contain an overview on the papers in the followup mailing of Urbana and the newest mailing from mid February 2015. Lets get started!

Did you notice, that std::regex does not have an allocator? Right, unlike the containers, strings and a few other things in the standard library, you cannot specify an allocator for an regex. This makes it hard to use std::regex in certain use cases, for example with shared memory.

There is a "simple" guideline, if a function in the standard library should be noexcept, the paper names the essiantial guidelines for C++11 and noexcept:

Each library function, having a wide contract (i.e. does not specify undefined behavior due to a precondition), that the LWG agree cannot throw , should be marked as unconditionally noexcept .

contract (i.e. does not specify undefined behavior due to a precondition), that the LWG agree , should be marked as . If a library swap function, move constructor, or move assignment operator ... can be proven not to throw by applying the noexcept operator then it should be marked as conditionally noexcept. No other function should use a conditional noexcept specification.

The paper goes into more details, especially on move constructors, and the impact it has if they are noexcept or not. If the move constructor is (not) noexcept, then the default constructor(s) should (not) be too. The paper gives also a very nice insight in the inner working and ongoing discussions in the LWG.

Well, this paper is about replacing the wording for std::uncaught_exceptions.

This paper contains the wording for atomic smart pointers.

This document contains the wording for function objects, std::optional and std::any.

Quote from the proposal:

This is a proposal to add erase_if(container, pred) and erase(container, value), making it easier to eliminate unwanted elements correctly and efficiently.

Nice.

This proposal has actually syntax highlighting, and is very well readable. Some men want to see the world burn...

Except that, its about making std::reference_wrapper TriviallyCopyable. Which is a very good point, as the reference_wrapper only holds an internal pointer to the object it wraps (not a reference though). Most implementations of reference_wrapper are already TriviallyCopyable, one exception is MSVC here. This change breaks the ABI, if the implementation has currently a non TriviallyCopyable reference_wrapper.

One of the arguments to do so, is the small buffer optimization, which then could be applied to reference_wrapper, the paper contains a trait which would allow to test for the ability of small buffer optimization at compile time.

This paper suggests to add two new member functions to std::map and std::unordered_map:

try_emplace

insert_or_assign

The impact on the standard would only be that 8 new template methods are added to the unique-key maps. From the paper:

The justification and rationale for the new interface are given in N3873. The initial reaction to N3873 in Issaquah was that the existing map interfaces should be fixed rather than adding new interfaces. We explored this idea in N4006 in Rapperswil and decided that the original proposal was preferable (with some name changes). This paper only summarises the proposed extension without repeating the original discussion.

This paper mainly contains the proposed wording for non-member size and related changes. N4207, the original paper, summarized the goal to add:

to add non-member std::size and other useful utility functions (std::empty, std::front, std::back, and std::data). The inclusion of these functions would provide benefits in regards to safety, efficiency, and generality.

std::size could be implemented as a simple constexpr function template:

template<class T, std::size_t N> constexpr std::size_t size(const T (&array)[N]) noexcept { return N; }

Further the authors argue:

We can currently use std::distance(std::begin(c), std::end(c)) to generically obtain the number of elements for both built-in arrays and Standard containers. However, as Stephan T. Lavavej pointed out, std::distance is verbose and inefficient for many containers. The Standard containers have a constant time size() member function yet std::distance is linear time for containers with a weaker than random-access iterator (list, the associative containers, and the unordered associative containers). Another disadvantage of std::distance is that it is not constexpr.

A proposal for a non-owning, smart-pointer like wrapper for raw-pointers. From the paper:

This paper proposes observer_ptr, a (not very) smart pointer type that takes no ownership responsibility for its pointees, i.e., for the objects it observes. As such, it is intended as a near drop-in replacement for raw pointer types, with the advantage that, as a vocabulary type, it indicates its intended use without need for detailed analysis by code readers.

Join the Meeting C++ patreon community!

This and other posts on Meeting C++ are enabled by my supporters on patreon!