Skip to content

Commit

Permalink
Fix examples, add ce links
Browse files Browse the repository at this point in the history
  • Loading branch information
cor3ntin committed Oct 26, 2023
1 parent 6a1fdc1 commit 45cc7eb
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 23 deletions.
72 changes: 70 additions & 2 deletions src/D2841.tex
Original file line number Diff line number Diff line change
Expand Up @@ -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]}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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},
Expand Down
63 changes: 42 additions & 21 deletions src/D2989.tex
Original file line number Diff line number Diff line change
Expand Up @@ -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]}
Expand All @@ -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}.
Expand Down Expand Up @@ -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...>;
};
Expand All @@ -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 :
Expand Down Expand Up @@ -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<
Expand All @@ -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}.
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.

Expand Down

0 comments on commit 45cc7eb

Please sign in to comment.