mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 02:28:21 +00:00
Merge remote-tracking branch 'origin/topic/vern/vector-holes'
* origin/topic/vern/vector-holes: Remove NEWS entry regarding changed vector-holes functionality Fix potential segfaults in VectorVal Insert/Remove methods Fix copy() to work with a vector that has trailing holes update test suite for vector holes now being supported for numeric types add vector tests for creating holes, "in" operator, "?" operator, copying vectors with holes restore support for vectors with holes remove vestigial comment fix using ++/-- to vectors that contain holes
This commit is contained in:
commit
e8247c2472
11 changed files with 165 additions and 80 deletions
137
src/Val.cc
137
src/Val.cc
|
@ -3246,7 +3246,7 @@ ValPtr TypeVal::DoClone(CloneState* state)
|
|||
|
||||
VectorVal::VectorVal(VectorTypePtr t) : Val(t)
|
||||
{
|
||||
vector_val = new vector<ZVal>();
|
||||
vector_val = new vector<std::optional<ZVal>>();
|
||||
yield_type = t->Yield();
|
||||
|
||||
auto y_tag = yield_type->Tag();
|
||||
|
@ -3260,14 +3260,19 @@ VectorVal::~VectorVal()
|
|||
{
|
||||
int n = yield_types->size();
|
||||
for ( auto i = 0; i < n; ++i )
|
||||
ZVal::DeleteIfManaged((*vector_val)[i], (*yield_types)[i]);
|
||||
{
|
||||
auto& elem = (*vector_val)[i];
|
||||
if ( elem )
|
||||
ZVal::DeleteIfManaged(*elem, (*yield_types)[i]);
|
||||
}
|
||||
delete yield_types;
|
||||
}
|
||||
|
||||
else if ( managed_yield )
|
||||
{
|
||||
for ( auto& elem : *vector_val )
|
||||
ZVal::DeleteManagedType(elem);
|
||||
if ( elem )
|
||||
ZVal::DeleteManagedType(*elem);
|
||||
}
|
||||
|
||||
delete vector_val;
|
||||
|
@ -3325,7 +3330,9 @@ bool VectorVal::Assign(unsigned int index, ValPtr element)
|
|||
|
||||
if ( index >= n )
|
||||
{
|
||||
AddHoles(index - n);
|
||||
if ( index > n )
|
||||
AddHoles(index - n);
|
||||
|
||||
vector_val->resize(index + 1);
|
||||
if ( yield_types )
|
||||
yield_types->resize(index + 1);
|
||||
|
@ -3335,14 +3342,21 @@ bool VectorVal::Assign(unsigned int index, ValPtr element)
|
|||
{
|
||||
const auto& t = element->GetType();
|
||||
(*yield_types)[index] = t;
|
||||
ZVal::DeleteIfManaged((*vector_val)[index], t);
|
||||
(*vector_val)[index] = ZVal(std::move(element), t);
|
||||
auto& elem = (*vector_val)[index];
|
||||
if ( elem )
|
||||
ZVal::DeleteIfManaged(*elem, t);
|
||||
elem = ZVal(std::move(element), t);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( managed_yield )
|
||||
ZVal::DeleteManagedType((*vector_val)[index]);
|
||||
(*vector_val)[index] = ZVal(std::move(element), yield_type);
|
||||
auto& elem = (*vector_val)[index];
|
||||
if ( managed_yield && elem )
|
||||
ZVal::DeleteManagedType(*elem);
|
||||
|
||||
if ( element )
|
||||
elem = ZVal(std::move(element), yield_type);
|
||||
else
|
||||
elem = std::nullopt;
|
||||
}
|
||||
|
||||
Modified();
|
||||
|
@ -3366,7 +3380,7 @@ bool VectorVal::Insert(unsigned int index, ValPtr element)
|
|||
if ( ! CheckElementType(element) )
|
||||
return false;
|
||||
|
||||
vector<ZVal>::iterator it;
|
||||
vector<std::optional<ZVal>>::iterator it;
|
||||
vector<TypePtr>::iterator types_it;
|
||||
|
||||
auto n = vector_val->size();
|
||||
|
@ -3376,28 +3390,39 @@ bool VectorVal::Insert(unsigned int index, ValPtr element)
|
|||
it = std::next(vector_val->begin(), index);
|
||||
if ( yield_types )
|
||||
{
|
||||
ZVal::DeleteIfManaged(*it, element->GetType());
|
||||
if ( *it )
|
||||
ZVal::DeleteIfManaged(**it, element->GetType());
|
||||
types_it = std::next(yield_types->begin(), index);
|
||||
}
|
||||
else if ( managed_yield )
|
||||
ZVal::DeleteManagedType(*it);
|
||||
{
|
||||
if ( *it )
|
||||
ZVal::DeleteManagedType(**it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
it = vector_val->end();
|
||||
if ( yield_types )
|
||||
types_it = yield_types->end();
|
||||
AddHoles(index - n);
|
||||
|
||||
if ( index > n )
|
||||
AddHoles(index - n);
|
||||
}
|
||||
|
||||
if ( yield_types )
|
||||
if ( element )
|
||||
{
|
||||
const auto& t = element->GetType();
|
||||
yield_types->insert(types_it, t);
|
||||
vector_val->insert(it, ZVal(std::move(element), t));
|
||||
if ( yield_types )
|
||||
{
|
||||
const auto& t = element->GetType();
|
||||
yield_types->insert(types_it, t);
|
||||
vector_val->insert(it, ZVal(std::move(element), t));
|
||||
}
|
||||
else
|
||||
vector_val->insert(it, ZVal(std::move(element), yield_type));
|
||||
}
|
||||
else
|
||||
vector_val->insert(it, ZVal(std::move(element), yield_type));
|
||||
vector_val->insert(it, std::nullopt);
|
||||
|
||||
Modified();
|
||||
return true;
|
||||
|
@ -3410,7 +3435,7 @@ void VectorVal::AddHoles(int nholes)
|
|||
fill_t = base_type(TYPE_ANY);
|
||||
|
||||
for ( auto i = 0; i < nholes; ++i )
|
||||
vector_val->emplace_back(ZVal(fill_t));
|
||||
vector_val->emplace_back(std::nullopt);
|
||||
}
|
||||
|
||||
bool VectorVal::Remove(unsigned int index)
|
||||
|
@ -3423,12 +3448,16 @@ bool VectorVal::Remove(unsigned int index)
|
|||
if ( yield_types )
|
||||
{
|
||||
auto types_it = std::next(yield_types->begin(), index);
|
||||
ZVal::DeleteIfManaged(*it, *types_it);
|
||||
if ( *it )
|
||||
ZVal::DeleteIfManaged(**it, *types_it);
|
||||
yield_types->erase(types_it);
|
||||
}
|
||||
|
||||
else if ( managed_yield )
|
||||
ZVal::DeleteManagedType(*it);
|
||||
{
|
||||
if ( *it )
|
||||
ZVal::DeleteManagedType(**it);
|
||||
}
|
||||
|
||||
vector_val->erase(it);
|
||||
|
||||
|
@ -3465,33 +3494,33 @@ ValPtr VectorVal::At(unsigned int index) const
|
|||
if ( index >= vector_val->size() )
|
||||
return Val::nil;
|
||||
|
||||
auto& elem = (*vector_val)[index];
|
||||
if ( ! elem )
|
||||
return Val::nil;
|
||||
|
||||
const auto& t = yield_types ? (*yield_types)[index] : yield_type;
|
||||
|
||||
return (*vector_val)[index].ToVal(t);
|
||||
return elem->ToVal(t);
|
||||
}
|
||||
|
||||
static Func* sort_function_comp = nullptr;
|
||||
|
||||
// Used for indirect sorting to support order().
|
||||
static std::vector<const ZVal*> index_map;
|
||||
static std::vector<const std::optional<ZVal>*> index_map;
|
||||
|
||||
// The yield type of the vector being sorted.
|
||||
static TypePtr sort_type;
|
||||
static bool sort_type_is_managed = false;
|
||||
|
||||
static bool sort_function(const ZVal& a, const ZVal& b)
|
||||
static bool sort_function(const std::optional<ZVal>& a, const std::optional<ZVal>& b)
|
||||
{
|
||||
// Missing values are only applicable for managed types.
|
||||
if ( sort_type_is_managed )
|
||||
{
|
||||
if ( ! a.ManagedVal() )
|
||||
return 0;
|
||||
if ( ! b.ManagedVal() )
|
||||
return 1;
|
||||
}
|
||||
if ( ! a )
|
||||
return false;
|
||||
|
||||
auto a_v = a.ToVal(sort_type);
|
||||
auto b_v = b.ToVal(sort_type);
|
||||
if ( ! b )
|
||||
return true;
|
||||
|
||||
auto a_v = a->ToVal(sort_type);
|
||||
auto b_v = b->ToVal(sort_type);
|
||||
|
||||
auto result = sort_function_comp->Invoke(a_v, b_v);
|
||||
int int_result = result->CoerceToInt();
|
||||
|
@ -3499,19 +3528,37 @@ static bool sort_function(const ZVal& a, const ZVal& b)
|
|||
return int_result < 0;
|
||||
}
|
||||
|
||||
static bool signed_sort_function (const ZVal& a, const ZVal& b)
|
||||
static bool signed_sort_function(const std::optional<ZVal>& a, const std::optional<ZVal>& b)
|
||||
{
|
||||
return a.AsInt() < b.AsInt();
|
||||
if ( ! a )
|
||||
return false;
|
||||
|
||||
if ( ! b )
|
||||
return true;
|
||||
|
||||
return a->AsInt() < b->AsInt();
|
||||
}
|
||||
|
||||
static bool unsigned_sort_function (const ZVal& a, const ZVal& b)
|
||||
static bool unsigned_sort_function(const std::optional<ZVal>& a, const std::optional<ZVal>& b)
|
||||
{
|
||||
return a.AsCount() < b.AsCount();
|
||||
if ( ! a )
|
||||
return false;
|
||||
|
||||
if ( ! b )
|
||||
return true;
|
||||
|
||||
return a->AsCount() < b->AsCount();
|
||||
}
|
||||
|
||||
static bool double_sort_function (const ZVal& a, const ZVal& b)
|
||||
static bool double_sort_function(const std::optional<ZVal>& a, const std::optional<ZVal>& b)
|
||||
{
|
||||
return a.AsDouble() < b.AsDouble();
|
||||
if ( ! a )
|
||||
return false;
|
||||
|
||||
if ( ! b )
|
||||
return true;
|
||||
|
||||
return a->AsDouble() < b->AsDouble();
|
||||
}
|
||||
|
||||
static bool indirect_sort_function(size_t a, size_t b)
|
||||
|
@ -3540,9 +3587,8 @@ void VectorVal::Sort(Func* cmp_func)
|
|||
reporter->RuntimeError(GetLocationInfo(), "cannot sort a vector-of-any");
|
||||
|
||||
sort_type = yield_type;
|
||||
sort_type_is_managed = ZVal::IsManagedType(sort_type);
|
||||
|
||||
bool (*sort_func)(const ZVal&, const ZVal&);
|
||||
bool (*sort_func)(const std::optional<ZVal>&, const std::optional<ZVal>&);
|
||||
|
||||
if ( cmp_func )
|
||||
{
|
||||
|
@ -3577,7 +3623,6 @@ VectorValPtr VectorVal::Order(Func* cmp_func)
|
|||
}
|
||||
|
||||
sort_type = yield_type;
|
||||
sort_type_is_managed = ZVal::IsManagedType(sort_type);
|
||||
|
||||
bool (*sort_func)(size_t, size_t);
|
||||
|
||||
|
@ -3671,8 +3716,8 @@ ValPtr VectorVal::DoClone(CloneState* state)
|
|||
|
||||
for ( auto i = 0; i < n; ++i )
|
||||
{
|
||||
auto vc = At(i)->Clone(state);
|
||||
vv->Append(std::move(vc));
|
||||
auto elem = At(i);
|
||||
vv->Assign(i, elem ? elem->Clone(state) : nullptr);
|
||||
}
|
||||
|
||||
return vv;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue