Use C++20 concepts to require constraints on template parameters (#1977)

This commit is contained in:
Rangi
2026-05-22 17:54:34 -04:00
committed by GitHub
parent 728bed39d5
commit dce14fd4b8
12 changed files with 64 additions and 27 deletions
+4 -2
View File
@@ -3,6 +3,7 @@
#include "asm/charmap.hpp"
#include <algorithm>
#include <concepts> // predicate
#include <map>
#include <optional>
#include <stack>
@@ -65,8 +66,9 @@ struct Charmap {
};
// Traverse the trie depth-first to derive the character mappings in definition order
template<typename CallbackFnT>
bool forEachChar(Charmap const &charmap, CallbackFnT callback) {
bool forEachChar(
Charmap const &charmap, std::predicate<size_t, std::string const &> auto callback
) {
// clang-format off: nested initializers
for (std::stack<std::pair<size_t, std::string>> prefixes({{0, ""}}); !prefixes.empty();) {
// clang-format on
+5 -4
View File
@@ -4,6 +4,7 @@
#include <sys/stat.h>
#include <algorithm>
#include <concepts> // predicate
#include <errno.h>
#include <fcntl.h>
#include <fstream>
@@ -527,6 +528,7 @@ static void shiftChar();
static int bumpChar();
static int nextChar();
template<uint32_t Base>
requires BaseV<Base>
static uint32_t readNumber(int initial, char const *prefix);
static uint32_t readBracketedMacroArgNum() {
@@ -818,8 +820,7 @@ static int nextChar() {
return peek();
}
template<typename PredicateFnT>
static int skipChars(PredicateFnT predicate) {
static int skipChars(std::predicate<int> auto predicate) {
int c = peek();
while (predicate(c)) {
c = nextChar();
@@ -1099,6 +1100,7 @@ void lexer_SetGfxDigits(char const digits[4]) {
}
template<uint32_t Base>
requires BaseV<Base>
static uint32_t readNumber(int initial, char const *prefix) {
auto isSomeDigit = [](int c) {
if constexpr (Base == 2) {
@@ -2283,8 +2285,7 @@ yy::parser::symbol_type yylex() {
}
}
template<typename CallbackFnT>
static Capture makeCapture(char const *name, CallbackFnT callback) {
static Capture makeCapture(char const *name, InvocableR<int, int> auto callback) {
// Due to parser internals, it reads the EOL after the expression before calling this.
// Thus, we don't need to keep one in the buffer afterwards.
// The following assumption checks that.
+4 -2
View File
@@ -32,6 +32,7 @@
%code {
#include <algorithm>
#include <concepts> // invocable
#include <inttypes.h>
#include <optional>
#include <stdio.h>
@@ -57,9 +58,10 @@
yy::parser::symbol_type yylex(); // Provided by lexer.cpp
template<typename NumCallbackFnT, typename StrCallbackFnT>
static auto handleSymbolByType(
std::string const &symName, NumCallbackFnT numCallback, StrCallbackFnT strCallback
std::string const &symName,
std::invocable<Expression const &> auto numCallback,
std::invocable<std::string const &> auto strCallback
) {
if (Symbol *sym = sym_FindScopedSymbol(symName); sym && sym->type == SYM_EQUS) {
return strCallback(*sym->getEqus());