123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- /*! ========================================================================
- ** Extended Template and Library Test Suite
- ** Handle Template Class Test
- **
- ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
- **
- ** This package is free software; you can redistribute it and/or
- ** modify it under the terms of the GNU General Public License as
- ** published by the Free Software Foundation; either version 2 of
- ** the License, or (at your option) any later version.
- **
- ** This package is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- ** General Public License for more details.
- **
- ** === N O T E S ===========================================================
- **
- ** ========================================================================= */
- #include <ETL/handle>
- #include <list>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string>
- #include <map>
- #include <vector>
- #define NUMBER_OF_OBJECTS 40000
- using namespace std;
- struct my_test_obj : public etl::rshared_object {
- static int instance_count;
- int my_id;
- my_test_obj(int my_id = 0): my_id(my_id)
- {
- instance_count++;
- }
- virtual ~my_test_obj()
- {
- if (instance_count == 0) {
- printf("Error, instance count is going past zero!\n");
- }
- instance_count--;
- }
- bool operator<(const my_test_obj &rhs)const
- {
- return my_id < rhs.my_id;
- }
- };
- struct my_other_test_obj : public my_test_obj {
- static int instance_count;
- my_other_test_obj(int my_id = 0): my_test_obj(my_id)
- {
- instance_count++;
- }
- virtual ~my_other_test_obj()
- {
- if (instance_count == 0) {
- printf("Error, instance count is going past zero!\n");
- }
- instance_count--;
- }
- };
- int my_test_obj::instance_count = 0;
- int my_other_test_obj::instance_count = 0;
- typedef etl::handle<my_test_obj> obj_handle;
- typedef etl::rhandle<my_test_obj> robj_handle;
- typedef etl::handle<my_other_test_obj> other_obj_handle;
- typedef list< obj_handle > obj_list;
- typedef list< other_obj_handle > other_obj_list;
- typedef list< robj_handle > robj_list;
- int handle_basic_test()
- {
- printf("handle: Size of a handle: %u\n", (unsigned int)sizeof(etl::handle<int>));
- printf("handle: Size of a loose_handle: %u\n", (unsigned int)sizeof(etl::loose_handle<int>));
- printf("handle: Size of a rhandle: %u\n", (unsigned int)sizeof(etl::rhandle<int>));
- printf("handle: Size of a shared_object: %u\n", (unsigned int)sizeof(etl::shared_object));
- printf("handle: Size of a rshared_object: %u\n", (unsigned int)sizeof(etl::rshared_object));
- printf("handle: Basic test: ");
- my_test_obj::instance_count = 0;
- {
- etl::handle<my_test_obj> obj_handle(new my_test_obj(rand()));
- }
- if (my_test_obj::instance_count != 0) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on create/destroy, instance count=%d, should be zero.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- {
- map<string, etl::handle<my_test_obj> > my_map;
- etl::handle<my_test_obj> obj_handle(new my_test_obj(rand()));
- my_map["bleh"] = obj_handle;
- }
- if (my_test_obj::instance_count != 0) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on create/destroy, instance count=%d, should be zero.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- etl::handle<my_test_obj> obj_handle(new my_test_obj(rand()));
- if (obj_handle != obj_handle.constant()) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on call to handle<>::constant().\n", __LINE__);
- return 1;
- }
- printf("PASSED\n");
- return 0;
- }
- int handle_general_use_test(void)
- {
- printf("handle: General-use test: ");
- my_test_obj::instance_count = 0;
- obj_list my_list, my_other_list;
- int i;
- for (i = 0; i < NUMBER_OF_OBJECTS; i++) {
- my_list.push_back(obj_handle(new my_test_obj(rand())));
- }
- my_other_list = my_list;
- if (my_test_obj::instance_count != NUMBER_OF_OBJECTS) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy, instance count=%d, should be %d.\n", __LINE__, my_test_obj::instance_count, NUMBER_OF_OBJECTS);
- return 1;
- }
- my_list.sort();
- if (my_test_obj::instance_count != NUMBER_OF_OBJECTS) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy, instance count=%d, should be %d.\n", __LINE__, my_test_obj::instance_count, NUMBER_OF_OBJECTS);
- return 1;
- }
- my_list.clear();
- if (my_test_obj::instance_count != NUMBER_OF_OBJECTS) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy's clear, instance count=%d, should be %d.\n", __LINE__, my_test_obj::instance_count, NUMBER_OF_OBJECTS);
- return 1;
- }
- {
- obj_handle a(new my_test_obj(27)), b(new my_test_obj(42));
- a.swap(b);
- if (a->my_id != 42 || b->my_id != 27) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On swap (27,42) gave (%d,%d), should be (42,27).\n", __LINE__, a->my_id, b->my_id);
- return 1;
- }
- }
- my_other_list.clear();
- if (my_test_obj::instance_count) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On clear, instance count=%d, should be zero.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- printf("PASSED\n");
- return 0;
- }
- struct ListItem {
- robj_handle obj;
- int bleh;
- int blah;
- ListItem(robj_handle obj, int bleh = 1, int blah = 2):
- obj(obj), bleh(bleh), blah(blah) { }
- };
- int rhandle_general_use_test(void)
- {
- printf("rhandle: General-use test: ");
- my_test_obj::instance_count = 0;
- robj_list my_list;
- int i;
- robj_handle obj = new my_test_obj(rand());
- for (i = 0; i < NUMBER_OF_OBJECTS; i++) {
- my_list.push_back(obj);
- }
- obj_list my_other_list(my_list.begin(), my_list.end());
- if (obj.count() != NUMBER_OF_OBJECTS * 2 + 1) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy, handle count=%d, should be %d.\n", __LINE__, obj.count(), NUMBER_OF_OBJECTS * 2 + 1);
- return 1;
- }
- if (obj.rcount() != NUMBER_OF_OBJECTS + 1) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy, rhandle count=%d, should be %d.\n", __LINE__, obj.rcount(), NUMBER_OF_OBJECTS + 1);
- return 1;
- }
- my_list.sort();
- if (obj.rcount() != NUMBER_OF_OBJECTS + 1) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy, instance count=%d, should be %d.\n", __LINE__, obj.rcount(), NUMBER_OF_OBJECTS + 1);
- return 1;
- }
- {
- robj_handle bleh(obj);
- }
- if (obj.rcount() != NUMBER_OF_OBJECTS + 1) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy, instance count=%d, should be %d.\n", __LINE__, obj.rcount(), NUMBER_OF_OBJECTS + 1);
- return 1;
- }
- my_other_list.clear();
- if (obj.rcount() != obj.count()) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy's clear, handle count (%d) != rhandle count (%d)\n", __LINE__, obj.count(), obj.rcount());
- return 1;
- }
- if (obj.rcount() != NUMBER_OF_OBJECTS + 1) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy's clear, instance count=%d, should be %d.\n", __LINE__, obj.rcount(), NUMBER_OF_OBJECTS + 1);
- return 1;
- }
- robj_handle new_obj = new my_test_obj(rand());
- int replacements = obj.replace(new_obj);
- if (replacements != NUMBER_OF_OBJECTS + 1) {
- printf("FAILED!\n");
- printf(__FILE__":%d: Only managed to replace %d, should have replaced %d\n", __LINE__, replacements, NUMBER_OF_OBJECTS + 1);
- return 1;
- }
- if (obj != new_obj) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On replace, handles should be equal.\n", __LINE__);
- return 1;
- }
- {
- robj_handle bleh(obj);
- robj_handle blah(obj.get());
- }
- my_list.clear();
- obj.detach();
- new_obj.detach();
- if (my_test_obj::instance_count) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On clear, instance count=%d, should be zero.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- std::vector<ListItem> my_item_list;
- for (i = 0; i < NUMBER_OF_OBJECTS; i++) {
- my_item_list.push_back(ListItem(new my_test_obj(rand()), 3, 4));
- }
- for (i = 0; i < 100; i++) {
- int src, dest;
- src = rand() % NUMBER_OF_OBJECTS;
- dest = rand() % NUMBER_OF_OBJECTS;
- ListItem tmp(my_item_list[src]);
- assert(tmp.obj.rcount() >= 2);
- my_item_list.erase(my_item_list.begin() + src);
- assert(tmp.obj.rcount() >= 1);
- my_item_list.insert(my_item_list.begin() + dest, tmp);
- assert(tmp.obj.rcount() >= 2);
- }
- my_item_list.clear();
- if (my_test_obj::instance_count) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On clear, instance count=%d, should be zero.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- printf("PASSED\n");
- return 0;
- }
- int handle_inheritance_test(void)
- {
- printf("handle: Inheritance test: ");
- my_test_obj::instance_count = 0;
- my_other_test_obj::instance_count = 0;
- other_obj_list my_other_list;
- int i;
- for (i = 0; i < NUMBER_OF_OBJECTS; i++) {
- my_other_list.push_back(other_obj_handle(new my_other_test_obj(rand())));
- }
- obj_list my_list(my_other_list.begin(), my_other_list.end());
- if (my_test_obj::instance_count != NUMBER_OF_OBJECTS) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On copy, instance count=%d, should be %d.\n", __LINE__, my_test_obj::instance_count, NUMBER_OF_OBJECTS);
- return 1;
- }
- for (i = 0; i < NUMBER_OF_OBJECTS; i++) {
- my_list.push_back(other_obj_handle(new my_other_test_obj(rand())));
- }
- if (my_other_test_obj::instance_count != NUMBER_OF_OBJECTS * 2 ||
- my_test_obj::instance_count != my_other_test_obj::instance_count) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On inherited copy, instance count=%d, should be %d.\n", __LINE__, my_test_obj::instance_count, NUMBER_OF_OBJECTS * 2);
- return 1;
- }
- my_list.sort();
- my_other_list.sort();
- if (my_test_obj::instance_count != NUMBER_OF_OBJECTS * 2) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On sort, instance count=%d, should be %d.\n", __LINE__, my_test_obj::instance_count, NUMBER_OF_OBJECTS * 2);
- return 1;
- }
- my_list.clear();
- if (my_test_obj::instance_count != NUMBER_OF_OBJECTS) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On clear, instance count=%d, should be %d.\n", __LINE__, my_test_obj::instance_count, NUMBER_OF_OBJECTS);
- return 1;
- }
- my_other_list.clear();
- if (my_test_obj::instance_count) {
- printf("FAILED!\n");
- printf(__FILE__":%d: On clear, instance count=%d, should be zero.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- printf("PASSED\n");
- return 0;
- }
- void test_func(etl::handle<my_test_obj> handle)
- {
- if (handle) {
- int i = handle.count();
- i++;
- }
- }
- int loose_handle_test(void)
- {
- printf("handle: loose_handle test: ");
- my_test_obj::instance_count = 0;
- etl::loose_handle<my_test_obj> obj_handle_loose;
- etl::handle<my_test_obj> obj_handle2;
- {
- etl::handle<my_test_obj> obj_handle(new my_test_obj(rand()));
- if (my_test_obj::instance_count != 1) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on handle assignment from new object, instance count=%d, should be 1.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- obj_handle_loose = obj_handle;
- if (obj_handle != obj_handle_loose) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on loose_handle assignment\n", __LINE__);
- return 1;
- }
- obj_handle2 = obj_handle_loose;
- if (my_test_obj::instance_count != 1) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on handle assignment from loose_handle, instance count=%d, should be 1.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- test_func(obj_handle_loose);
- if (my_test_obj::instance_count != 1) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on handle assignment from loose_handle, instance count=%d, should be 1.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- }
- {
- etl::loose_handle<my_test_obj> a(new my_test_obj(27)), b(new my_test_obj(42));
- a.swap(b);
- if (a->my_id != 42 || b->my_id != 27) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on loose_handle swap (27,42) gave (%d,%d), should be (42,27).\n", __LINE__, a->my_id, b->my_id);
- return 1;
- }
- }
- if (my_test_obj::instance_count != 3) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on create/destroy, instance count=%d, should be 3.\n", __LINE__, my_test_obj::instance_count);
- return 1;
- }
- printf("PASSED\n");
- return 0;
- }
- int handle_cast_test()
- {
- printf("handle: casting test: ");
- etl::handle<my_test_obj> obj;
- etl::handle<my_other_test_obj> other_obj;
- etl::loose_handle<my_other_test_obj> loose_obj;
- other_obj.spawn();
- loose_obj = other_obj;
- obj = etl::handle<my_test_obj>::cast_dynamic(loose_obj);
- if (obj != other_obj) {
- printf("FAILED!\n");
- printf(__FILE__":%d: on handle assignment from loose_handle.\n", __LINE__);
- return 1;
- }
- printf("PASSED\n");
- return 0;
- }
- int main()
- {
- int error = 0;
- error += handle_basic_test();
- error += handle_cast_test();
- error += handle_general_use_test();
- error += handle_inheritance_test();
- error += loose_handle_test();
- error += rhandle_general_use_test();
- return error;
- }
|