-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
112 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
\documentclass{wg21} | ||
|
||
\title{Concept and variable-template template-parameters} | ||
\docnumber{P2841R1} | ||
\docnumber{D2841R2} | ||
\audience{EWG} | ||
\author{Corentin Jabot}{[email protected]} | ||
\authortwo{Gašper Ažman}{[email protected]} | ||
|
@@ -42,6 +42,30 @@ \section{Abstract} | |
|
||
|
||
|
||
\section{Revisions} | ||
|
||
\subsection{R2} | ||
|
||
\begin{itemize} | ||
\item Add a section in the deduction of template parameters from the arguments of a variable template/concept specialization | ||
\end{itemize} | ||
|
||
|
||
\subsection{R1} | ||
|
||
\begin{itemize} | ||
\item Add examples, motivation | ||
\item Wording improvement | ||
\end{itemize} | ||
|
||
\subsection{R0} | ||
|
||
\begin{itemize} | ||
\item{Initial revision} | ||
\end{itemize} | ||
|
||
|
||
|
||
\section{Motivation} | ||
|
||
Template template-parameters allow for higher-order templates and greater composability. | ||
|
@@ -508,6 +532,50 @@ \subsection{Deduction and partial ordering} | |
|
||
[\href{https://compiler-explorer.com/z/66dr6fnKj}{Run this example on Compiler Explorer}] | ||
|
||
\subsection{Deduction of template argument fron the argument lust of a variable template argument} | ||
|
||
This is not proposed. | ||
|
||
Consider: | ||
|
||
\begin{colorblock} | ||
template<template <typename...> auto, auto> | ||
inline constexpr bool is_specialization_of_v = false; | ||
|
||
template< | ||
template <typename...> auto v, | ||
typename... Args | ||
> | ||
inline constexpr bool is_specialization_of_v<v, v<Args...>> = false; // #2 | ||
|
||
template <typename T> | ||
constexpr int i = 42; | ||
|
||
static_assert(is_specialization_of_v<i, i<int>>); // #3 | ||
\end{colorblock} | ||
|
||
\href{https://godbolt.org/z/sqTfEojh4}{[Compiler Explorer]} | ||
|
||
|
||
Should we be able to deduce \tcode{Args} from \tcode{int}? | ||
Some existing implementations will eagerly substitute \tcode{i<int>} by its value (here, \tcode{42}), | ||
such that there is subsequently nothing left to deduce \tcode{Args} against. | ||
|
||
While it would be possible to make that work, the implementation effort is non-negligible and the benefits limited, | ||
as we could only deduce the arguments of entities that are valid template arguments - which sounds obvious but that means that the | ||
above example can only work on a subset of variables (constexpr variables template specialization of structural types). | ||
|
||
We would also need to decide whether \tcode{is_specialization_of_v<i, i<int>>} behaves differently from \tcode{is_specialization_of_v<i, (i<int>)>} | ||
and how that generalizes to arbitrary subexpressions involving variable template specializations. | ||
|
||
So, for now, arguments of variable template template parameter are not deduced. | ||
instead, we should make \#2 ill-formed, so that we have the opportunity to extend that at a later time if we find sufficient motivation for it. | ||
|
||
There are existing cases where we make non-deductible partial specializations ill-formed (see \href{https://eel.is/c++draft/temp.spec.partial#match-3}{[temp.spec.partial.match])}, | ||
howevever in the general case we don't seem to (\href{https://gcc.godbolt.org/z/fv1e8nnsf}{for example here is an exampler with a non-deducible pack}) | ||
|
||
|
||
|
||
\subsection{Equivalence of atomic constraints} | ||
|
||
One interesting concept to consider is \tcode{tuple_of}, which would e.g., allow constraining a function on a \placeholder{tuple-like} | ||
|
@@ -692,7 +760,7 @@ \section{Wording} | |
\item | ||
\grammarterm{parameter-declaration} \iref{dcl.fct}, | ||
\item | ||
\grammarterm{type-parameter} \iref{temp.param},\textbf{} | ||
\grammarterm{type-parameter} \iref{temp.param}, | ||
\begin{addedblock} | ||
\item | ||
\grammarterm{template-template-parameter} \iref{temp.param}, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
\documentclass{wg21} | ||
|
||
\title{A Simple Approach to Universal Template Parameters} | ||
\docnumber{P2989R0} | ||
\docnumber{D2989R1} | ||
\audience{EWG} | ||
\author{Corentin Jabot}{[email protected]} | ||
\authortwo{Gašper Ažman}{[email protected]} | ||
|
@@ -25,6 +25,23 @@ \section{Abstract} | |
We proposed allowing the use of universal template parameters in all contexts, which would have added a large amount of complexity to both the specification and implementations | ||
for limited benefits. In this paper, we propose a much simpler approach to the same feature. | ||
|
||
|
||
\section{Revisions} | ||
|
||
\subsection{R1} | ||
|
||
\begin{itemize} | ||
\item Update the implementation experience | ||
\item Fix code examples and add compiler explorer links | ||
\end{itemize} | ||
|
||
\subsection{R0} | ||
|
||
\begin{itemize} | ||
\item{Initial revision} | ||
\end{itemize} | ||
|
||
|
||
\section{Difference with \paper{P1985R3}} | ||
|
||
This paper is really a follow-up on \paper{P1985R3}. | ||
|
@@ -60,7 +77,10 @@ \subsection{Generic rebind} | |
|
||
|
||
\begin{colorblock} | ||
template <template <class, universal template...> Alloc, class T, universal... Args, class U> | ||
template <typename, typename> | ||
struct rebind_alloc_t; | ||
|
||
template <template <class, universal template...> typename Alloc, class T, universal template... Args, class U> | ||
struct rebind_alloc_t<Alloc<T, Args...>, U> { | ||
using type = Alloc<U, Args...>; | ||
}; | ||
|
@@ -70,9 +90,11 @@ \subsection{Generic rebind} | |
using rebind_alloc = rebind_alloc_t<Alloc, T>::type; | ||
}; | ||
using rebound = allocator_traits<BlockAllocator<int>>::rebind_alloc<long>; // now ok | ||
using rebound = allocator_traits<BlockAllocator<int, 128>>::rebind_alloc<long>; // ok too | ||
using rebound2 = allocator_traits<BlockAllocator<int, 128>>::rebind_alloc<long>; // ok too | ||
\end{colorblock} | ||
|
||
\href{https://gcc.godbolt.org/z/z7n978vdv}{[Demo on compiler explorer]} | ||
|
||
\subsection{\tcode{ranges::to}} | ||
|
||
The code : | ||
|
@@ -250,13 +272,15 @@ \subsection{Library Support: Universal template parameters with \tcode{is}} | |
template <template<universal template...> concept U> | ||
inline constexpr bool is_concept_v<U> = true; | ||
\end{colorblock} | ||
|
||
\href{https://godbolt.org/z/cEfvsaf4j}{[Demo on compiler explorer]} | ||
|
||
The final wording will most likely include support for the non-\tcode{_v} version of these traits. | ||
|
||
We would be remiss if we did not propose \tcode{std::is_specialization_of} (\paper{P2098R1}) here: | ||
|
||
\begin{colorblock} | ||
template<universal template Primary, universal template> | ||
requires is_var_template_v<Primary> || is_type_template_v<Primary> | ||
template<template<universal template...> typename, typename> | ||
inline constexpr bool is_specialization_of_v = false; | ||
|
||
template< | ||
|
@@ -265,17 +289,13 @@ \subsection{Library Support: Universal template parameters with \tcode{is}} | |
> | ||
inline constexpr bool is_specialization_of_v<Primary, Primary<Args...>> = true; | ||
|
||
template< | ||
template<universal template...> auto Primary, | ||
universal template... Args | ||
> | ||
inline constexpr bool is_specialization_of_v<Primary, Primary<Args...>> = true; | ||
|
||
\end{colorblock} | ||
|
||
Unlike \paper{P2098R1}, which was rejected for not being universal enough (the technology did not exist at the time), this implementation not only supports checking | ||
specializations for any class templates, including those having template parameters that are not types, but also specialization of variable templates. | ||
|
||
\href{https://godbolt.org/z/5W47odaK5}{[Demo on compiler explorer]} | ||
|
||
\subsection{In which we mention reflection} | ||
|
||
One of the things we do not propose in this paper is to force the interpretation of a universal template as a specific kind "in place", in contrast with \paper{P1985R3}. | ||
|
@@ -317,6 +337,8 @@ \subsection{In which we mention reflection} | |
static_assert(test<24>() == 24); | ||
\end{colorblock} | ||
|
||
\href{https://godbolt.org/z/oTPGvEYoa}{[Demo on Compiler Explorer]} | ||
|
||
The second reason is that use cases are limited. | ||
We need universal template parameters so we can handle entities of different shapes in generic contexts, by forwarding them to other templates, as illustrated in the examples at the start of this paper. | ||
|
||
|
@@ -368,7 +390,8 @@ \subsection{Syntax} | |
|
||
\begin{itemize} | ||
|
||
\item \tcode{universal template Foo} works (i.e., is not ambiguous). | ||
\item \tcode{universal template Foo} works (i.e., is not ambiguous). \href{https://tinyurl.com/pth8v9p7}{A search for \tcode{\#define universal}} | ||
finds one instance in a no-longer maintained project. | ||
|
||
\item \tcode{template auto} which is the syntax used by circle and \paper{P1985R0} reused \tcode{auto} in inconsistent ways | ||
which we and many others found undesirable. | ||
|
@@ -454,18 +477,16 @@ \subsection{Syntax} | |
|
||
\section{Status of this proposal and implementation} | ||
|
||
The design presented in this paper roughly matches the implementation of universal template parameters in Circle, albeit with a different syntax. | ||
We started a prototype implementation in Clang to demonstrate implementability in a second C++ compiler and discover any interesting design questions we might otherwise | ||
miss. | ||
|
||
The Clang implementation does not support packs or template template parameters, but it does support passing type and nontype template arguments | ||
as arguments to universal parameters, and partial ordering/specialization also generally works. | ||
The design presented in this paper roughly matches the implementation of universal template parameters in Circle (itself inspired by a previous iteration of this proposal), | ||
albeit with a different syntax. | ||
|
||
Introducing a new kind of template parameters/template arguments certainly requires a few weeks of work to acchieve a production-ready implementation, | ||
but Clang has no fundamental limitations that would make this proposal impossible or unreasonable to implement. | ||
We provide a prototype implementation in Clang to demonstrate implementability in a second C++ compiler and discover any interesting design questions we might otherwise | ||
miss. Our implementation compile the examples presented in this paper. However it remains a prototype that is not production ready. | ||
The implementation represented a few weeks of work. The main challenge of bringing this proposal to production ready implementations certainly resides in the | ||
testing of all possible combination of template parameter and arguments. | ||
|
||
|
||
Our aim is to agree on general design and syntax in Kona and then to follow-up in the next few months with a more complete implementation and wording. | ||
Our aim is to agree on general design and syntax in Kona and then to follow-up in the next few months with wording. | ||
We should also progress \paper{P2841R0}, first since we intend for concepts and variable templates to be valid universal template parameters. | ||
There is a better order of operation, especially for ease of specification. | ||
|
||
|