mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Give clearer names to template parameters
This commit is contained in:
@@ -71,6 +71,7 @@ Language: Cpp
|
|||||||
MaxEmptyLinesToKeep: 1
|
MaxEmptyLinesToKeep: 1
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
PPIndentWidth: -1
|
PPIndentWidth: -1
|
||||||
|
PenaltyBreakScopeResolution: 1000
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
QualifierAlignment: Right
|
QualifierAlignment: Right
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
|
|||||||
@@ -25,15 +25,15 @@ extern Tracing tracing;
|
|||||||
|
|
||||||
bool trace_ParseTraceDepth(char const *arg);
|
bool trace_ParseTraceDepth(char const *arg);
|
||||||
|
|
||||||
template<typename T, typename M, typename N>
|
template<typename NodeT, typename NameFnT, typename LineNoFnT>
|
||||||
void trace_PrintBacktrace(std::vector<T> const &stack, M getName, N getLineNo) {
|
void trace_PrintBacktrace(std::vector<NodeT> const &stack, NameFnT getName, LineNoFnT getLineNo) {
|
||||||
size_t n = stack.size();
|
size_t n = stack.size();
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return; // LCOV_EXCL_LINE
|
return; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
|
|
||||||
auto printLocation = [&](size_t i) {
|
auto printLocation = [&](size_t i) {
|
||||||
T const &item = stack[n - i - 1];
|
NodeT const &item = stack[n - i - 1];
|
||||||
style_Reset(stderr);
|
style_Reset(stderr);
|
||||||
if (!tracing.collapse) {
|
if (!tracing.collapse) {
|
||||||
fputs(" ", stderr); // Just three spaces; the fourth will be printed next
|
fputs(" ", stderr); // Just three spaces; the fourth will be printed next
|
||||||
|
|||||||
@@ -30,35 +30,35 @@ struct WarningState {
|
|||||||
|
|
||||||
std::pair<WarningState, std::optional<uint32_t>> getInitialWarningState(std::string &flag);
|
std::pair<WarningState, std::optional<uint32_t>> getInitialWarningState(std::string &flag);
|
||||||
|
|
||||||
template<typename L>
|
template<typename LevelEnumT>
|
||||||
struct WarningFlag {
|
struct WarningFlag {
|
||||||
char const *name;
|
char const *name;
|
||||||
L level;
|
LevelEnumT level;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WarningBehavior { DISABLED, ENABLED, ERROR };
|
enum WarningBehavior { DISABLED, ENABLED, ERROR };
|
||||||
|
|
||||||
template<typename W>
|
template<typename WarningEnumT>
|
||||||
struct ParamWarning {
|
struct ParamWarning {
|
||||||
W firstID;
|
WarningEnumT firstID;
|
||||||
W lastID;
|
WarningEnumT lastID;
|
||||||
uint8_t defaultLevel;
|
uint8_t defaultLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename W>
|
template<typename WarningEnumT>
|
||||||
struct DiagnosticsState {
|
struct DiagnosticsState {
|
||||||
WarningState flagStates[W::NB_WARNINGS];
|
WarningState flagStates[WarningEnumT::NB_WARNINGS];
|
||||||
WarningState metaStates[W::NB_WARNINGS];
|
WarningState metaStates[WarningEnumT::NB_WARNINGS];
|
||||||
bool warningsEnabled = true;
|
bool warningsEnabled = true;
|
||||||
bool warningsAreErrors = false;
|
bool warningsAreErrors = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename L, typename W>
|
template<typename LevelEnumT, typename WarningEnumT>
|
||||||
struct Diagnostics {
|
struct Diagnostics {
|
||||||
std::vector<WarningFlag<L>> metaWarnings;
|
std::vector<WarningFlag<LevelEnumT>> metaWarnings;
|
||||||
std::vector<WarningFlag<L>> warningFlags;
|
std::vector<WarningFlag<LevelEnumT>> warningFlags;
|
||||||
std::vector<ParamWarning<W>> paramWarnings;
|
std::vector<ParamWarning<WarningEnumT>> paramWarnings;
|
||||||
DiagnosticsState<W> state;
|
DiagnosticsState<WarningEnumT> state;
|
||||||
uint64_t nbErrors;
|
uint64_t nbErrors;
|
||||||
|
|
||||||
void incrementErrors() {
|
void incrementErrors() {
|
||||||
@@ -67,12 +67,12 @@ struct Diagnostics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WarningBehavior getWarningBehavior(W id) const;
|
WarningBehavior getWarningBehavior(WarningEnumT id) const;
|
||||||
void processWarningFlag(char const *flag);
|
void processWarningFlag(char const *flag);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename L, typename W>
|
template<typename LevelEnumT, typename WarningEnumT>
|
||||||
WarningBehavior Diagnostics<L, W>::getWarningBehavior(W id) const {
|
WarningBehavior Diagnostics<LevelEnumT, WarningEnumT>::getWarningBehavior(WarningEnumT id) const {
|
||||||
// Check if warnings are globally disabled
|
// Check if warnings are globally disabled
|
||||||
if (!state.warningsEnabled) {
|
if (!state.warningsEnabled) {
|
||||||
return WarningBehavior::DISABLED;
|
return WarningBehavior::DISABLED;
|
||||||
@@ -112,7 +112,7 @@ WarningBehavior Diagnostics<L, W>::getWarningBehavior(W id) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If no meta flag is specified, check the default state of this warning flag
|
// If no meta flag is specified, check the default state of this warning flag
|
||||||
if (warningFlags[id].level == L::LEVEL_DEFAULT) { // enabled by default
|
if (warningFlags[id].level == LevelEnumT::LEVEL_DEFAULT) { // enabled by default
|
||||||
return enabledBehavior;
|
return enabledBehavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +120,8 @@ WarningBehavior Diagnostics<L, W>::getWarningBehavior(W id) const {
|
|||||||
return WarningBehavior::DISABLED;
|
return WarningBehavior::DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename L, typename W>
|
template<typename LevelEnumT, typename WarningEnumT>
|
||||||
void Diagnostics<L, W>::processWarningFlag(char const *flag) {
|
void Diagnostics<LevelEnumT, WarningEnumT>::processWarningFlag(char const *flag) {
|
||||||
std::string rootFlag = flag;
|
std::string rootFlag = flag;
|
||||||
|
|
||||||
// Check for `-Werror` or `-Wno-error` to return early
|
// Check for `-Werror` or `-Wno-error` to return early
|
||||||
@@ -140,8 +140,8 @@ void Diagnostics<L, W>::processWarningFlag(char const *flag) {
|
|||||||
// Try to match the flag against a parametric warning
|
// Try to match the flag against a parametric warning
|
||||||
// If there was an equals sign, it will have set `param`; if not, `param` will be 0,
|
// If there was an equals sign, it will have set `param`; if not, `param` will be 0,
|
||||||
// which applies to all levels
|
// which applies to all levels
|
||||||
for (ParamWarning<W> const ¶mWarning : paramWarnings) {
|
for (ParamWarning<WarningEnumT> const ¶mWarning : paramWarnings) {
|
||||||
W baseID = paramWarning.firstID;
|
WarningEnumT baseID = paramWarning.firstID;
|
||||||
uint8_t maxParam = paramWarning.lastID - baseID + 1;
|
uint8_t maxParam = paramWarning.lastID - baseID + 1;
|
||||||
assume(paramWarning.defaultLevel <= maxParam);
|
assume(paramWarning.defaultLevel <= maxParam);
|
||||||
|
|
||||||
@@ -183,13 +183,13 @@ void Diagnostics<L, W>::processWarningFlag(char const *flag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to match against a "meta" warning
|
// Try to match against a "meta" warning
|
||||||
for (WarningFlag<L> const &metaWarning : metaWarnings) {
|
for (WarningFlag<LevelEnumT> const &metaWarning : metaWarnings) {
|
||||||
if (rootFlag != metaWarning.name) {
|
if (rootFlag != metaWarning.name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set each of the warning flags that meets this level
|
// Set each of the warning flags that meets this level
|
||||||
for (W id : EnumSeq(W::NB_WARNINGS)) {
|
for (WarningEnumT id : EnumSeq(WarningEnumT::NB_WARNINGS)) {
|
||||||
if (metaWarning.level >= warningFlags[id].level) {
|
if (metaWarning.level >= warningFlags[id].level) {
|
||||||
state.metaStates[id].update(flagState);
|
state.metaStates[id].update(flagState);
|
||||||
}
|
}
|
||||||
@@ -198,7 +198,7 @@ void Diagnostics<L, W>::processWarningFlag(char const *flag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to match against a "normal" flag
|
// Try to match against a "normal" flag
|
||||||
for (W id : EnumSeq(W::NB_PLAIN_WARNINGS)) {
|
for (WarningEnumT id : EnumSeq(WarningEnumT::NB_PLAIN_WARNINGS)) {
|
||||||
if (rootFlag == warningFlags[id].name) {
|
if (rootFlag == warningFlags[id].name) {
|
||||||
state.flagStates[id].update(flagState);
|
state.flagStates[id].update(flagState);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -100,16 +100,16 @@ static inline int clz(unsigned int x) {
|
|||||||
#define RRANGE(s) std::rbegin(s), std::rend(s)
|
#define RRANGE(s) std::rbegin(s), std::rend(s)
|
||||||
|
|
||||||
// MSVC does not inline `strlen()` or `.length()` of a constant string
|
// MSVC does not inline `strlen()` or `.length()` of a constant string
|
||||||
template<int N>
|
template<int SizeOfString>
|
||||||
static constexpr int literal_strlen(char const (&)[N]) {
|
static constexpr int literal_strlen(char const (&)[SizeOfString]) {
|
||||||
return N - 1;
|
return SizeOfString - 1; // Don't count the ending '\0'
|
||||||
}
|
}
|
||||||
|
|
||||||
// For ad-hoc RAII in place of a `defer` statement or cross-platform `__attribute__((cleanup))`
|
// For ad-hoc RAII in place of a `defer` statement or cross-platform `__attribute__((cleanup))`
|
||||||
template<typename T>
|
template<typename DeferredFnT>
|
||||||
struct Defer {
|
struct Defer {
|
||||||
T deferred;
|
DeferredFnT deferred;
|
||||||
Defer(T func) : deferred(func) {}
|
Defer(DeferredFnT func) : deferred(func) {}
|
||||||
~Defer() { deferred(); }
|
~Defer() { deferred(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -12,29 +12,31 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
template<typename T>
|
// A wrapper around iterables to reverse their iteration order; used in `for`-each loops.
|
||||||
|
template<typename IterableT>
|
||||||
struct ReversedIterable {
|
struct ReversedIterable {
|
||||||
T &_iterable;
|
IterableT &_iterable;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename IterableT>
|
||||||
auto begin(ReversedIterable<T> r) {
|
auto begin(ReversedIterable<IterableT> r) {
|
||||||
return std::rbegin(r._iterable);
|
return std::rbegin(r._iterable);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename IterableT>
|
||||||
auto end(ReversedIterable<T> r) {
|
auto end(ReversedIterable<IterableT> r) {
|
||||||
return std::rend(r._iterable);
|
return std::rend(r._iterable);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename IterableT>
|
||||||
ReversedIterable<T> reversed(T &&_iterable) {
|
ReversedIterable<IterableT> reversed(IterableT &&_iterable) {
|
||||||
return {_iterable};
|
return {_iterable};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
// A map from `std::string` keys to `ItemT` items, iterable in the order the items were inserted.
|
||||||
|
template<typename ItemT>
|
||||||
class InsertionOrderedMap {
|
class InsertionOrderedMap {
|
||||||
std::deque<T> list;
|
std::deque<ItemT> list;
|
||||||
std::unordered_map<std::string, size_t> map; // Indexes into `list`
|
std::unordered_map<std::string, size_t> map; // Indexes into `list`
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -44,25 +46,25 @@ public:
|
|||||||
|
|
||||||
bool contains(std::string const &name) const { return map.find(name) != map.end(); }
|
bool contains(std::string const &name) const { return map.find(name) != map.end(); }
|
||||||
|
|
||||||
T &operator[](size_t i) { return list[i]; }
|
ItemT &operator[](size_t i) { return list[i]; }
|
||||||
|
|
||||||
typename decltype(list)::iterator begin() { return list.begin(); }
|
typename decltype(list)::iterator begin() { return list.begin(); }
|
||||||
typename decltype(list)::iterator end() { return list.end(); }
|
typename decltype(list)::iterator end() { return list.end(); }
|
||||||
typename decltype(list)::const_iterator begin() const { return list.begin(); }
|
typename decltype(list)::const_iterator begin() const { return list.begin(); }
|
||||||
typename decltype(list)::const_iterator end() const { return list.end(); }
|
typename decltype(list)::const_iterator end() const { return list.end(); }
|
||||||
|
|
||||||
T &add(std::string const &name) {
|
ItemT &add(std::string const &name) {
|
||||||
map[name] = list.size();
|
map[name] = list.size();
|
||||||
return list.emplace_back();
|
return list.emplace_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
T &add(std::string const &name, T &&value) {
|
ItemT &add(std::string const &name, ItemT &&value) {
|
||||||
map[name] = list.size();
|
map[name] = list.size();
|
||||||
list.emplace_back(std::move(value));
|
list.emplace_back(std::move(value));
|
||||||
return list.back();
|
return list.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
T &addAnonymous() {
|
ItemT &addAnonymous() {
|
||||||
// Add the new item to the list, but do not update the map
|
// Add the new item to the list, but do not update the map
|
||||||
return list.emplace_back();
|
return list.emplace_back();
|
||||||
}
|
}
|
||||||
@@ -75,43 +77,45 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
// An iterable of `enum` values in the half-open range [start, stop).
|
||||||
|
template<typename EnumT>
|
||||||
class EnumSeq {
|
class EnumSeq {
|
||||||
T _start;
|
EnumT _start;
|
||||||
T _stop;
|
EnumT _stop;
|
||||||
|
|
||||||
class Iterator {
|
class Iterator {
|
||||||
T _value;
|
EnumT _value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Iterator(T value) : _value(value) {}
|
explicit Iterator(EnumT value) : _value(value) {}
|
||||||
|
|
||||||
Iterator &operator++() {
|
Iterator &operator++() {
|
||||||
_value = static_cast<T>(_value + 1);
|
_value = static_cast<EnumT>(_value + 1);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator*() const { return _value; }
|
EnumT operator*() const { return _value; }
|
||||||
|
|
||||||
bool operator==(Iterator const &rhs) const { return _value == rhs._value; }
|
bool operator==(Iterator const &rhs) const { return _value == rhs._value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit EnumSeq(T stop) : _start(static_cast<T>(0)), _stop(stop) {}
|
explicit EnumSeq(EnumT stop) : _start(static_cast<EnumT>(0)), _stop(stop) {}
|
||||||
explicit EnumSeq(T start, T stop) : _start(start), _stop(stop) {}
|
explicit EnumSeq(EnumT start, EnumT stop) : _start(start), _stop(stop) {}
|
||||||
|
|
||||||
Iterator begin() { return Iterator(_start); }
|
Iterator begin() { return Iterator(_start); }
|
||||||
Iterator end() { return Iterator(_stop); }
|
Iterator end() { return Iterator(_stop); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Only needed inside `ZipContainer` below.
|
||||||
// This is not a fully generic implementation; its current use cases only require for-loop behavior.
|
// This is not a fully generic implementation; its current use cases only require for-loop behavior.
|
||||||
// We also assume that all iterators have the same length.
|
// We also assume that all iterators have the same length.
|
||||||
template<typename... Ts>
|
template<typename... IteratorTs>
|
||||||
class ZipIterator {
|
class ZipIterator {
|
||||||
std::tuple<Ts...> _iters;
|
std::tuple<IteratorTs...> _iters;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ZipIterator(std::tuple<Ts...> &&iters) : _iters(iters) {}
|
explicit ZipIterator(std::tuple<IteratorTs...> &&iters) : _iters(iters) {}
|
||||||
|
|
||||||
ZipIterator &operator++() {
|
ZipIterator &operator++() {
|
||||||
std::apply([](auto &&...it) { (++it, ...); }, _iters);
|
std::apply([](auto &&...it) { (++it, ...); }, _iters);
|
||||||
@@ -129,12 +133,14 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Ts>
|
// Only needed inside `zip` below.
|
||||||
|
template<typename... IterableTs>
|
||||||
class ZipContainer {
|
class ZipContainer {
|
||||||
std::tuple<Ts...> _containers;
|
std::tuple<IterableTs...> _containers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ZipContainer(Ts &&...containers) : _containers(std::forward<Ts>(containers)...) {}
|
explicit ZipContainer(IterableTs &&...containers)
|
||||||
|
: _containers(std::forward<IterableTs>(containers)...) {}
|
||||||
|
|
||||||
auto begin() {
|
auto begin() {
|
||||||
return ZipIterator(std::apply(
|
return ZipIterator(std::apply(
|
||||||
@@ -157,15 +163,19 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Only needed inside `zip` below.
|
||||||
// Take ownership of objects and rvalue refs passed to us, but not lvalue refs
|
// Take ownership of objects and rvalue refs passed to us, but not lvalue refs
|
||||||
template<typename T>
|
template<typename IterableT>
|
||||||
using Holder = std::
|
using ZipHolder = std::conditional_t<
|
||||||
conditional_t<std::is_lvalue_reference_v<T>, T, std::remove_cv_t<std::remove_reference_t<T>>>;
|
std::is_lvalue_reference_v<IterableT>,
|
||||||
|
IterableT,
|
||||||
|
std::remove_cv_t<std::remove_reference_t<IterableT>>>;
|
||||||
|
|
||||||
|
// Iterates over N containers at once, yielding tuples of N items at a time.
|
||||||
// Does the same number of iterations as the first container's iterator!
|
// Does the same number of iterations as the first container's iterator!
|
||||||
template<typename... Ts>
|
template<typename... IterableTs>
|
||||||
static constexpr auto zip(Ts &&...cs) {
|
static constexpr auto zip(IterableTs &&...containers) {
|
||||||
return ZipContainer<Holder<Ts>...>(std::forward<Ts>(cs)...);
|
return ZipContainer<ZipHolder<IterableTs>...>(std::forward<IterableTs>(containers)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // RGBDS_ITERTOOLS_HPP
|
#endif // RGBDS_ITERTOOLS_HPP
|
||||||
|
|||||||
@@ -52,28 +52,28 @@ struct Section {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Template class for both const and non-const iterators over the "pieces" of this section
|
// Template class for both const and non-const iterators over the "pieces" of this section
|
||||||
template<typename T>
|
template<typename SectionT>
|
||||||
class PiecesIterable {
|
class PiecesIterable {
|
||||||
T *_firstPiece;
|
SectionT *_firstPiece;
|
||||||
|
|
||||||
class Iterator {
|
class Iterator {
|
||||||
T *_piece;
|
SectionT *_piece;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Iterator(T *piece) : _piece(piece) {}
|
explicit Iterator(SectionT *piece) : _piece(piece) {}
|
||||||
|
|
||||||
Iterator &operator++() {
|
Iterator &operator++() {
|
||||||
_piece = _piece->nextPiece.get();
|
_piece = _piece->nextPiece.get();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
T &operator*() const { return *_piece; }
|
SectionT &operator*() const { return *_piece; }
|
||||||
|
|
||||||
bool operator==(Iterator const &rhs) const { return _piece == rhs._piece; }
|
bool operator==(Iterator const &rhs) const { return _piece == rhs._piece; }
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PiecesIterable(T *firstPiece) : _firstPiece(firstPiece) {}
|
explicit PiecesIterable(SectionT *firstPiece) : _firstPiece(firstPiece) {}
|
||||||
|
|
||||||
Iterator begin() { return Iterator(_firstPiece); }
|
Iterator begin() { return Iterator(_firstPiece); }
|
||||||
Iterator end() { return Iterator(nullptr); }
|
Iterator end() { return Iterator(nullptr); }
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ struct Uppercase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
// An unordered map from case-insensitive `std::string` keys to `ItemT` items
|
||||||
using UpperMap = std::unordered_map<std::string, T, Uppercase, Uppercase>;
|
template<typename ItemT>
|
||||||
|
using UpperMap = std::unordered_map<std::string, ItemT, Uppercase, Uppercase>;
|
||||||
|
|
||||||
#endif // RGBDS_UTIL_HPP
|
#endif // RGBDS_UTIL_HPP
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ struct Charmap {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Traverse the trie depth-first to derive the character mappings in definition order
|
// Traverse the trie depth-first to derive the character mappings in definition order
|
||||||
template<typename F>
|
template<typename CallbackFnT>
|
||||||
bool forEachChar(Charmap const &charmap, F callback) {
|
bool forEachChar(Charmap const &charmap, CallbackFnT callback) {
|
||||||
// clang-format off: nested initializers
|
// clang-format off: nested initializers
|
||||||
for (std::stack<std::pair<size_t, std::string>> prefixes({{0, ""}}); !prefixes.empty();) {
|
for (std::stack<std::pair<size_t, std::string>> prefixes({{0, ""}}); !prefixes.empty();) {
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|||||||
@@ -816,8 +816,8 @@ static int nextChar() {
|
|||||||
return peek();
|
return peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename P>
|
template<typename PredicateFnT>
|
||||||
static int skipChars(P predicate) {
|
static int skipChars(PredicateFnT predicate) {
|
||||||
int c = peek();
|
int c = peek();
|
||||||
while (predicate(c)) {
|
while (predicate(c)) {
|
||||||
c = nextChar();
|
c = nextChar();
|
||||||
@@ -2281,8 +2281,8 @@ yy::parser::symbol_type yylex() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename CallbackFnT>
|
||||||
static Capture makeCapture(char const *name, F callback) {
|
static Capture makeCapture(char const *name, CallbackFnT callback) {
|
||||||
// Due to parser internals, it reads the EOL after the expression before calling this.
|
// 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.
|
// Thus, we don't need to keep one in the buffer afterwards.
|
||||||
// The following assumption checks that.
|
// The following assumption checks that.
|
||||||
|
|||||||
@@ -57,8 +57,10 @@
|
|||||||
|
|
||||||
yy::parser::symbol_type yylex(); // Provided by lexer.cpp
|
yy::parser::symbol_type yylex(); // Provided by lexer.cpp
|
||||||
|
|
||||||
template <typename N, typename S>
|
template<typename NumCallbackFnT, typename StrCallbackFnT>
|
||||||
static auto handleSymbolByType(std::string const &symName, N numCallback, S strCallback) {
|
static auto handleSymbolByType(
|
||||||
|
std::string const &symName, NumCallbackFnT numCallback, StrCallbackFnT strCallback
|
||||||
|
) {
|
||||||
if (Symbol *sym = sym_FindScopedSymbol(symName); sym && sym->type == SYM_EQUS) {
|
if (Symbol *sym = sym_FindScopedSymbol(symName); sym && sym->type == SYM_EQUS) {
|
||||||
return strCallback(*sym->getEqus());
|
return strCallback(*sym->getEqus());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Template class for both const and non-const iterators over the non-empty `_assigned` slots
|
// Template class for both const and non-const iterators over the non-empty `_assigned` slots
|
||||||
template<typename I, template<typename> typename Constness>
|
template<typename IteratorT, template<typename> typename Constness>
|
||||||
class AssignedSetsIter {
|
class AssignedSetsIter {
|
||||||
public:
|
public:
|
||||||
friend class AssignedSets;
|
friend class AssignedSets;
|
||||||
@@ -84,7 +84,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Constness<decltype(_assigned)> *_array = nullptr;
|
Constness<decltype(_assigned)> *_array = nullptr;
|
||||||
I _iter{};
|
IteratorT _iter{};
|
||||||
|
|
||||||
AssignedSetsIter(decltype(_array) array, decltype(_iter) &&iter)
|
AssignedSetsIter(decltype(_array) array, decltype(_iter) &&iter)
|
||||||
: _array(array), _iter(iter) {}
|
: _array(array), _iter(iter) {}
|
||||||
@@ -164,11 +164,11 @@ public:
|
|||||||
size_t nbColorSets() const { return std::distance(RANGE(*this)); }
|
size_t nbColorSets() const { return std::distance(RANGE(*this)); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename I>
|
template<typename IteratorT>
|
||||||
static void addUniqueColors(
|
static void addUniqueColors(
|
||||||
std::unordered_set<uint16_t> &colors,
|
std::unordered_set<uint16_t> &colors,
|
||||||
I iter,
|
IteratorT iter,
|
||||||
I const &end,
|
IteratorT const &end,
|
||||||
std::vector<ColorSet> const &colorSets
|
std::vector<ColorSet> const &colorSets
|
||||||
) {
|
) {
|
||||||
for (; iter != end; ++iter) {
|
for (; iter != end; ++iter) {
|
||||||
@@ -240,18 +240,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Computes the "relative size" of a set of color sets on this palette
|
// Computes the "relative size" of a set of color sets on this palette
|
||||||
template<typename I>
|
template<typename IteratorT>
|
||||||
size_t combinedVolume(I &&begin, I const &end, std::vector<ColorSet> const &colorSets) const {
|
size_t combinedVolume(
|
||||||
|
IteratorT &&begin, IteratorT const &end, std::vector<ColorSet> const &colorSets
|
||||||
|
) const {
|
||||||
std::unordered_set<uint16_t> &colors = uniqueColors();
|
std::unordered_set<uint16_t> &colors = uniqueColors();
|
||||||
addUniqueColors(colors, std::forward<I>(begin), end, colorSets);
|
addUniqueColors(colors, std::forward<IteratorT>(begin), end, colorSets);
|
||||||
return colors.size();
|
return colors.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computes the "relative size" of a set of colors on this palette
|
// Computes the "relative size" of a set of colors on this palette
|
||||||
template<typename I>
|
template<typename IteratorT>
|
||||||
size_t combinedVolume(I &&begin, I &&end) const {
|
size_t combinedVolume(IteratorT &&begin, IteratorT &&end) const {
|
||||||
std::unordered_set<uint16_t> &colors = uniqueColors();
|
std::unordered_set<uint16_t> &colors = uniqueColors();
|
||||||
colors.insert(std::forward<I>(begin), std::forward<I>(end));
|
colors.insert(std::forward<IteratorT>(begin), std::forward<IteratorT>(end));
|
||||||
return colors.size();
|
return colors.size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -210,15 +210,15 @@ static void warnExtraColors(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parses the initial part of a string_view, advancing the "read index" as it does
|
// Parses the initial part of a string_view, advancing the "read index" as it does
|
||||||
template<typename U> // Should be uint*_t
|
template<typename UintT> // Should be uint*_t
|
||||||
static std::optional<U> parseDec(std::string const &str, size_t &n) {
|
static std::optional<UintT> parseDec(std::string const &str, size_t &n) {
|
||||||
uintmax_t value = 0;
|
uintmax_t value = 0;
|
||||||
auto result = std::from_chars(str.data() + n, str.data() + str.length(), value);
|
auto result = std::from_chars(str.data() + n, str.data() + str.length(), value);
|
||||||
if (static_cast<bool>(result.ec)) {
|
if (static_cast<bool>(result.ec)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
n = result.ptr - str.data();
|
n = result.ptr - str.data();
|
||||||
return std::optional<U>{value};
|
return std::optional<UintT>{value};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<Rgba> parseColor(std::string const &str, size_t &n, uint16_t i) {
|
static std::optional<Rgba> parseColor(std::string const &str, size_t &n, uint16_t i) {
|
||||||
|
|||||||
@@ -314,8 +314,8 @@ static bool compareSymbols(SortedSymbol const &sym1, SortedSymbol const &sym2) {
|
|||||||
< std::tie(sym2.addr, sym2_local, sym2.parentAddr, sym2_name);
|
< std::tie(sym2.addr, sym2_local, sym2.parentAddr, sym2_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename CallbackFnT>
|
||||||
static void forEachSortedSection(SortedSections const &bankSections, F callback) {
|
static void forEachSortedSection(SortedSections const &bankSections, CallbackFnT callback) {
|
||||||
for (Section const *sect : bankSections.zeroLenSections) {
|
for (Section const *sect : bankSections.zeroLenSections) {
|
||||||
for (Section const &piece : sect->pieces()) {
|
for (Section const &piece : sect->pieces()) {
|
||||||
callback(piece);
|
callback(piece);
|
||||||
@@ -415,8 +415,8 @@ static void writeSectionName(std::string const &name, FILE *file) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename CallbackFnT>
|
||||||
uint16_t forEachSection(SortedSections const §List, F callback) {
|
uint16_t forEachSection(SortedSections const §List, CallbackFnT callback) {
|
||||||
uint16_t used = 0;
|
uint16_t used = 0;
|
||||||
auto section = sectList.sections.begin();
|
auto section = sectList.sections.begin();
|
||||||
auto zeroLenSection = sectList.zeroLenSections.begin();
|
auto zeroLenSection = sectList.zeroLenSections.begin();
|
||||||
|
|||||||
Reference in New Issue
Block a user