URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [tools/] [src/] [libcdl/] [testsuite/] [libcdl/] [cdl2.cxx] - Rev 528
Go to most recent revision | Compare with Previous | Blame | View Log
//========================================================================== // // cdl2.cxx // // Tests for the CdlHandle class. // //========================================================================== //####COPYRIGHTBEGIN#### // // ---------------------------------------------------------------------------- // Copyright (C) 1999, 2000 Red Hat, Inc. // // This file is part of the eCos host tools. // // This program 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 program 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. // // You should have received a copy of the GNU General Public License along with // this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // ---------------------------------------------------------------------------- // //####COPYRIGHTEND#### //========================================================================== //#####DESCRIPTIONBEGIN#### // // Author(s): bartv // Contributors: bartv // Date: 1999-01-12 // Description: Large parts of libcdl are implemented using a // CdlHandle template and a CdlRefcountSupport class. // This tests check that these both work as expected. // //####DESCRIPTIONEND#### //========================================================================== #include <cstdio> #include <cdlconfig.h> #include <cdl.hxx> #include <cyg/infra/cyg_ass.h> #include <cyg/infra/cyg_trac.h> #include <cyg/infra/testcase.h> #include <cstdlib> #ifndef CYGBLD_LIBCDL_USE_SMART_POINTERS int main(int argc, char** argv) { CYG_TEST_FAIL_FINISH("Smart pointers not yet enabled - waiting for a working version of Visual C++"); return EXIT_FAILURE; } #else // CYGBLD_LIBCDL_USE_SMART_POINTERS // ---------------------------------------------------------------------------- // Miscellaneous statics. // This routine controls the return value of a class1_body check_this() // operation, allowing test code to make sure that using check_this() // on a smart pointer works as expected. static bool check_this_ok = true; // ---------------------------------------------------------------------------- // This test case makes use of three implementation classes. It is necessary // to have forward declarations of these, and then it is possible to define // handle classes for each one. class class01_body; class class02_body; class derived_body; typedef CdlHandle<class01_body> class01; typedef CdlHandle<class02_body> class02; typedef CdlHandle<derived_body> derived; // ---------------------------------------------------------------------------- // This test needs three additional classes which are reference-counted and // which are accessed via CdlHandle smart pointers. It is necessary to start class class01_body : public CdlRefcountSupport { friend class CdlTest; public: static int class01_objects; class01_body() : CdlRefcountSupport() { class01_objects++; object_number = class01_objects; modifiable = 0; class01_body_cookie = class01_body_magic; } ~class01_body() { class01_objects--; class01_body_cookie = class01_body_invalid; } int get_number(void) { return object_number; } void modify(void) { modifiable++; } bool check_this(cyg_assert_class_zeal zeal) const { CYG_UNUSED_PARAM(cyg_assert_class_zeal, zeal); if (class01_body_magic != class01_body_cookie) { return false; } return check_this_ok; } private: // Which object is this? int object_number; int modifiable; class01_body(const class01_body&); class01_body& operator=(const class01_body&); enum { class01_body_invalid = 0, class01_body_magic = 0x015b19d6 } class01_body_cookie; }; class class02_body : public CdlRefcountSupport { friend class CdlTest; public: static int class02_objects; class02_body() : CdlRefcountSupport() { class02_objects++; class02_body_cookie = class02_body_magic; } ~class02_body() { class02_objects--; class02_body_cookie = class02_body_invalid; } bool check_this(cyg_assert_class_zeal zeal) const { CYG_UNUSED_PARAM(cyg_assert_class_zeal, zeal); return class02_body_magic == class02_body_cookie; } private: class02_body(const class02_body&); class02_body& operator=(const class02_body&); enum { class02_body_invalid = 0, class02_body_magic = 0x3225c96c } class02_body_cookie; }; class derived_body : public class01_body { friend class CdlTest; public: static int derived_objects; derived_body() : class01_body() { derived_objects++; derived_body_cookie = derived_body_magic; } ~derived_body() { derived_objects--; derived_body_cookie = derived_body_invalid; } bool check_this(cyg_assert_class_zeal zeal) const { if (derived_body_magic != derived_body_cookie) { return false; } return class01_body::check_this(zeal); } private: derived_body(const derived_body&); derived_body& operator=(const derived_body&); enum { derived_body_invalid = 0, derived_body_magic = 0x7ed15350 } derived_body_cookie; }; int class01_body::class01_objects = 0; int class02_body::class02_objects = 0; int derived_body::derived_objects = 0; // ---------------------------------------------------------------------------- // The actual test code. bool check_const_arg(const class01 const_ptr) { // Make sure that read-only access is allowed and goes to the right // object if (!const_ptr->check_this(cyg_quick)) { CYG_TEST_FAIL("check_this() on a constant pointer should be fine"); return false; } check_this_ok = false; if (const_ptr->check_this(cyg_quick)) { CYG_TEST_FAIL("check_this() on a constant pointer should be fine"); check_this_ok = true; return false; } check_this_ok = true; return true; } int main(int argc, char** argv) { bool ok = true; // Make sure that smart pointers do not impose any kind of overhead. if ((sizeof(void *) != sizeof(class01)) || (sizeof(void *) != sizeof(class02)) || (sizeof(void *) != sizeof(derived))) { CYG_TEST_FAIL("smart pointers are not the same size as dumb pointers"); } else { CYG_TEST_PASS("smart pointers are the same size as dumb pointers"); } // Start by creating a number of objects to be manipulated. class01_body * class01_obj1 = new class01_body; class01_body * class01_obj2 = new class01_body; class02_body * class02_obj1 = new class02_body; derived_body * derived_obj1 = new derived_body; // Quick sanity check if ((1 != derived_body::derived_objects) || (1 != class02_body::class02_objects) || (3 != class01_body::class01_objects)) { CYG_TEST_FAIL("Testcase has created an invalid number of objects"); } // Convert the basic objects to smart pointers. If this code compiles // then the test succeeds. class01 class01_ptr1 = class01(class01_obj1); class01 class01_ptr2 = class01(class01_obj2); class02 class02_ptr1 = class02(class02_obj1); derived derived_ptr1 = derived(derived_obj1); CYG_TEST_PASS("conversion to smart pointers works"); // Also create a couple of other smart pointers. These should be // initialised to 0. class01 class01_ptr3; class01 class01_ptr4 = 0; class01 class01_ptr5 = class01(0); CYG_TEST_PASS("smart pointers can have the value zero"); // Try to dereference the smart pointers. if ((1 != class01_ptr1->get_number()) || (2 != class01_ptr2->get_number()) || (3 != derived_ptr1->get_number())) { CYG_TEST_FAIL("-> dereferencing operator broken"); } else { CYG_TEST_PASS("-> dereferencing operator functional"); } if ((1 != (*class01_ptr1).get_number()) || (2 != (*class01_ptr2).get_number()) || (3 != (*derived_ptr1).get_number())) { CYG_TEST_FAIL("* dereferencing operator broken"); } else { CYG_TEST_PASS("* dereferencing operator functional"); } // Also try to access the check_this() member functions if (!class01_ptr1->check_this(cyg_quick)) { } // Do a couple of if's. This checks that the !operator is // functional. Some of the checks are there to make sure that the // compiler does the right thing. ok = true; if (!class01_ptr1) { CYG_TEST_FAIL("!(assigned smart pointer) is true"); ok = false; } if (0 == class01_ptr1) { CYG_TEST_FAIL("0 == assigned smart pointer"); ok = false; } if (0 != class01_ptr3) { CYG_TEST_FAIL("0 != unassigned smart pointer"); ok = false; } if (class01_ptr1 == 0) { CYG_TEST_FAIL("0 == assigned smart pointer"); ok = false; } if (class01_ptr3 != 0) { CYG_TEST_FAIL("0 != unassigned smart pointer"); ok = false; } if (class01_ptr1 == class01_ptr2) { CYG_TEST_FAIL("comparing two different smart pointers succeeds"); ok = false; } if (class01_ptr1 != class01_ptr2) { // Do nothing } else { CYG_TEST_FAIL("comparing two different smart pointers succeeds"); ok = false; } #if 0 // Comparing base and derived smart pointers directly does not work yet. if (class01_ptr1 == derived_ptr1) { CYG_TEST_FAIL("comparing different base and derived pointers succeeds"); } #endif if (ok) { CYG_TEST_PASS("smart pointer comparisons work"); } // Try some assignment operators. class01_ptr3 = class01_ptr1; class01_ptr4 = derived_ptr1; class01_ptr5 = class01_ptr2; // After doing all of these assignments there should be no change in // the number of underlying objects. ok = true; if ((1 != derived_body::derived_objects) || (1 != class02_body::class02_objects) || (3 != class01_body::class01_objects)) { ok = false; CYG_TEST_FAIL("Assignment of smart pointers has changed the underlying number of objects"); } if ((class01_ptr1 != class01_ptr3) || (class01_ptr2 != class01_ptr5)) { ok = false; CYG_TEST_FAIL("Assignment of smart pointers has not worked"); } if (class01_ptr4.get_dumb_pointer() != derived_ptr1.get_dumb_pointer()) { ok = false; CYG_TEST_FAIL("Assignment of derived to base smart pointer has not worked"); } if ((2 != class01_ptr1->get_refcount()) || (2 != class01_ptr2->get_refcount()) || (2 != class01_ptr4->get_refcount()) || (2 != derived_ptr1->get_refcount())) { ok = false; CYG_TEST_FAIL("Reference counts after assignment operators do not match up"); } if (ok) { CYG_TEST_PASS("Assignment of smart pointers"); } // Now try assigning zero. Incidentally this is necessary if the underlying // objects are to be destroyed again at the end. class01_ptr3 = 0; class01_ptr4 = 0; class01_ptr5 = 0; ok = true; if (0 != class01_ptr3) { ok = false; CYG_TEST_FAIL("assigning 0 to a smart pointer does not work"); } if ((1 != class01_ptr1->get_refcount()) || (1 != class01_ptr2->get_refcount()) || (1 != derived_ptr1->get_refcount())) { ok = false; CYG_TEST_FAIL("Reference counts after assignment operators do not match up"); } if (ok) { CYG_TEST_PASS("Assigning zero to smart pointers"); } // Make sure that implicit casts to const work. This is really // a compiler test. if (check_const_arg(class01_ptr1) && check_const_arg(derived_ptr1)) { CYG_TEST_PASS("Implicit cast to const smart pointer"); } #if 0 // All of this code should fail to compile. // Applying delete to a smart pointer does not work. Use destroy() instead. delete class01_ptr1; #endif #if 0 // Attempts to do incompatible assignments should fail. class01_ptr1 = class02_ptr1; #endif #if 0 // Comparing completely different types should fail. if (class01_ptr1 == class02_ptr1) { CYG_TEST_FAIL("it should not be possible to compare objects of different types"); } #endif #if 0 { const class01 const_class01_ptr = class01_ptr1; const_class01_ptr->modify(); } #endif #if 0 { const class01 const_derived_ptr = derived_ptr1; const_derived_ptr->modify(); } #endif // Check that destroy() actually gets rid of the underlying objects. class01_ptr1.destroy(); class01_ptr2.destroy(); class02_ptr1.destroy(); derived_ptr1.destroy(); if ((0 != derived_body::derived_objects) || (0 != class02_body::class02_objects) || (0 != class01_body::class01_objects)) { CYG_TEST_FAIL("There are still objects after the smart pointers have been destroyed"); } else { CYG_TEST_PASS("Using destroy() on the smart pointers cleans up the underlying objects"); } return EXIT_SUCCESS; } #endif
Go to most recent revision | Compare with Previous | Blame | View Log