source: SVN/cambria/redboot/host/libcdl/testsuite/libcdl/cdl2.cxx @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 13.7 KB
Line 
1//==========================================================================
2//
3//      cdl2.cxx
4//
5//      Tests for the CdlHandle class.
6//
7//==========================================================================
8//####COPYRIGHTBEGIN####
9//                                                                         
10// ----------------------------------------------------------------------------
11// Copyright (C) 1999, 2000 Red Hat, Inc.
12//
13// This file is part of the eCos host tools.
14//
15// This program is free software; you can redistribute it and/or modify it
16// under the terms of the GNU General Public License as published by the Free
17// Software Foundation; either version 2 of the License, or (at your option)
18// any later version.
19//
20// This program is distributed in the hope that it will be useful, but WITHOUT
21// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
23// more details.
24//
25// You should have received a copy of the GNU General Public License along with
26// this program; if not, write to the Free Software Foundation, Inc.,
27// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28//
29// ----------------------------------------------------------------------------
30//                                                                         
31//####COPYRIGHTEND####
32//==========================================================================
33//#####DESCRIPTIONBEGIN####                                             
34//
35// Author(s):           bartv
36// Contributors:        bartv
37// Date:                1999-01-12
38// Description:         Large parts of libcdl are implemented using a
39//                      CdlHandle template and a CdlRefcountSupport class.
40//                      This tests check that these both work as expected.
41//
42//####DESCRIPTIONEND####
43//==========================================================================
44
45#include <cstdio>
46#include <cdlconfig.h>
47#include <cdl.hxx>
48#include <cyg/infra/cyg_ass.h>
49#include <cyg/infra/cyg_trac.h>
50#include <cyg/infra/testcase.h>
51#include <cstdlib>
52
53#ifndef CYGBLD_LIBCDL_USE_SMART_POINTERS
54int
55main(int argc, char** argv)
56{
57    CYG_TEST_FAIL_FINISH("Smart pointers not yet enabled - waiting for a working version of Visual C++");
58    return EXIT_FAILURE;
59}
60#else // CYGBLD_LIBCDL_USE_SMART_POINTERS
61// ----------------------------------------------------------------------------
62// Miscellaneous statics.
63
64// This routine controls the return value of a class1_body check_this()
65// operation, allowing test code to make sure that using check_this()
66// on a smart pointer works as expected.
67static bool check_this_ok = true;
68
69// ----------------------------------------------------------------------------
70// This test case makes use of three implementation classes. It is necessary
71// to have forward declarations of these, and then it is possible to define
72// handle classes for each one.
73class class01_body;
74class class02_body;
75class derived_body;
76
77typedef CdlHandle<class01_body> class01;
78typedef CdlHandle<class02_body> class02;
79typedef CdlHandle<derived_body> derived;
80
81// ----------------------------------------------------------------------------
82// This test needs three additional classes which are reference-counted and
83// which are accessed via CdlHandle smart pointers. It is necessary to start
84
85class class01_body : public CdlRefcountSupport {
86
87    friend class CdlTest;
88   
89  public:
90
91    static int class01_objects;
92    class01_body() : CdlRefcountSupport() {
93        class01_objects++;
94        object_number = class01_objects;
95        modifiable    = 0;
96        class01_body_cookie = class01_body_magic;
97    }
98    ~class01_body() {
99        class01_objects--;
100        class01_body_cookie = class01_body_invalid;
101    }
102    int
103    get_number(void) {
104        return object_number;
105    }
106    void
107    modify(void) {
108        modifiable++;
109    }
110    bool check_this(cyg_assert_class_zeal zeal) const {
111        CYG_UNUSED_PARAM(cyg_assert_class_zeal, zeal);
112        if (class01_body_magic != class01_body_cookie) {
113            return false;
114        }
115        return check_this_ok;
116    }
117   
118  private:
119    // Which object is this?
120    int object_number;
121    int modifiable;
122   
123    class01_body(const class01_body&);
124    class01_body& operator=(const class01_body&);
125    enum {
126        class01_body_invalid     = 0,
127        class01_body_magic       = 0x015b19d6
128    } class01_body_cookie;
129};
130
131class class02_body : public CdlRefcountSupport {
132
133    friend class CdlTest;
134   
135  public:
136    static int class02_objects;
137    class02_body() : CdlRefcountSupport() {
138        class02_objects++;
139        class02_body_cookie = class02_body_magic;
140    }
141    ~class02_body() {
142        class02_objects--;
143        class02_body_cookie = class02_body_invalid;
144    }
145
146    bool check_this(cyg_assert_class_zeal zeal) const {
147        CYG_UNUSED_PARAM(cyg_assert_class_zeal, zeal);
148        return class02_body_magic == class02_body_cookie;
149    }
150
151  private:
152    class02_body(const class02_body&);
153    class02_body& operator=(const class02_body&);
154    enum {
155        class02_body_invalid     = 0,
156        class02_body_magic       = 0x3225c96c
157    } class02_body_cookie;
158};
159
160class derived_body : public class01_body {
161
162    friend class CdlTest;
163   
164  public:
165    static int derived_objects;
166    derived_body() : class01_body() {
167        derived_objects++;
168        derived_body_cookie = derived_body_magic;
169    }
170    ~derived_body() {
171        derived_objects--;
172        derived_body_cookie = derived_body_invalid;
173    }
174    bool check_this(cyg_assert_class_zeal zeal) const {
175        if (derived_body_magic != derived_body_cookie) {
176            return false;
177        }
178        return class01_body::check_this(zeal);
179    }
180
181  private:
182    derived_body(const derived_body&);
183    derived_body& operator=(const derived_body&);
184    enum {
185        derived_body_invalid    = 0,
186        derived_body_magic      = 0x7ed15350
187    } derived_body_cookie;
188};
189
190int class01_body::class01_objects   = 0;
191int class02_body::class02_objects   = 0;
192int derived_body::derived_objects   = 0;
193
194// ----------------------------------------------------------------------------
195// The actual test code.
196
197bool
198check_const_arg(const class01 const_ptr)
199{
200    // Make sure that read-only access is allowed and goes to the right
201    // object
202    if (!const_ptr->check_this(cyg_quick)) {
203        CYG_TEST_FAIL("check_this() on a constant pointer should be fine");
204        return false;
205    }
206    check_this_ok = false;
207    if (const_ptr->check_this(cyg_quick)) {
208        CYG_TEST_FAIL("check_this() on a constant pointer should be fine");
209        check_this_ok = true;
210        return false;
211    }
212    check_this_ok = true;
213    return true;
214}
215
216int
217main(int argc, char** argv)
218{
219    bool ok = true;
220
221    // Make sure that smart pointers do not impose any kind of overhead.
222    if ((sizeof(void *) != sizeof(class01)) ||
223        (sizeof(void *) != sizeof(class02)) ||
224        (sizeof(void *) != sizeof(derived))) {
225
226        CYG_TEST_FAIL("smart pointers are not the same size as dumb pointers");
227    } else {
228        CYG_TEST_PASS("smart pointers are the same size as dumb pointers");
229    }
230   
231    // Start by creating a number of objects to be manipulated.
232    class01_body *      class01_obj1    = new class01_body;
233    class01_body *      class01_obj2    = new class01_body;
234    class02_body *      class02_obj1    = new class02_body;
235    derived_body *      derived_obj1    = new derived_body;
236
237    // Quick sanity check
238    if ((1 != derived_body::derived_objects) ||
239        (1 != class02_body::class02_objects) ||
240        (3 != class01_body::class01_objects)) {
241        CYG_TEST_FAIL("Testcase has created an invalid number of objects");
242    }
243
244    // Convert the basic objects to smart pointers. If this code compiles
245    // then the test succeeds.
246    class01     class01_ptr1    = class01(class01_obj1);
247    class01     class01_ptr2    = class01(class01_obj2);
248    class02     class02_ptr1    = class02(class02_obj1);
249    derived     derived_ptr1    = derived(derived_obj1);
250    CYG_TEST_PASS("conversion to smart pointers works");
251
252    // Also create a couple of other smart pointers. These should be
253    // initialised to 0.
254    class01      class01_ptr3;
255    class01      class01_ptr4     = 0;
256    class01      class01_ptr5     = class01(0);
257    CYG_TEST_PASS("smart pointers can have the value zero");
258
259    // Try to dereference the smart pointers.
260    if ((1 != class01_ptr1->get_number()) ||
261        (2 != class01_ptr2->get_number()) ||
262        (3 != derived_ptr1->get_number())) {
263        CYG_TEST_FAIL("-> dereferencing operator broken");
264    } else {
265        CYG_TEST_PASS("-> dereferencing operator functional");
266    }
267    if ((1 != (*class01_ptr1).get_number()) ||
268        (2 != (*class01_ptr2).get_number()) ||
269        (3 != (*derived_ptr1).get_number())) {
270        CYG_TEST_FAIL("* dereferencing operator broken");
271    } else {
272        CYG_TEST_PASS("* dereferencing operator functional");
273    }
274
275    // Also try to access the check_this() member functions
276    if (!class01_ptr1->check_this(cyg_quick)) {
277    }
278   
279    // Do a couple of if's. This checks that the !operator is
280    // functional. Some of the checks are there to make sure that the
281    // compiler does the right thing.
282    ok = true;
283    if (!class01_ptr1) {
284        CYG_TEST_FAIL("!(assigned smart pointer) is true");
285        ok = false;
286    }
287    if (0 == class01_ptr1) {
288        CYG_TEST_FAIL("0 == assigned smart pointer");
289        ok = false;
290    }
291    if (0 != class01_ptr3) {
292        CYG_TEST_FAIL("0 != unassigned smart pointer");
293        ok = false;
294    }
295    if (class01_ptr1 == 0) {
296        CYG_TEST_FAIL("0 == assigned smart pointer");
297        ok = false;
298    }
299    if (class01_ptr3 != 0) {
300        CYG_TEST_FAIL("0 != unassigned smart pointer");
301        ok = false;
302    }
303    if (class01_ptr1 == class01_ptr2) {
304        CYG_TEST_FAIL("comparing two different smart pointers succeeds");
305        ok = false;
306    }
307    if (class01_ptr1 != class01_ptr2) {
308        // Do nothing
309    } else {
310        CYG_TEST_FAIL("comparing two different smart pointers succeeds");
311        ok = false;
312    }
313#if 0
314    // Comparing base and derived smart pointers directly does not work yet.
315    if (class01_ptr1 == derived_ptr1) {
316        CYG_TEST_FAIL("comparing different base and derived pointers succeeds");
317    }
318#endif
319    if (ok) {
320        CYG_TEST_PASS("smart pointer comparisons work");
321    }
322   
323    // Try some  assignment operators.
324    class01_ptr3 = class01_ptr1;
325    class01_ptr4 = derived_ptr1;
326    class01_ptr5 = class01_ptr2;
327
328    // After doing all of these assignments there should be no change in
329    // the number of underlying objects.
330    ok = true;
331    if ((1 != derived_body::derived_objects) ||
332        (1 != class02_body::class02_objects)   ||
333        (3 != class01_body::class01_objects)) {
334        ok = false;
335        CYG_TEST_FAIL("Assignment of smart pointers has changed the underlying number of objects");
336    }
337    if ((class01_ptr1 != class01_ptr3) ||
338        (class01_ptr2 != class01_ptr5)) {
339        ok = false;
340        CYG_TEST_FAIL("Assignment of smart pointers has not worked");
341    }
342    if (class01_ptr4.get_dumb_pointer() != derived_ptr1.get_dumb_pointer()) {
343        ok = false;
344        CYG_TEST_FAIL("Assignment of derived to base smart pointer has not worked");
345    }
346    if ((2 != class01_ptr1->get_refcount()) ||
347        (2 != class01_ptr2->get_refcount()) ||
348        (2 != class01_ptr4->get_refcount()) ||
349        (2 != derived_ptr1->get_refcount())) {
350        ok = false;
351        CYG_TEST_FAIL("Reference counts after assignment operators do not match up");
352    }
353    if (ok) {
354        CYG_TEST_PASS("Assignment of smart pointers");
355    }
356
357    // Now try assigning zero. Incidentally this is necessary if the underlying
358    // objects are to be destroyed again at the end.
359    class01_ptr3 = 0;
360    class01_ptr4 = 0;
361    class01_ptr5 = 0;
362
363    ok = true;
364    if (0 != class01_ptr3) {
365        ok = false;
366        CYG_TEST_FAIL("assigning 0 to a smart pointer does not work");
367    }
368    if ((1 != class01_ptr1->get_refcount()) ||
369        (1 != class01_ptr2->get_refcount()) ||
370        (1 != derived_ptr1->get_refcount())) {
371        ok = false;
372        CYG_TEST_FAIL("Reference counts after assignment operators do not match up");
373    }
374    if (ok) {
375        CYG_TEST_PASS("Assigning zero to smart pointers");
376    }
377
378    // Make sure that implicit casts to const work. This is really
379    // a compiler test.
380    if (check_const_arg(class01_ptr1) &&
381        check_const_arg(derived_ptr1)) {
382        CYG_TEST_PASS("Implicit cast to const smart pointer");
383    }
384   
385#if 0
386    // All of this code should fail to compile.
387    // Applying delete to a smart pointer does not work. Use destroy() instead.
388    delete class01_ptr1;
389#endif
390#if 0
391    // Attempts to do incompatible assignments should fail.
392    class01_ptr1 = class02_ptr1;
393#endif
394#if 0   
395    // Comparing completely different types should fail.
396    if (class01_ptr1 == class02_ptr1) {
397        CYG_TEST_FAIL("it should not be possible to compare objects of different types");
398    }
399#endif
400#if 0
401    {
402        const class01 const_class01_ptr = class01_ptr1;
403        const_class01_ptr->modify();
404    }
405#endif
406#if 0
407    {
408        const class01 const_derived_ptr = derived_ptr1;
409        const_derived_ptr->modify();
410    }
411#endif
412   
413    // Check that destroy() actually gets rid of the underlying objects.
414    class01_ptr1.destroy();
415    class01_ptr2.destroy();
416    class02_ptr1.destroy();
417    derived_ptr1.destroy();
418    if ((0 != derived_body::derived_objects) ||
419        (0 != class02_body::class02_objects)    ||
420        (0 != class01_body::class01_objects)) {
421        CYG_TEST_FAIL("There are still objects after the smart pointers have been destroyed");
422    } else {
423        CYG_TEST_PASS("Using destroy() on the smart pointers cleans up the underlying objects");
424    }
425
426    return EXIT_SUCCESS;
427}
428#endif
Note: See TracBrowser for help on using the repository browser.