From 810455f1b80959ce096ed8be5c7f3c50b58fc7d9 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Sat, 28 Jun 2025 15:30:43 +0300 Subject: [PATCH] libexpr: Simplify Value::is* methods by introducing isa function template --- src/libexpr/eval.cc | 9 +++--- src/libexpr/include/nix/expr/value.hh | 40 +++++++++++++++++---------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index ae422a3d4..806b506a5 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -125,7 +125,7 @@ std::string showType(const Value & v) // Allow selecting a subset of enum values #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch-enum" - switch (v.internalType) { + switch (v.getInternalType()) { case tString: return v.context() ? "a string with context" : "a string"; case tPrimOp: return fmt("the built-in function '%s'", std::string(v.primOp()->name)); @@ -145,7 +145,7 @@ PosIdx Value::determinePos(const PosIdx pos) const // Allow selecting a subset of enum values #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch-enum" - switch (internalType) { + switch (getInternalType()) { case tAttrs: return attrs()->pos; case tLambda: return lambda().fun->pos; case tApp: return app().left->determinePos(pos); @@ -157,9 +157,8 @@ PosIdx Value::determinePos(const PosIdx pos) const bool Value::isTrivial() const { return - internalType != tApp - && internalType != tPrimOpApp - && (internalType != tThunk + !isa() + && (!isa() || (dynamic_cast(thunk().expr) && ((ExprAttrs *) thunk().expr)->dynamicAttrs.empty()) || dynamic_cast(thunk().expr) diff --git a/src/libexpr/include/nix/expr/value.hh b/src/libexpr/include/nix/expr/value.hh index 658cb5a6a..0af9e1ea5 100644 --- a/src/libexpr/include/nix/expr/value.hh +++ b/src/libexpr/include/nix/expr/value.hh @@ -175,6 +175,18 @@ struct Value private: InternalType internalType = tUninitialized; + InternalType getInternalType() const noexcept + { + return internalType; + } + + /** Check if currently stored value type is either of Vs. */ + template + bool isa() const noexcept + { + return ((getInternalType() == Vs) || ...); + } + friend std::string showType(const Value & v); public: @@ -193,26 +205,26 @@ public: // type() == nThunk inline bool isThunk() const { - return internalType == tThunk; + return isa(); }; inline bool isApp() const { - return internalType == tApp; + return isa(); }; inline bool isBlackhole() const; // type() == nFunction inline bool isLambda() const { - return internalType == tLambda; + return isa(); }; inline bool isPrimOp() const { - return internalType == tPrimOp; + return isa(); }; inline bool isPrimOpApp() const { - return internalType == tPrimOpApp; + return isa(); }; /** @@ -302,7 +314,7 @@ public: */ inline ValueType type(bool invalidIsThunk = false) const { - switch (internalType) { + switch (getInternalType()) { case tUninitialized: break; case tInt: @@ -351,7 +363,7 @@ public: */ inline bool isValid() const { - return internalType != tUninitialized; + return !isa(); } inline void mkInt(NixInt::Inner n) @@ -451,7 +463,7 @@ public: bool isList() const { - return internalType == tListSmall || internalType == tListN; + return isa(); } std::span listItems() const @@ -462,12 +474,12 @@ public: Value * const * listElems() const { - return internalType == tListSmall ? payload.smallList : payload.bigList.elems; + return isa() ? payload.smallList : payload.bigList.elems; } size_t listSize() const { - return internalType == tListSmall ? (payload.smallList[1] == nullptr ? 1 : 2) : payload.bigList.size; + return isa() ? (payload.smallList[1] == nullptr ? 1 : 2) : payload.bigList.size; } PosIdx determinePos(const PosIdx pos) const; @@ -481,19 +493,19 @@ public: SourcePath path() const { - assert(internalType == tPath); + assert(isa()); return SourcePath(ref(pathAccessor()->shared_from_this()), CanonPath(CanonPath::unchecked_t(), pathStr())); } std::string_view string_view() const { - assert(internalType == tString); + assert(isa()); return std::string_view(payload.string.c_str); } const char * c_str() const { - assert(internalType == tString); + assert(isa()); return payload.string.c_str; } @@ -567,7 +579,7 @@ extern ExprBlackHole eBlackHole; bool Value::isBlackhole() const { - return internalType == tThunk && thunk().expr == (Expr *) &eBlackHole; + return isa() && thunk().expr == (Expr *) &eBlackHole; } void Value::mkBlackhole()