// Put a struct in a vector. // TODO: test erase, swap, and clear -Jeremy /*include_c "stdio.h";*/ use "g_stdio.g"; use "vector.g"; use "numeric.g"; use "sequence_queries.g"; use "slist.g"; struct foo { int n; }; // Yuk, these should be generated! -Jeremy model DefaultConstructible { fun new_on_stack() -> foo*@ { return nullptr; } fun new_on_heap() -> foo**@ { return new foo*(); } fun new_placement(void* p) -> foo**@ { return new (p) foo*(); } fun new_on_gc() -> foo**@ { return new GC foo*(); } fun new_array_on_heap(int n) -> foo**@ { return new foo*[n]; } fun new_array_on_gc(int n) -> foo**@ { return new GC foo*[n]; } }; model Regular { fun operator= *(foo*! x ,foo* y) -> foo*! { return x = y; } fun new_on_stack(foo* x) -> foo*@ { return x; } fun new_on_heap(foo* x) -> foo**@ { return new foo*(x); } fun new_placement(void* p, foo* x) -> foo**@ { return new (p) foo*(x); } fun new_on_gc(foo* x) -> foo**@ { return new GC foo*(x); } fun cleanup(foo** x) { delete x; } fun wipeout(foo**) { } }; model Semigroup { fun binary_op(foo x, foo y) -> foo@ { return @foo{ n = x.n + y.n }; } }; model Monoid { fun identity_elt() -> foo@ { return @foo{ n = 0 }; } }; fun operator==(foo a, foo b) -> bool@ { return a.n == b.n; } model EqualityComparable {}; fun main() -> int@ { // Test default constructors, push_back, size, capacity, and empty let v = @vector(); if (not (size(v) == 0 and capacity(v) >= 0)) return 1; if (not empty(v)) return 2; push_back(@foo{n=1}, v); if (not (size(v) == 1 and capacity(v) >= 1)) return 3; if (empty(v)) return -1; push_back(@foo{n=2}, v); if (not (size(v) == 2 and capacity(v) >= 2)) return 4; push_back(@foo{n=3}, v); if (not (size(v) == 3 and capacity(v) >= 3)) return 5; push_back(@foo{n=4}, v); if (not (size(v) == 4 and capacity(v) >= 4)) return 6; let s = accumulate(begin(v), end(v)); if (s.n != 10) return 7; // Test operator[] let s = @slist(); for (let n = 3; n >= 0; --n) push_front(v[n], s); // Test input iterator range constructor let z = @vector(begin(s), end(s)); if (not (size(z) == size(s) and equal(begin(z), end(z), begin(s)))) return 8; // Test forward iterator range constructor let x = @vector(begin(v), end(v)); if (not (size(x) == size(v) and equal(begin(x), end(x), begin(v)))) return 9; // Test length constructor let y = @vector(size(v)); copy(begin(v), end(v), begin(y)); if (not (size(x) == size(v) and equal(begin(x), end(x), begin(v)))) return 10; // Test assignment operator let w = @vector(); w = v; if (not (size(x) == size(v) and equal(begin(x), end(x), begin(v)))) return 11; // Test insert element insert(begin(v), @foo{n=0}, v); if (not (size(v) == 5 and capacity(v) >= 5)) return 12; if (not (equal(begin(v) + 1, end(v), begin(x)))) return 13; if (not (v[0].n == 0)) return 14; insert(end(v), @foo{n=5}, v); if (not (size(v) == 6 and capacity(v) >= 6)) return 14; if (not (equal(begin(v) + 1, end(v) - 1, begin(x)))) return 15; if (not (v[5].n == 5)) return 16; // Test insert input iterator range insert(begin(z), begin(s), end(s), z); if (not (equal(begin(z), begin(z) + size(s), begin(s)))) return 17; if (not (equal(begin(z) + size(s), end(z), begin(s)))) return 18; // Test insert forward iterator range insert(end(x), begin(y), end(y), x); if (not (equal(begin(x), begin(x) + size(y), begin(y)))) return 19; if (not (equal(begin(x) + size(y), end(x), begin(y)))) return 20; return 0; }