Document number: | N3814 |
Date: | 2013-10-06 |
Project: | Programming Language C++, Reflection Study Group |
Authors: | Jeff Snyder <jeff-isocpp@caffeinated.me.uk> |
Chandler Carruth <chandlerc@google.com> | |
Reply-to: | Reflection Study Group <reflection@isocpp.org> |
Introduction
Targeted use cases
1. Generation of common functions
2. Type transformations
3. Compile-time context information
4. Enumeration of other entities
Submitting a proposal
References
The reflection study group (SG7) of the C++ standards committee is soliciting proposals for features that add compile-time reflection capabilities to C++. Whilst all proposals regarding reflection in C++ will be considered, the group's current focus is on compile-time reflection. This is because the design of compile-time reflection features will likely influence the requirements for run-time reflection features.
This call for proposals in open ended; there is no cut-off date. As a practical matter, the committee has recently stopped accepting new features for the next revision of the language (tentatively C++14), and so the next year is a particularly good time to propose features that are targeted at inclusion in the following revision of the language (tentatively C++17).
The study group welcomes proposals either with or without formal standard wording (often known as "standardese"). Proposals may consist of core language extensions, both core language and library extensions or (where possible) pure library extensions.
The reflection study group has identified four broad areas where reflection would be useful in C++, and for each area a representative use-case has been chosen; these use-cases are outlined below.
In order to facilitate comparison, proposals submitted to the reflection study group are encouraged to use one or more of these use cases to demonstrate the features they are proposing, in preference to similar use-cases from the same area.
These areas, and their corresponding representative use-cases, are as follows:
Representative use case: generating equality operators
There are many functions that generally consist of boilerplate code, performing some action for each member of a class. Such functions include equality operators, comparison operators, serialization functions, hash functions and swap functions.
SG7 would like to see proposals for reflection functionality that would allow users to avoid writing repetitive code to implement functions such as these.
Representative use case: Struct-of-Arrays vector (see below)
There are also cases where it is useful to synthesize a new type based on the contents of an existing class. Examples of this include class mocking, creating delegates, parallel class hierarchies and the Struct-of-Arrays vector (SoA vector).
In typical C++ code, an ordered collection of instances of a struct
'S
' would be declared using
std::vector<S> s_vec;
. This is quick and convenient, but in
some applications it can lead to significantly worse performance than the
CPU is capable of, particularly in vectorized loops over the container. These
performance problems are a consequence of the "array of structs" data layout
used by std::vector<S>
[BrumerNCPaM].
Instead of allocating one array containing instances of S
, a
SoA vector of S
would contain one array for each of
S
' members, creating a data layout similar to
SoA_vector_of_S
below.
struct S { int a; int b; int c; };
struct SoA_vector_of_S { std::vector<int> as; std::vector<int> bs; std::vector<int> cs; };
Whilst having the container's data laid out like this is desirable for
performance, the interface that SoA_vector_of_S
provides is not
as user-friendly as std::vector
's. Ideally, a reflection-based
SoA vector implementation would implement the same API as
std::vector
, as far as is possible.
Representative use case: replacing assert
We would like to be able to define functions that have access to the information about the compile-time context of the caller, e.g. the file name, line number, and the name of the calling function.
Today, there is no way to implement a useful assert
function in
C++ without preprocessor macros, because __FILE__
,
__LINE__
and friends are the only way of obtaining compile-time
context information. This is problematic for any library wishing to provide a
customized assertion function, since they must introduce a new macro name and
risk name collisions with their users' code.
This use-case is not limited to replacing the assert
macro with
an exact replica; proposals that improve upon the diagnostic information that
assert
provides are welcome.
Representative use case: enumerating enums
Besides class members (see above), there are many entities in C++ that it would be useful to enumerate at compile time, such as:
There have been many attempts to write a good "enhanced enum" library such as [HusseEnum], which provide extra features such as enum-to-string conversion, string-to-enum conversion and checked int-to-enum conversion. These libraries generally rely on preprocessor magic to achieve their goals, requiring users to write their enums with using unfamiliar syntax.
Ideally, proposals in this area would make it possible to implement an "enhanced enum" without intrusive syntax changes to the declaration of enums.
The Standard C++ Foundation has a page on their website that provides general guidance on submitting a proposal. However, where the isocpp.org guidance mentions posting to the std-proposals forum, please use the reflection mailing list (reflection@isocpp.org) instead of the std-proposals for discussion of ideas and submission of initial proposals in response to this call for proposals. The reflection mailing list both is open to the public and has a public archive, but you must join the list before posting to it. To join, either visit the google groups page or send a blank email to reflection+subscribe@isocpp.org.