Doc. no.: | N3890 |
---|---|
Date: | 2014-01-19 |
Project: | Programming Language C++, Library Evolution Working Group |
Reply-to: | Zhihao Yuan <zy at miator dot net> |
struct Entry
{
std::deque<Entry> messages;
// ...
};
The goal of this paper is to allow recursive data structure definitions with STL containers, while to make the STL container instantiations well-formed even when some of the template arguments are incomplete types (in contrast to 17.6.4.8/2) is an approach to achieve the goal without breaking any language restrictions or existing practices.
The approach, namely “Containers of Incomplete Types”, was well-known shortly after the C++98 standard being shipped[1]
, is one of the main features provided by Boost.Container[2]
and libstdc++, and is receiving increasing interest in libc++.
Some workarounds have been discussed, including using a container of smart pointers. However, the proposed solution has the following significant advantages:
value_type
is well-preserved;An additional “Completeness” requirement for each category of the containers – Sequence, Associative, Unordered associative, and Container adaptors, plus the Hash requirements and Allocator requirements.
Require the unspecialized and transparent function objects (std::less<T>
and std::less<>
, for example, respectively) to be complete types unconditionally.
Require std::allocator<T>
to unconditionally satisfy the “Allocator completeness requirements” in 1).
2) and 3) are trivial to the existing implementations, but not 1). Some changes involve ABI breakages, and some changes result in less compile-time checking; but run-time performance will not be affected (interestingly, the situation is similar to that of the SCARY iterators, as well as some techniques we are using, plus some goals we want to achieve from a type system’s point of view).
Currently,
libc++ can fully satisfy the proposed solution after being patched (see Sample Implementation, but with an ABI breakage on std::deque
;
libstdc++ can satisfy the proposed solution with some untested changes made to the unordered associative containers;
MSVC STL perfers to perserve some compile-time constants for debugger visualization on std::deque
(read as “the solution remains unknown”), and is interested in patching std::list
and std::forward_list
.
The proposed feature set is chosen in a “least common multiple” (of the existing implementations) manner. All the possible (no std::array
) and useful cases are conditionally covered, so that only the standard library implementations may be affected, but not existing user code. For example, if a customized MyLess
is not a complete type, the whole std::set<T, MyLess>
specialization is not well-formed.
This specification only covers 1) in Impact on the Standard; 2) and 3) are merely wording details.
A type H
satisfies the Hash completeness requirements if:
h(k)
is well formed when treated as an unevaluated operand.[Just a note: h
and k
are defined in 17.6.3.4 –end note]
A type X
satisfies the Allocator completeness requirements if:
X::value_type
is defined and identical to T
.[Just a note: If LWG 2311 is applied, this section may no longer be needed. –end note]
A sequence container with an Allocator
template parameter is a complete type if:
Allocator
satisfies the Allocator completeness requirements.An associative container is a complete type if:
Compare
is a complete type, andAllocator
satisfies the Allocator completeness requirements.An unordered associative container is a complete type if:
Hash
satisfies the Hash completeness requirements,Pred
is a complete type, andAlloc
satisfies the Allocator completeness requirements.Compare
, if any, is a complete type, andContainer
is a complete type, and Container::size_type
is a complete type.The proposed solution has been implemented (as an llvm/libc++ fork) and well- tested: https://github.com/lichray/libcxx/tree/container_incomplete
[1]
Austern, Matthew H. The Standard Librarian: Containers of Incomplete Types. http://www.drdobbs.com/the-standard-librarian-containers-of-inc/184403814
[2]
Main features: Containers of Incomplete Types. “Boost.Container” http://www.boost.org/doc/libs/1_55_0/doc/html/container/main_features.html#container.main_features.containers_of_incomplete_types
Thanks to the library implementers who helped refine the idea, run my crappy test code, and review the patches publicly and/or privately.