void StrongForEachStatement::eval(VariableEnvironment &env) const { if (env.isGotoing()) return; ENTER_STMT; LvalExpression* lvalSource = m_source->cast<LvalExpression>(); Variant source(lvalSource ? ref(lvalSource->lval(env)) : ref(m_source->eval(env))); source.escalate(true); Variant vTemp; if (m_key) { Variant kTemp; for (MutableArrayIter iter = source.begin(&kTemp, vTemp, env.currentContext()); iter.advance();) { m_key->set(env, kTemp); m_value->set(env, ref(vTemp)); if (!m_body) continue; EVAL_STMT_HANDLE_GOTO_BEGIN(restart1); EVAL_STMT_HANDLE_BREAK(m_body, env); EVAL_STMT_HANDLE_GOTO_END(restart1); } } else { for (MutableArrayIter iter = source.begin(NULL, vTemp, env.currentContext()); iter.advance();) { m_value->set(env, ref(vTemp)); if (!m_body) continue; EVAL_STMT_HANDLE_GOTO_BEGIN(restart2); EVAL_STMT_HANDLE_BREAK(m_body, env); EVAL_STMT_HANDLE_GOTO_END(restart2); } } }
void ArrayUtil::Walk(VRefParam input, PFUNC_WALK walk_function, const void *data, bool recursive /* = false */, PointerSet *seen /* = NULL */, CVarRef userdata /* = null_variant */) { assert(walk_function); Variant k; Variant v; for (MutableArrayIter iter = input->begin(&k, v); iter.advance(); ) { if (recursive && v.is(KindOfArray)) { assert(seen); ArrayData *arr = v.getArrayData(); if (v.isReferenced()) { if (seen->find((void*)arr) != seen->end()) { raise_warning("array_walk_recursive(): recursion detected"); return; } seen->insert((void*)arr); } Walk(directRef(v), walk_function, data, recursive, seen, userdata); if (v.isReferenced()) { seen->erase((void*)arr); } } else { walk_function(directRef(v), k, userdata, data); } } }
bool TestCppBase::TestVariant() { // operators { Variant v(15); v += 20; VERIFY(v.isNumeric()); VERIFY(v.is(KindOfInt64)); VERIFY(v == Variant(35)); } // conversions { Variant v("123"); VERIFY(v.toInt32() == 123); } // offset { Variant v = "test"; VS(v.rvalAt(0), "t"); } { Variant v; v.lvalAt(0) = String("v0"); v.lvalAt(1) = String("v1"); VERIFY(v[0] == "v0"); VERIFY(v[1] == "v1"); } { Variant v; v.lvalAt() = String("test"); VS(v, CREATE_VECTOR1("test")); } { Variant v; v.lvalAt(1) = String("test"); VS(v[1], "test"); VS(v[1.5], "test"); VS(v[Variant(1.5)], "test"); VS(v[s_1], "test"); VS(v[Variant("1")], "test"); } { Variant v; v.lvalAt(Variant(1.5)) = String("test"); VS(v[1], "test"); VS(v[1.5], "test"); VS(v[Variant(1.5)], "test"); VS(v[s_1], "test"); VS(v[Variant("1")], "test"); } { Variant v; v.lvalAt(s_1) = String("test"); VS(v[1], "test"); VS(v[1.5], "test"); VS(v[Variant(1.5)], "test"); VS(v[s_1], "test"); VS(v[Variant("1")], "test"); } { Variant v; v.lvalAt(Variant("1")) = String("test"); VS(v[1], "test"); VS(v[1.5], "test"); VS(v[Variant(1.5)], "test"); VS(v[s_1], "test"); VS(v[Variant("1")], "test"); } // membership { Variant v; v.lvalAt(s_n0) = String("v0"); v.lvalAt(s_n1) = String("v1"); v.remove(s_n1); VS(v, CREATE_MAP1(s_n0, "v0")); v.append("v2"); VS(v, CREATE_MAP2(s_n0, "v0", 0, "v2")); } { Variant v; v.lvalAt(s_n0) = String("v0"); v.lvalAt(1) = String("v1"); v.remove(Variant(1.5)); VS(v, CREATE_MAP1("n0", "v0")); } { Variant v; v.lvalAt(s_n0) = String("v0"); v.lvalAt(1) = String("v1"); v.remove(Variant("1")); VS(v, CREATE_MAP1("n0", "v0")); } { Variant v; v.lvalAt(s_n0) = String("v0"); v.lvalAt(1) = String("v1"); v.remove(String("1")); VS(v, CREATE_MAP1("n0", "v0")); } { Variant v; v.lvalAt(s_n0) = String("v0"); v.lvalAt(empty_string) = String("v1"); v.remove(Variant()); VS(v, CREATE_MAP1("n0", "v0")); } // references { Variant v1("original"); Variant v2 = v1; v2 = String("changed"); VERIFY(v1 == "original"); } { Variant v1("original"); Variant v2 = strongBind(v1); v2 = String("changed"); VERIFY(v1 == "changed"); } { Variant v1 = 10; Variant v2 = Array(ArrayInit(1).setRef(v1).create()); v1 = 20; VS(v2[0], 20); } { Variant v1 = 10; Variant v2; v2.lvalAt() = ref(v1); v1 = 20; VS(v2[0], 20); } { Variant v1 = 10; Variant v2 = CREATE_VECTOR1(5); v2.lvalAt() = ref(v1); v1 = 20; VS(v2[1], 20); } { Variant v1 = 10; Variant v2 = strongBind(v1); v2++; VS(v2, 11); VS(v1, 11); } { Variant arr = CREATE_VECTOR2(1, 2); Variant v; for (MutableArrayIter iter = arr.begin(nullptr, v); iter.advance();) { v++; } VS(arr, CREATE_VECTOR2(2, 3)); } // array escalation { Variant arr; lval(arr.lvalAt(0)).lvalAt(0) = 1.2; VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2))); } { Variant arr; lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2; VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2))); } { Variant arr = Array::Create(); lval(arr.lvalAt(0)).lvalAt(0) = 1.2; VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2))); } { Variant arr = Array::Create(); lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2; VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2))); } { Variant arr = Array::Create("test"); arr.lvalAt(0) = CREATE_VECTOR1(1.2); VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2))); } { Variant arr = Array::Create("test"); lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2; VS(arr, CREATE_MAP2(0, "test", s_name, CREATE_VECTOR1(1.2))); } return Count(true); }
bool TestCppBase::TestArray() { // Array::Create(), Array constructors and informational { Array arr; VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0); VERIFY(arr.isNull()); arr = Array::Create(); VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0); VERIFY(!arr.isNull()); arr = Array::Create(0); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY((int)arr[0] == 0); VS(arr, Array(ArrayInit(1).set(0).create())); arr = Array::Create("test"); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(arr[0] == "test"); VS(arr, Array(ArrayInit(1).set("test").create())); Array arrCopy = arr; arr = Array::Create(arr); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(arr[0].toArray().size() == 1); VS(arr[0], arrCopy); VS(arr, Array(ArrayInit(1).set(arrCopy).create())); arr = Array::Create("name", 1); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY((int)arr["name"] == 1); VS(arr, Array(ArrayInit(1).set("name", 1).create())); arr = Array::Create("name", "test"); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VERIFY(arr["name"] == "test"); VS(arr, Array(ArrayInit(1).set("name", "test").create())); arrCopy = arr; arr = Array::Create("name", arr); VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1); VERIFY(!arr.isNull()); VS(arr["name"], arrCopy); VERIFY(arr["name"].toArray().size() == 1); VS(arr, Array(ArrayInit(1).set("name", arrCopy).create())); } // iteration { Array arr = CREATE_MAP2("n1", "v1", "n2", "v2"); int i = 0; for (ArrayIter iter = arr.begin(); iter; ++iter, ++i) { if (i == 0) { VERIFY(iter.first() == "n1"); VERIFY(iter.second() == "v1"); } else { VERIFY(iter.first() == "n2"); VERIFY(iter.second() == "v2"); } } VERIFY(i == 2); } { Variant arr = CREATE_MAP1("n1", "v1"); Variant k, v; for (MutableArrayIter iter = arr.begin(&k, v); iter.advance();) { arr.weakRemove(k); } VS(arr, Array::Create()); } /* TODO: fix this { Variant arr = CREATE_MAP2("n1", "v1", "n2", "v2"); arr.escalate(); for (ArrayIterPtr iter = arr.begin(arr, true); !iter->end(); iter->next()){ unset(arr.lvalAt(iter->first())); } VS(arr, Array::Create()); } */ // conversions { Array arr0; VERIFY(arr0.toBoolean() == false); VERIFY(arr0.toByte() == 0); VERIFY(arr0.toInt16() == 0); VERIFY(arr0.toInt32() == 0); VERIFY(arr0.toInt64() == 0); VERIFY(arr0.toDouble() == 0.0); VERIFY(arr0.toString() == ""); Array arr1 = Array::Create("test"); VERIFY(arr1.toBoolean() == true); VERIFY(arr1.toByte() == 1); VERIFY(arr1.toInt16() == 1); VERIFY(arr1.toInt32() == 1); VERIFY(arr1.toInt64() == 1); VERIFY(arr1.toDouble() == 1.0); VERIFY(arr1.toString() == "Array"); } // offset { Array arr; arr.set(0, "v1"); arr.set(1, "v2"); VS(arr, CREATE_VECTOR2("v1", "v2")); } { Array arr; arr.set("n1", "v1"); arr.set("n2", "v2"); VS(arr, CREATE_MAP2("n1", "v1", "n2", "v2")); } { Array arr; arr.lvalAt(0) = "v1"; arr.lvalAt(1) = "v2"; VS(arr, CREATE_VECTOR2("v1", "v2")); } { Array arr; arr.lvalAt("n1") = "v1"; arr.lvalAt("n2") = "v2"; VS(arr, CREATE_MAP2("n1", "v1", "n2", "v2")); } { Array arr; Variant name = "name"; arr.lvalAt(name) = "value"; VS(arr, CREATE_MAP1("name", "value")); } { Array arr; arr.lvalAt("A") = 10; arr.lvalAt("A")++; VS(arr["A"], 11); } { Array arr; arr.lvalAt(1) = 10; VS(arr[1], 10); VS(arr[1.5], 10); VS(arr[Variant(1.5)], 10); VS(arr["1"], 10); VS(arr[Variant("1")], 10); } { Array arr; arr.lvalAt(Variant(1.5)) = 10; VS(arr[1], 10); VS(arr[1.5], 10); VS(arr[Variant(1.5)], 10); VS(arr["1"], 10); VS(arr[Variant("1")], 10); } { Array arr; arr.lvalAt("1") = 10; VS(arr[1], 10); VS(arr[1.5], 10); VS(arr[Variant(1.5)], 10); VS(arr["1"], 10); VS(arr[Variant("1")], 10); } { Array arr; arr.lvalAt(Variant("1")) = 10; VS(arr[1], 10); VS(arr[1.5], 10); VS(arr[Variant(1.5)], 10); VS(arr["1"], 10); VS(arr[Variant("1")], 10); } // membership { Array arr; arr.lvalAt(0) = "v1"; arr.lvalAt(1) = "v2"; VERIFY(arr.exists(0)); arr.remove(0); VERIFY(!arr.exists(0)); VS(arr, Array::Create(1, "v2")); arr.append("v3"); VS(arr, CREATE_MAP2(1, "v2", 2, "v3")); } { Array arr; arr.lvalAt(0) = "v1"; VERIFY(arr.exists(0)); arr.remove("0"); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(0) = "v1"; VERIFY(arr.exists(0)); arr.remove(Variant("0")); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(0) = "v1"; VERIFY(arr.exists(0)); arr.remove(Variant(Variant("0"))); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(0) = "v1"; VERIFY(arr.exists(0)); arr.remove(Variant(Variant(0.5))); VERIFY(!arr.exists(0)); } { Array arr; arr.lvalAt(Variant()) = 123; VERIFY(arr.exists("")); arr.remove(Variant()); VERIFY(!arr.exists("")); } { Array arr; arr.lvalAt("n1") = "v1"; arr.lvalAt("n2") = "v2"; VERIFY(arr.exists("n1")); arr.remove("n1"); VERIFY(!arr.exists("n1")); VS(arr, Array::Create("n2", "v2")); arr.append("v3"); VS(arr, CREATE_MAP2("n2", "v2", 0, "v3")); } { Array arr; arr.lvalAt() = "test"; VS(arr, CREATE_VECTOR1("test")); } { Array arr; arr.lvalAt("name") = "value"; VERIFY(arr.exists("name")); } { Array arr; arr.lvalAt(1) = "value"; VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists("1")); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt("1") = "value"; VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists("1")); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(1.5) = "value"; VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists("1")); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(Variant(1.5)) = "value"; VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists("1")); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } { Array arr; arr.lvalAt(Variant("1")) = "value"; VERIFY(arr.exists(1)); VERIFY(arr.exists(1.5)); VERIFY(arr.exists("1")); VERIFY(arr.exists(Variant("1"))); VERIFY(arr.exists(Variant(1))); VERIFY(arr.exists(Variant(1.5))); } // merge { Array arr = Array::Create(0) + Array::Create(1); VS(arr, Array::Create(0)); arr += CREATE_VECTOR2(0, 1); VS(arr, CREATE_VECTOR2(0, 1)); arr = Array::Create(0).merge(Array::Create(1)); VS(arr, CREATE_VECTOR2(0, 1)); arr = arr.merge(CREATE_VECTOR2(0, 1)); VS(arr, CREATE_VECTOR4(0, 1, 0, 1)); arr = Array::Create("s0").merge(Array::Create("s1")); VS(arr, CREATE_VECTOR2("s0", "s1")); arr = Array::Create("n0", "s0") + Array::Create("n1", "s1"); VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1")); arr += CREATE_MAP2("n0", "s0", "n1", "s1"); VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1")); arr = Array::Create("n0", "s0").merge(Array::Create("n1", "s1")); VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1")); Array arrX = CREATE_MAP2("n0", "s2", "n1", "s3"); arr = arr.merge(arrX); VS(arr, CREATE_MAP2("n0", "s2", "n1", "s3")); } // slice { Array arr = CREATE_VECTOR2("test1", "test2"); Array sub = arr.slice(1, 1, true); VS(sub, CREATE_MAP1(1, "test2")); } { Array arr = CREATE_VECTOR2("test1", "test2"); Array sub = arr.slice(1, 1, false); VS(sub, CREATE_VECTOR1("test2")); } { Array arr = CREATE_MAP2("n1", "test1", "n2", "test2"); Array sub = arr.slice(1, 1, true); VS(sub, CREATE_MAP1("n2", "test2")); } { Array arr = CREATE_MAP2("n1", "test1", "n2", "test2"); Array sub = arr.slice(1, 1, false); VS(sub, CREATE_MAP1("n2", "test2")); } // escalation { Array arr; lval(arr.lvalAt(0)).lvalAt(0) = 1.2; VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2))); } { Array arr; lval(arr.lvalAt("name")).lvalAt(0) = 1.2; VS(arr, CREATE_MAP1("name", CREATE_VECTOR1(1.2))); } { Array arr = Array::Create(); lval(arr.lvalAt(0)).lvalAt(0) = 1.2; VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2))); } { Array arr = Array::Create(); lval(arr.lvalAt("name")).lvalAt(0) = 1.2; VS(arr, CREATE_MAP1("name", CREATE_VECTOR1(1.2))); } { Array arr = Array::Create("test"); arr.lvalAt(0) = CREATE_VECTOR1(1.2); VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2))); } { Array arr = Array::Create("test"); lval(arr.lvalAt("name")).lvalAt(0) = 1.2; VS(arr, CREATE_MAP2(0, "test", "name", CREATE_VECTOR1(1.2))); } { Array arr = Array::Create(); arr.append("apple"); arr.set(2, "pear"); VS(arr[2], "pear"); } { Array arr = CREATE_MAP2(0, "a", 1, "b"); VERIFY(arr->isVectorData()); } { Array arr = CREATE_MAP2(1, "a", 0, "b"); VERIFY(!arr->isVectorData()); } { Array arr = CREATE_MAP2(1, "a", 2, "b"); VERIFY(!arr->isVectorData()); } { Array arr = CREATE_MAP1(1, "a"); arr.set(0, "b"); VERIFY(!arr->isVectorData()); } return Count(true); }