| Index: test/cctest/test-utils.cc
|
| diff --git a/test/cctest/test-utils.cc b/test/cctest/test-utils.cc
|
| index c1dae6484a2d6e0a81217c2f8045d7b0cbf9d7ea..d90b2d6224d1605efd4e44329a1e7d299317bf49 100644
|
| --- a/test/cctest/test-utils.cc
|
| +++ b/test/cctest/test-utils.cc
|
| @@ -27,9 +27,13 @@
|
|
|
| #include <stdlib.h>
|
|
|
| +#include <deque>
|
| +#include <list>
|
| +
|
| #include "src/v8.h"
|
|
|
| #include "src/base/platform/platform.h"
|
| +#include "src/ostreams.h"
|
| #include "src/utils-inl.h"
|
| #include "test/cctest/cctest.h"
|
|
|
| @@ -218,3 +222,188 @@ TEST(SequenceCollectorRegression) {
|
| CHECK_EQ(0, strncmp("0123456789012345678901234567890123",
|
| seq.start(), seq.length()));
|
| }
|
| +
|
| +
|
| +// The tests for the iteration macros below are slightly modified examples taken
|
| +// from the Boost docs at http://www.boost.org/doc/libs/release/libs/foreach/.
|
| +
|
| +// Iterate over an STL container.
|
| +TEST(ForeachSTL) {
|
| + OStringStream os;
|
| + std::list<int> list_int;
|
| + list_int.push_back(11);
|
| + list_int.push_back(22);
|
| + list_int.push_back(33);
|
| +
|
| + V8_FOREACH_C(int i, list_int) { os << i << " "; }
|
| + V8_FOREACH(int i, list_int) { os << i << " "; }
|
| +
|
| + CHECK_EQ("11 22 33 11 22 33 ", os.c_str());
|
| +}
|
| +
|
| +
|
| +// Iteration over arrays is not supported yet.
|
| +#if 0
|
| +// Iterate over an array, with covariance (i.e., the type of the iteration
|
| +// variable is not exactly the same as the element type of the container).
|
| +TEST(ForeachArrayCovariance) {
|
| + OStringStream os;
|
| + short array_short[] = {111, 222, 333}; // NOLINT
|
| +
|
| + V8_FOREACH(int i, array_short) {
|
| + // The short was implicitly converted to an int
|
| + os << i << " ";
|
| + }
|
| +
|
| + CHECK_EQ("111 222 333 ", os.c_str());
|
| +}
|
| +#endif
|
| +
|
| +
|
| +// Predeclare the loop variable, and use continue + break in the loop body.
|
| +TEST(ForeachContinueBreak) {
|
| + OStringStream os;
|
| + std::deque<int> deque_int;
|
| + deque_int.push_back(1111);
|
| + deque_int.push_back(2222);
|
| + deque_int.push_back(3333);
|
| + deque_int.push_back(4444);
|
| + deque_int.push_back(5555);
|
| +
|
| + int i = 0;
|
| + V8_FOREACH_C(i, deque_int) {
|
| + if (i == 2222) continue;
|
| + if (i == 4444) break;
|
| + os << i << " ";
|
| + }
|
| +
|
| + CHECK_EQ("1111 3333 ", os.c_str());
|
| +}
|
| +
|
| +
|
| +// Iteration over arrays is not supported yet.
|
| +#if 0
|
| +// Iterate over a sequence by reference, and modify the underlying sequence.
|
| +TEST(ForeachModify) {
|
| + short array_short[] = {1, 2, 3}; // NOLINT
|
| +
|
| + V8_FOREACH(short& i, array_short) { ++i; } // NOLINT
|
| +
|
| + CHECK_EQ(2, array_short[0]);
|
| + CHECK_EQ(3, array_short[1]);
|
| + CHECK_EQ(4, array_short[2]);
|
| +}
|
| +#endif
|
| +
|
| +
|
| +// Iterate over a vector of vectors with nested V8_FOREACH_ loops. In this
|
| +// example, notice that braces around the loop body are not necessary:
|
| +TEST(ForeachNested) {
|
| + std::vector<int> row0;
|
| + row0.push_back(11);
|
| + std::vector<int> row1;
|
| + row1.push_back(22);
|
| + row1.push_back(33);
|
| + std::vector<std::vector<int> > matrix_int;
|
| + matrix_int.push_back(row0);
|
| + matrix_int.push_back(row1);
|
| +
|
| + V8_FOREACH(std::vector<int>& row, matrix_int)
|
| + V8_FOREACH(int& i, row)
|
| + ++i;
|
| +
|
| + CHECK_EQ(12, matrix_int[0][0]);
|
| + CHECK_EQ(23, matrix_int[1][0]);
|
| + CHECK_EQ(34, matrix_int[1][1]);
|
| +
|
| + OStringStream os;
|
| +
|
| + V8_FOREACH_C_REV(const std::vector<int>& row, matrix_int)
|
| + V8_FOREACH_C_REV(const int& i, row)
|
| + os << i << " ";
|
| +
|
| + CHECK_EQ("34 23 12 ", os.c_str());
|
| +}
|
| +
|
| +
|
| +static int get_vector_float_counter = 0;
|
| +
|
| +std::vector<float> get_vector_float() {
|
| + get_vector_float_counter++;
|
| + std::vector<float> v;
|
| + v.push_back(1.5);
|
| + v.push_back(2.5);
|
| + v.push_back(3.5);
|
| + return v;
|
| +}
|
| +
|
| +
|
| +#if !V8_FOREACH_RVALUE_BROKEN
|
| +// Iterate over an expression that returns a sequence by value (i.e. an rvalue).
|
| +TEST(ForeachRvalue) {
|
| + OStringStream os;
|
| +
|
| + V8_FOREACH(float f, get_vector_float()) { os << f << " "; }
|
| +
|
| + CHECK_EQ(1, get_vector_float_counter);
|
| + CHECK_EQ("1.5 2.5 3.5 ", os.c_str());
|
| +}
|
| +#endif
|
| +
|
| +
|
| +// Iterate in reverse.
|
| +TEST(ForeachReverse) {
|
| + OStringStream os;
|
| + std::list<int> list_int;
|
| + list_int.push_back(12);
|
| + list_int.push_back(34);
|
| + list_int.push_back(56);
|
| +
|
| + V8_FOREACH_C_REV(int i, list_int) { os << i << " "; }
|
| + V8_FOREACH_REV(int i, list_int) { os << i << " "; }
|
| +
|
| + CHECK_EQ("56 34 12 56 34 12 ", os.c_str());
|
| +}
|
| +
|
| +
|
| +struct Foo {
|
| + Foo(int aa, int bb, int cc) : a(aa), b(bb), c(cc) {}
|
| + Foo(const Foo& f) {
|
| + a = f.a;
|
| + b = f.b;
|
| + c = f.c;
|
| + copy_constructor_count++;
|
| + }
|
| +
|
| + static int copy_constructor_count;
|
| +
|
| + int a, b, c;
|
| +};
|
| +
|
| +
|
| +int Foo::copy_constructor_count = 0;
|
| +
|
| +
|
| +// Check that V8_FOREACH_ does not copy the container.
|
| +TEST(ForeachCopy) {
|
| + OStringStream os;
|
| +
|
| + std::list<Foo> list_foo;
|
| + list_foo.push_back(Foo(1, 2, 3));
|
| + list_foo.push_back(Foo(4, 5, 6));
|
| + list_foo.push_back(Foo(7, 8, 9));
|
| +
|
| + CHECK_EQ(3, Foo::copy_constructor_count);
|
| +
|
| + V8_FOREACH(Foo f, list_foo)
|
| + os << f.a << f.b << f.c << " ";
|
| +
|
| + CHECK_EQ("123 456 789 ", os.c_str());
|
| + CHECK_EQ(6, Foo::copy_constructor_count);
|
| +
|
| + V8_FOREACH(const Foo& f, list_foo)
|
| + os << f.a << f.b << f.c << " ";
|
| +
|
| + CHECK_EQ("123 456 789 123 456 789 ", os.c_str());
|
| + CHECK_EQ(6, Foo::copy_constructor_count);
|
| +}
|
|
|