Esempio n. 1
0
int
main() {
    {
        Deque_MyClass deq;
        Deque_MyClass_ctor(&deq, MyClass_less_by_id);

        assert(deq.size(&deq) == 0);
        assert(deq.empty(&deq));

        // Should print "---- Deque_MyClass, 14".
        printf("---- %s, %d\n", deq.type_name, (int) sizeof(deq.type_name));
        // std::cout << "---- " << deq.type_name << ", " << sizeof(deq.type_name) << std::endl;
        assert(sizeof deq.type_name == 14);

        deq.push_back(&deq, MyClass{1, "Joe"});
        deq.push_back(&deq, MyClass{2, "Mary"});
        deq.push_back(&deq, MyClass{3, "Tom"});
        deq.push_front(&deq, MyClass{0, "Mike"});
        deq.push_front(&deq, MyClass{-1, "Mary"});

        MyClass_print(&deq.front(&deq));
        MyClass_print(&deq.back(&deq));
        assert(deq.front(&deq).id == -1);
        assert(deq.back(&deq).id == 3);

        deq.pop_front(&deq);
        deq.pop_back(&deq);
        assert(deq.front(&deq).id == 0);
        assert(deq.back(&deq).id == 2);

        assert(deq.size(&deq) == 3);

        for (Deque_MyClass_Iterator it = deq.begin(&deq);
         !Deque_MyClass_Iterator_equal(it, deq.end(&deq)); it.inc(&it)) {
            MyClass_print(&it.deref(&it));
        }

        // Multiple iterators?
        for (Deque_MyClass_Iterator it1 = deq.begin(&deq);
         !Deque_MyClass_Iterator_equal(it1, deq.end(&deq)); it1.inc(&it1)) {
            MyClass_print(&it1.deref(&it1));
            for (Deque_MyClass_Iterator it2 = deq.begin(&deq);
             !Deque_MyClass_Iterator_equal(it2, deq.end(&deq)); it2.inc(&it2)) {
                MyClass_print(&it2.deref(&it2));
                for (Deque_MyClass_Iterator it3 = deq.begin(&deq);
                 !Deque_MyClass_Iterator_equal(it3, deq.end(&deq)); it3.inc(&it3)) {
                    MyClass_print(&it3.deref(&it3));
                }
            }
        }

        // Test decrement of end.
        {
            auto it = deq.end(&deq);
            it.dec(&it);
            assert(it.deref(&it).id == 2);
        }

        // printf("Using at.\n");

        for (size_t i = 0; i < 3; i++) {
            MyClass_print(&deq.at(&deq, i));
        }

        // Test that front(), back(), at(), and deref() are returning a reference.
        // Change via at().
        assert(deq.at(&deq, 0).id == 0);
        deq.at(&deq, 0).id = 100;
        assert(deq.at(&deq, 0).id == 100);
        // Change via front().
        assert(deq.front(&deq).id == 100);
        deq.front(&deq).id = 0;
        assert(deq.front(&deq).id == 0);
        assert(deq.at(&deq, 0).id == 0); // Verify with at() also.
        {
            auto it = deq.end(&deq);
            it.dec(&it);
            assert(it.deref(&it).id == 2);
            it.deref(&it).id = 200;
            assert(it.deref(&it).id == 200);
            // Change using back().
            assert(deq.back(&deq).id == 200);
            deq.back(&deq).id = 2;
            assert(deq.back(&deq).id == 2);
            assert(it.deref(&it).id == 2); // Verify with iterator also.
        }

        deq.clear(&deq);

        deq.dtor(&deq);

        // Test equality.  Two deques compare equal if they are of the same
        // length and all the elements compare equal.  It is undefined behavior
        // if the two deques were constructed with different comparison
        // functions.
        {
            Deque_MyClass deq1, deq2;
            Deque_MyClass_ctor(&deq1, MyClass_less_by_id);
            Deque_MyClass_ctor(&deq2, MyClass_less_by_id);

            deq1.push_back(&deq1, MyClass{1, "Joe"});
            deq1.push_back(&deq1, MyClass{2, "Jane"});
            deq1.push_back(&deq1, MyClass{3, "Mary"});
            deq2.push_back(&deq2, MyClass{1, "Joe"});
            deq2.push_back(&deq2, MyClass{2, "Jane"});
            deq2.push_back(&deq2, MyClass{3, "Mary"});

            assert(Deque_MyClass_equal(deq1, deq2));

            deq1.pop_back(&deq1);
            assert(!Deque_MyClass_equal(deq1, deq2));
            deq1.push_back(&deq1, MyClass{4, "Mary"});
            assert(!Deque_MyClass_equal(deq1, deq2));

            deq1.dtor(&deq1);
            deq2.dtor(&deq2);
        }
    }

    // Test that it can handle other types.  Tests are the same, more or less.
    {
        Deque_int deq;
        Deque_int_ctor(&deq, int_less);

        assert(deq.size(&deq) == 0);
        assert(deq.empty(&deq));

        // Should print "---- Deque_int, 10".
        printf("---- %s, %d\n", deq.type_name, int(sizeof(deq.type_name)));
        // std::cout << "---- " << deq.type_name << ", " << sizeof(deq.type_name) << std::endl;
        assert(sizeof deq.type_name == 10);

        deq.push_back(&deq, 1);
        deq.push_back(&deq, 2);
        deq.push_back(&deq, 3);
        deq.push_front(&deq, 0);
        deq.push_front(&deq, -1);

        printf("%d\n", deq.front(&deq));
        printf("%d\n", deq.back(&deq));
        assert(deq.front(&deq) == -1);
        assert(deq.back(&deq) == 3);

        deq.pop_front(&deq);
        deq.pop_back(&deq);
        assert(deq.front(&deq) == 0);
        assert(deq.back(&deq) == 2);

        assert(deq.size(&deq) == 3);

        for (Deque_int_Iterator it = deq.begin(&deq);
         !Deque_int_Iterator_equal(it, deq.end(&deq)); it.inc(&it)) {
            printf("%d\n", it.deref(&it));
        }

        // Test decrement.
        {
            auto it = deq.end(&deq);
            it.dec(&it);
            assert(it.deref(&it) == 2);
        }

        printf("Using at.\n");

        for (size_t i = 0; i < 3; i++) {
            printf("%d: %d\n", int(i), deq.at(&deq, i));
        }

        deq.clear(&deq);

        deq.dtor(&deq);
    }

    // Test equality.  It is undefined behavior if the two deques were constructed with different
    // comparison functions.
    {
        Deque_int deq1, deq2;
        Deque_int_ctor(&deq1, int_less);
        Deque_int_ctor(&deq2, int_less);

        deq1.push_back(&deq1, 1);
        deq1.push_back(&deq1, 2);
        deq1.push_back(&deq1, 3);
        deq2.push_back(&deq2, 1);
        deq2.push_back(&deq2, 2);
        deq2.push_back(&deq2, 3);

        assert(Deque_int_equal(deq1, deq2));

        deq1.pop_back(&deq1);
        assert(!Deque_int_equal(deq1, deq2));
        deq1.push_back(&deq1, 4);
        assert(!Deque_int_equal(deq1, deq2));

        deq1.dtor(&deq1);
        deq2.dtor(&deq2);
    }

    // Test performance.
    {
        std::default_random_engine e;
        using rand = std::uniform_int_distribution<int>;
        std::uniform_real_distribution<float> action;
        Deque_int deq;
        Deque_int_ctor(&deq, int_less);

        for (int i = 0; i < 1000000; i++) {
            deq.push_back(&deq, i);
        }

        // In one end, out the other.
        for (int i = 0; i < 200000000; i++) {
            // fprintf(stderr, "iter: %d\n", i);
            deq.push_back(&deq, i);
            deq.pop_front(&deq);
        }
        for (int i = 0; i < 200000000; i++) {
            deq.push_front(&deq, i);
            deq.pop_back(&deq);
        }

        // Random.
        int pf = 0, pb = 0, pof = 0, pob = 0;
        for (int i = 0; i < 10000000; i++) {
            if (action(e) > .51) {
                if (rand(0, 1)(e) == 0) {
                    deq.push_back(&deq, i);
                    pf++;
                } else {
                    deq.push_front(&deq, i);
                    pb++;
                }
            } else {
                if (deq.size(&deq) > 0) {
                    if (rand(0, 1)(e) == 0) {
                        deq.pop_back(&deq);
                        pob++;
                    } else {
                        deq.pop_front(&deq);
                        pof++;
                    }
                }
            }
        }
        printf("%d push_backs, %d push_fronts, %d pop_backs, %d pop_fronts, %d size\n", pb, pf, pob, pof, (int) deq.size(&deq));
        deq.dtor(&deq);
    }

    // Test random access performance
    {
       size_t sum = 0;
       int lo = 0, hi = 100000000;
       Deque_int deq;
       Deque_int_ctor(&deq, int_less);

       for(int i = lo; i < hi; i++) {
          deq.push_back(&deq, i);
       }

       for(int i = lo; i < hi; i++) {
          sum += deq.at(&deq, i);
       }
       if(sum > 0) printf("sum of all integers between %d and %d calculated using a deque is %zu\n", lo, hi, sum);
       deq.dtor(&deq);
    }

   // Print allocation info
   printf("%zd allocations totalling %zd bytes\n", alloc_call_count, total_bytes_allocated);
}
Esempio n. 2
0
int
main(void) {
	srand(time(NULL));
	Deque_int d;
	for (size_t i = 0; i < NCYCLES; ++i) {
		std::deque<int> s;
		Deque_int_ctor(&d, int_less);
		Deque_int d2;
		for (size_t i = 0; i < NITERATIONS; ++i) {
			for (size_t i = 0; i < NOPERATIONS; ++i) {
				int val;
				switch(rand() % 100) {
					case 0:
						d.clear(&d);
						s.clear();
						break;
					default:
						switch(rand() % 3) {
							case 0:
								switch(rand() % 2) {
									case 0:
										if (s.empty()) continue;
										d.pop_front(&d);
										s.pop_front();
										break;
									case 1:
										if (s.empty()) continue;
										d.pop_back(&d);
										s.pop_back();
								}
							default:
								switch(rand() % 2) {
									case 0:
										val = int_ctor();
										d.push_front(&d, val);
										s.push_front(val);
										break;
									case 1:
										val = int_ctor();
										d.push_back(&d, val);
										s.push_back(val);
								}
						}
				}
                
			}
			assert(d.size(&d) == s.size());
			assert(d.empty(&d) == s.empty());
            
			for (size_t i = 0; i < s.size(); ++i) {
                //cout<< d.at(&d, i) << " " << s.at(i) <<endl;
				assert(d.at(&d, i) == s.at(i));
			}
            
			Deque_int_ctor(&d2, int_less);
			for (size_t i = 0; i < s.size(); ++i)
				d2.push_back(&d2, s.at(i));
			assert(Deque_int_equal(d, d2));
			assert(Deque_int_equal(d2, d));
			d2.dtor(&d2);
            
			Deque_int_Iterator dit = d.begin(&d);
			std::deque<int>::iterator sit = s.begin();
			for (size_t i = 0; i < NITERATOR; ++i) {
				switch(rand() % 2) {
					case 0:
						if (sit == s.end()) continue;
						++sit;
						dit.inc(&dit);
						break;
					case 1:
						if (sit == s.begin()) continue;
						--sit;
						dit.dec(&dit);
						break;
				}
				assert((sit == s.begin()) == Deque_int_Iterator_equal(dit, d.begin(&d)));
				assert((sit == s.end()) == Deque_int_Iterator_equal(dit, d.end(&d)));
				if (sit == s.end()) continue;
				assert(*sit == dit.deref(&dit));
			}
            
			Deque_int_Iterator dit2 = dit = d.begin(&d);
			int itval = 0, itval2 = 0;
			for (size_t i = 0; i < NITERATOR; ++i) {
				switch(rand() % 4) {
					case 0:
						if (Deque_int_Iterator_equal(dit, d.end(&d))) continue;
						dit.inc(&dit);
						++itval;
						break;
					case 1:
						if (Deque_int_Iterator_equal(dit, d.begin(&d))) continue;
						dit.dec(&dit);
						--itval;
						break;
					case 2:
						if (Deque_int_Iterator_equal(dit2, d.end(&d))) continue;
						dit2.inc(&dit2);
						++itval2;
						break;
					case 3:
						if (Deque_int_Iterator_equal(dit2, d.begin(&d))) continue;
						dit2.dec(&dit2);
						--itval2;
						break;
				}
				assert((itval == itval2) == Deque_int_Iterator_equal(dit, dit2));
				assert((itval == itval2) == Deque_int_Iterator_equal(dit2, dit));
			}
            
			if (s.empty()) continue;
			assert(d.front(&d) == s.front());
			assert(d.back(&d) == s.back());
		}
		d.dtor(&d);
	}
    printf("OK\n");
	return 0;
}