1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-07 22:33:57 +02:00

libexpr: Simplify Value::is* methods by introducing isa function template

This commit is contained in:
Sergei Zimmerman 2025-06-28 15:30:43 +03:00
parent 1a033ee4ee
commit 810455f1b8
No known key found for this signature in database
GPG key ID: A9B0B557CA632325
2 changed files with 30 additions and 19 deletions

View file

@ -125,7 +125,7 @@ std::string showType(const Value & v)
// Allow selecting a subset of enum values // Allow selecting a subset of enum values
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum" #pragma GCC diagnostic ignored "-Wswitch-enum"
switch (v.internalType) { switch (v.getInternalType()) {
case tString: return v.context() ? "a string with context" : "a string"; case tString: return v.context() ? "a string with context" : "a string";
case tPrimOp: case tPrimOp:
return fmt("the built-in function '%s'", std::string(v.primOp()->name)); 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 // Allow selecting a subset of enum values
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum" #pragma GCC diagnostic ignored "-Wswitch-enum"
switch (internalType) { switch (getInternalType()) {
case tAttrs: return attrs()->pos; case tAttrs: return attrs()->pos;
case tLambda: return lambda().fun->pos; case tLambda: return lambda().fun->pos;
case tApp: return app().left->determinePos(pos); case tApp: return app().left->determinePos(pos);
@ -157,9 +157,8 @@ PosIdx Value::determinePos(const PosIdx pos) const
bool Value::isTrivial() const bool Value::isTrivial() const
{ {
return return
internalType != tApp !isa<tApp, tPrimOpApp>()
&& internalType != tPrimOpApp && (!isa<tThunk>()
&& (internalType != tThunk
|| (dynamic_cast<ExprAttrs *>(thunk().expr) || (dynamic_cast<ExprAttrs *>(thunk().expr)
&& ((ExprAttrs *) thunk().expr)->dynamicAttrs.empty()) && ((ExprAttrs *) thunk().expr)->dynamicAttrs.empty())
|| dynamic_cast<ExprLambda *>(thunk().expr) || dynamic_cast<ExprLambda *>(thunk().expr)

View file

@ -175,6 +175,18 @@ struct Value
private: private:
InternalType internalType = tUninitialized; InternalType internalType = tUninitialized;
InternalType getInternalType() const noexcept
{
return internalType;
}
/** Check if currently stored value type is either of Vs. */
template<InternalType... Vs>
bool isa() const noexcept
{
return ((getInternalType() == Vs) || ...);
}
friend std::string showType(const Value & v); friend std::string showType(const Value & v);
public: public:
@ -193,26 +205,26 @@ public:
// type() == nThunk // type() == nThunk
inline bool isThunk() const inline bool isThunk() const
{ {
return internalType == tThunk; return isa<tThunk>();
}; };
inline bool isApp() const inline bool isApp() const
{ {
return internalType == tApp; return isa<tApp>();
}; };
inline bool isBlackhole() const; inline bool isBlackhole() const;
// type() == nFunction // type() == nFunction
inline bool isLambda() const inline bool isLambda() const
{ {
return internalType == tLambda; return isa<tLambda>();
}; };
inline bool isPrimOp() const inline bool isPrimOp() const
{ {
return internalType == tPrimOp; return isa<tPrimOp>();
}; };
inline bool isPrimOpApp() const inline bool isPrimOpApp() const
{ {
return internalType == tPrimOpApp; return isa<tPrimOpApp>();
}; };
/** /**
@ -302,7 +314,7 @@ public:
*/ */
inline ValueType type(bool invalidIsThunk = false) const inline ValueType type(bool invalidIsThunk = false) const
{ {
switch (internalType) { switch (getInternalType()) {
case tUninitialized: case tUninitialized:
break; break;
case tInt: case tInt:
@ -351,7 +363,7 @@ public:
*/ */
inline bool isValid() const inline bool isValid() const
{ {
return internalType != tUninitialized; return !isa<tUninitialized>();
} }
inline void mkInt(NixInt::Inner n) inline void mkInt(NixInt::Inner n)
@ -451,7 +463,7 @@ public:
bool isList() const bool isList() const
{ {
return internalType == tListSmall || internalType == tListN; return isa<tListSmall, tListN>();
} }
std::span<Value * const> listItems() const std::span<Value * const> listItems() const
@ -462,12 +474,12 @@ public:
Value * const * listElems() const Value * const * listElems() const
{ {
return internalType == tListSmall ? payload.smallList : payload.bigList.elems; return isa<tListSmall>() ? payload.smallList : payload.bigList.elems;
} }
size_t listSize() const size_t listSize() const
{ {
return internalType == tListSmall ? (payload.smallList[1] == nullptr ? 1 : 2) : payload.bigList.size; return isa<tListSmall>() ? (payload.smallList[1] == nullptr ? 1 : 2) : payload.bigList.size;
} }
PosIdx determinePos(const PosIdx pos) const; PosIdx determinePos(const PosIdx pos) const;
@ -481,19 +493,19 @@ public:
SourcePath path() const SourcePath path() const
{ {
assert(internalType == tPath); assert(isa<tPath>());
return SourcePath(ref(pathAccessor()->shared_from_this()), CanonPath(CanonPath::unchecked_t(), pathStr())); return SourcePath(ref(pathAccessor()->shared_from_this()), CanonPath(CanonPath::unchecked_t(), pathStr()));
} }
std::string_view string_view() const std::string_view string_view() const
{ {
assert(internalType == tString); assert(isa<tString>());
return std::string_view(payload.string.c_str); return std::string_view(payload.string.c_str);
} }
const char * c_str() const const char * c_str() const
{ {
assert(internalType == tString); assert(isa<tString>());
return payload.string.c_str; return payload.string.c_str;
} }
@ -567,7 +579,7 @@ extern ExprBlackHole eBlackHole;
bool Value::isBlackhole() const bool Value::isBlackhole() const
{ {
return internalType == tThunk && thunk().expr == (Expr *) &eBlackHole; return isa<tThunk>() && thunk().expr == (Expr *) &eBlackHole;
} }
void Value::mkBlackhole() void Value::mkBlackhole()