mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 18:18:19 +00:00
Merge remote-tracking branch 'origin/topic/timw/3059-set-vector-conversion'
* origin/topic/timw/3059-set-vector-conversion: Fix conversion with record types Add conversion between set and vector using 'as' keyword Add std::move for a couple of variables passed by value
This commit is contained in:
commit
e8ef169b27
11 changed files with 206 additions and 3 deletions
79
src/Val.cc
79
src/Val.cc
|
@ -4282,9 +4282,80 @@ ValPtr cast_value_to_type(Val* v, Type* t)
|
|||
return static_cast<Broker::detail::DataVal*>(dv.get())->castTo(t);
|
||||
}
|
||||
|
||||
// Allow casting between sets and vectors if the yield types are the same.
|
||||
if ( v->GetType()->IsSet() && IsVector(t->Tag()) )
|
||||
{
|
||||
auto set_type = v->GetType<SetType>();
|
||||
auto indices = set_type->GetIndices();
|
||||
|
||||
if ( indices->GetTypes().size() > 1 )
|
||||
return nullptr;
|
||||
|
||||
auto ret_type = IntrusivePtr<VectorType>{NewRef{}, t->AsVectorType()};
|
||||
auto ret = make_intrusive<VectorVal>(ret_type);
|
||||
|
||||
auto* table = v->AsTable();
|
||||
auto* tval = v->AsTableVal();
|
||||
int index = 0;
|
||||
for ( const auto& te : *table )
|
||||
{
|
||||
auto k = te.GetHashKey();
|
||||
auto lv = tval->RecreateIndex(*k);
|
||||
ValPtr entry_key = lv->Length() == 1 ? lv->Idx(0) : lv;
|
||||
ret->Assign(index, entry_key);
|
||||
index++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else if ( IsVector(v->GetType()->Tag()) && t->IsSet() )
|
||||
{
|
||||
auto ret_type = IntrusivePtr<TableType>{NewRef{}, t->AsSetType()};
|
||||
auto ret = make_intrusive<TableVal>(ret_type);
|
||||
|
||||
auto vv = v->AsVectorVal();
|
||||
size_t size = vv->Size();
|
||||
|
||||
for ( size_t i = 0; i < size; i++ )
|
||||
{
|
||||
auto ve = vv->ValAt(i);
|
||||
ret->Assign(std::move(ve), nullptr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool can_cast_set_and_vector(const Type* t1, const Type* t2)
|
||||
{
|
||||
const TableType* st = nullptr;
|
||||
const VectorType* vt = nullptr;
|
||||
|
||||
if ( t1->IsSet() && IsVector(t2->Tag()) )
|
||||
{
|
||||
st = t1->AsSetType();
|
||||
vt = t2->AsVectorType();
|
||||
}
|
||||
else if ( IsVector(t1->Tag()) && t2->IsSet() )
|
||||
{
|
||||
st = t2->AsSetType();
|
||||
vt = t1->AsVectorType();
|
||||
}
|
||||
|
||||
if ( st && vt )
|
||||
{
|
||||
auto set_indices = st->GetIndices()->GetTypes();
|
||||
if ( set_indices.size() > 1 )
|
||||
return false;
|
||||
|
||||
return same_type(set_indices[0], vt->Yield());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool can_cast_value_to_type(const Val* v, Type* t)
|
||||
{
|
||||
// Note: when changing this function, adapt all three of
|
||||
|
@ -4308,6 +4379,10 @@ bool can_cast_value_to_type(const Val* v, Type* t)
|
|||
return static_cast<const Broker::detail::DataVal*>(dv.get())->canCastTo(t);
|
||||
}
|
||||
|
||||
// Allow casting between sets and vectors if the yield types are the same.
|
||||
if ( can_cast_set_and_vector(v->GetType().get(), t) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4327,6 +4402,10 @@ bool can_cast_value_to_type(const Type* s, Type* t)
|
|||
// will.
|
||||
return true;
|
||||
|
||||
// Allow casting between sets and vectors if the yield types are the same.
|
||||
if ( can_cast_set_and_vector(s, t) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue