C++ Papers for Chicago: Part 3 - Library
by Jens Weller
This week the C++ committee meeting has started in Chicago, and we will hopefully see at its end, what improvements C++14 brings to C++11. And in this 3rd part of my series for the Chicago papers, I will start looking at the library proposals, as there are in total 26 proposals for Library to cover, and I'll include network and reflection in the last part. The first part was about concurrency papers, and the 2nd part covered mainly core, concepts & evolution.
In case you work professionally with the C++ Standard (e.g. getting paid for), this paragraph is for you. Otherwise simply skip towards the papers. I'm currently working on a software, making things a littel easier, it will feature listing dependencies to other papers and I do also plan to add a search somehow plus some other features. If you are/would able to back this, please contact me. The tool will be available in 2014.
This edition is about the papers from the library subgroup, so it is likely to contain a few more papers on C++14, and a few papers for the standards after C++14...
N3699 - A proposal to add a generalized callable negator
This proposal aims at replacing the not1 and not2 functions in the standard. As they only accept unary/binary functors, with C++11/14 a more modern approach can be taken. The paper suggests to create a new negator template not_fn in the standard. This proposal would, if successful, replace the not1 and not2 functions with a template function not_fn taking 1 - n arguments. One advantage is, that you then could also use results from std::bind and std::function, which you currently can not use with not1/not2. not_fn would allow to create a negator for any callable object.
N3700 - Hierarchical Data Structures and Related Concepts for the C++ Standard Library
Long title and long paper, which brings already a little bit of history with it starting in 2006, and has been now updated as it seems. Interestingly its distributed under the boost software license, only a few papers make assumptions about the license of the code they contain. The paper aims at adding tree-like structures to the Standard Library. The paper is based on the work for the boost.tree library. The paper proposes to add the classes binary_tree and nary_tree to the Standard Library together with a few tree-algorithms and hierarchy-adaptors.
N3702 - Introducing an optional parameter for mem_fn, which allows to bind an object to its member function
This proposal aims at what already is described in its title: adding an optional parameter to mem_fn, for supporting member functions. Today you'd have to use std::bind, a lambda or a wrapper function to achieve the same, generating quite some boilerplate code. The proposal wants to add a parameter to mem_fn for passing the instance pointer to the function.
N3703 - Extending std::search to use Additional Searching Algorithms
The 3rd version of this paper, which aims at adding more search algorithms to the standard library. This version includes the proposed standard wording, an simplified default interface and comparison predicates for the two proposed algorithms. The proposed add-on to std::search is, to include a search object to its interface, allowing the user to customize its search with a search object:
template<typename Iterator, typename Searcher>
void search(Iterator first, Iterator last, Searcher&& search)
Additionally the paper wants to add two new search algorithms as searcher classes to the Standard Library:
The proposal also includes an example implementation of a searcher object.
N3708 - A proposal to add coroutines to the C++ standard library
This proposal aims at adding coroutines as a library solution, based on boost::coroutines. The PDF of this proposal is somehow hard to read in you browser, as it seems to draw the text or something. It feels weird and makes to me impossible to actually read it to an extend I could do any work with it. Maybe you shouldn't open the PDF if you are on a slow machine in your browser. Adobe Reader seems to be better in dealing with it. The paper gives a nice overview over coroutines, and tries to add boost::coroutines to the standard. Coroutines are a possible library solution to resumable functions, so this paper is also to see a little bit in the context of concurrency.
N3716 - A printf-like Interface for the Streams Library
This paper aims at adding a printf like interface to C++. The format of printf is widely used, not only in C, but also in other languages such as Perl or even Java. There are some library based implementations for a more or less type safe printf available, for example boost::format or in Qt. The paper aims at adding a type safe version to the standard, that supports printf and boost::format ways of formatting output with strings:
cout << format("The answer:%5d\n") % 42; // boost.format cout << putf("The answer:%5d\n", 42); // std::experimental::putf
So the goal is to also integrate printf support into iostreams.
N3719 - Extend INVOKE to support types convertible to target class
This paper is about the Standard clause $ 20.10.2 which defines an INVOKE expression. This paper aims at adding support for invoking types convertible to the target class. In particular its about invoking methods over member pointers and functors, which are currently different.
N3726 - Polymorphic Memory Resources
This paper is the new version of polymorphic allocators, which did receive strong support for its concepts in Bristol. It aims at having a standard interface for allocators, that is runtime sensitive. So that you could exchange data between containers that have different allocators. Currently allocators in the STL are bound to the type at compile time. Which will not really change with this proposal, instead this proposal aims at adding standard allocator types. The paper makes two considerations about allocators:
- The allocator used to construct a container should also be used to construct the elements within that container.
- An object’s type should be independent of the allocator it uses to obtain memory.
While the first point is already part of the C++ Standard, the second is not. Its the opposite, currently the type of a container depends also on its allocator for example. The author proposes a new namespace in std: std::polyalloc. The name might be subject to change, it shall contain the polymorphic allocator interface for C++. The namespace will contain a abstract base class memory_resource, with the 3 pure virtual methods allocate(), deallocate() and is_equal(). The template polymorphic_allocator<T> acts as a wrapper around a memory_resource pointer, which allows separation of the objects type and allocator. So two objects of the type list<int, polymorphic_allocator<int> > are the same type, but maybe use totally different allocators. Also polymorphic_allocator gives memory_resource a C++11 allocator interface. The namespace polyalloc will also contain template aliases for all STL Containers (except std::array). The paper also shows an example on how to make use of different allocators in a std::polyalloc::vector<string_type>, and hence comparing strings allocated with different allocators directly. Something that yet cannot be done in C++11.
N3727 - A proposal to add invoke function template
Building up on the previous proposal N3719, this paper aims at not only improving the wording of the standard for the invoke expression, but also adding a function template std::invoke usable with all versions of the invoke expression.
N3729 - Invocation type traits
Adding a new type trait for invocation types is the aim of this paper. The proposed std::invocation_type contains a typedef type is the implied function type of the callable object when called with the given argument types. For example this could help with perfect forwarding, the paper uses an implementation of async as an example.
N3739 - Improving pair and tuple
This is the first revision of this paper, the previous version is N3680. There is std::pair and std::tuple, which both have their uses, but do not share the same interface. But that is a different story, the paper deals mostly with constructing tuples or pairs from types. Which often can fail, due to the restrictions on the constructors for tuple and pair. The paper shows that the over-constraint constructors of both tuple and pair leads to problems in using them easily in code, that could be fixed with lifting some of the constraints.
N3740 - A Proposal for the World's Dumbest Smart Pointer
C++11 brought std::shared_ptr and unique_ptr to the standard, and deprecated C++03 auto_ptr. This proposal aims at adding a 3rd smart pointer type, only providing very basic functionality. And very basic means, the pointer isn't owning the object its pointing to. Its only providing the interface of a pointer type, but does not know how to manage it. This class could replace a raw pointer, only used to access or point to an object. The paper proposes the name exempt_ptr for this kind of type, but also lists various other possible names. An alternative would be to define a unique_ptr with a non-deleting deleter. But the semantics of a unique_ptr are quite different from an non-owning pointer type. While unique_ptr is only moveable, a non-owning pointer type should be also copyable and movable.
N3742 - Three <random>-related Proposals
A new version of a previous already in Bristol discussed paper, there are no major changes since. So this version only contains a few corrections and adoptions to C++14. The 3 proposed changes in this paper are:
- adding a function template to <algorithm>
- adding a few novice-friendly functions to <random>
- to deprecate some related legacy interfaces
Starting with <algorithm>, it was proposed to add random_sample and random_sample_n to the Standard Library in C++11. But then considered to propose them for TR2 instead, as they might not be understand well enough for Standardization back then. This paper now proposes to unify random_sample and random_sample_n as sample.
The novice-friendly functions considered adding to <random> are:
- global_urng() - returns an implementation defined global Universal Random Number Generator.
- randomize() - sets the above global URNG object to an (ideally) unpredictable state
- pick_a_number(from, thru) - returns an int number in range[from,thru]
- pick_a_number(from, upto) - returns a double number in the open range[from,upto)
It is also proposed to give the algorithm shuffle and the above proposed sample a default argument of type UniversalRandomNumberGenerator&&, with the default value returned by global_urng(). Also the proposal aims for the deprecation of rand(), srand() and RAND_MAX from <cstdlib>, plus random_shuffle() from <algorithm>, in order to provide a more precise and user friendly interface for randomness in C++.
N3743 - Conditionally-supported Special Math Functions for C++14
As the previous paper, this is an updated paper already discussed in Bristol. So, this paper is about Special Math Functions, which could be conditionally supported for C++14/C++1y. The paper claims, that adding those functions to the C++ Standard would help the numeric computing communities to adopt C++. Also it states, that these functions are not only useful for the scientific or engineering domain, but are less commonly used in other domains.
There is the need for some explanation (which is also stated in the paper), Special Match Functions were already in discussion for TR1, but left out. The reason was, that it was seen as a burden to the compiler vendors to implement those Special Math Functions. This is also valid for C++11. Today there exists a ISO Standard for Mathematical Special Functions, which could now be added to C++14. The paper proposes now, to add this standard as conditionally-supported. Where conditionally-supported is defined as:
"program construct that an implementation is not required to support" [DuT12]
This solves the problem of implementation for the compiler vendors, but still lets Special Math Function become a part of the C++ Standard.
N3749 - Constexpr Library Additions: functional
This paper is about constexpr, which allows in C++11 and after, to do calculations in (restricted) C++ code at compile time. This paper aims to update some of the functional template objects of the STL to be use able in constexpr code. Mainly the named function objects for comparison, std::less, (greater, equal, ...) are used as an example, which are currently not defined as being constexpr. But they could, and actually should, so the proposed change is more or less, to simply add constexpr to the operator() of those named function objects.
N3753 - Centralized Defensive-Programming Support for Narrow Contracts
A very interesting paper, that is hard to describe in short. The previous paper, I already claimed, that you should read it. I now want to add a little summary about what narrow and wide contracts are. The paper uses std::vector and operator vs. at(size_t) as an example, which I think is a very good one. The standard offers with both two different interfaces, the first being narrow (most efficient) and the second being wide (most safe):
- Has a narrow contract
- Which means, only the range of 0 - (size-1) is in the bounds of defined behavior, every thing else is undefined.
- In practice, operator will not check for you, if your index is valid
- Has a wide contract
- This means, it will test for all side effects. If the argument is out of range, then an exception is thrown.
- In practice, at will check your index each call, and is therefore not as fast as operator, but it will throw if you overreach.
This paper tries now to find a way, to minimize the risk for narrow contracts, to be undefined behavior. The authors suggest to use defensive programming for this, and to extend the Standard Library with the header <preassert>. This header shall contain the classes and macros to provide the additional support for C++ in defensive programming. The build mode (safe, debug, release build) then decide, which asserts are executed.
In the example that would mean, that operator contains an assert in safe build (all asserts), maybe in debug, and none in release. For more details please read this interesting paper.
This is the end of Part 3, Part 4 contains the 2nd part of library papers and network, reflection, undefined behavior and ranges.