1 /*---------------------------------------------------------------------------*
2   Project:  How to set up new/delete operators for C++
3   File:     cppsetupdemo.cpp
4 
5   Copyright 1998, 1999 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: cppsetupdemo.cpp,v $
14   Revision 1.2  02/20/2006 04:13:11  mitu
15   changed include path from dolphin/ to revolution/.
16 
17   Revision 1.1  01/13/2006 11:24:13  hiratsu
18   Initial check in.
19 
20 
21     4     6/11/01 7:55p Tian
22     Integrated SN changes
23 
24     3     3/16/01 12:04p Tian
25     Comments fix
26 
27     2     9/29/00 5:27p Tian
28     OS now supports pre-main new.
29 
30     1     6/22/00 7:24p Tian
31     Initial check-in.
32   $NoKeywords: $
33  *---------------------------------------------------------------------------*/
34 
35 /*---------------------------------------------------------------------------*
36   This demo shows how to override the standard new/delete operators with the
37   Dolphin OS memory allocator.  Note the following important caveats:
38 
39   - the standard Metrowerks new/delete operators are NOT supported,
40   and will cause a DSI exception if you attempt to use them.
41 
42   - this demo works because our new/delete operators occur earlier in
43   the link order than the Metrowerks Standard Libraries.  If the MSL
44   libraries occur earlier in the link order than your definition of
45   new/delete, then the MSL new/delete will be used throughout your
46   code.
47 
48   This demo does show how to use static global constructors.  The trick is
49   to initialize the heap in the first invocation of new().  The flag
50   /IsHeapInitialized/ is used in this example to indicate whether or not
51   the heap has been initialized.
52  *---------------------------------------------------------------------------*/
53 
54 #include <revolution.h>
55 #include <stddef.h>
56 /*---------------------------------------------------------------------------*
57   Override new and delete
58  *---------------------------------------------------------------------------*/
59 
60 #define HEAP_ID 0
61 
62 static BOOL IsHeapInitialized = FALSE;
63 
64 
65 /*---------------------------------------------------------------------------*
66   Name:         CPPInit
67 
68   Description:  Initializes the Dolphin OS memory allocator and ensures that
69                 new and delete will work properly.
70 
71   Arguments:    None.
72 
73   Returns:      None.
74  *---------------------------------------------------------------------------*/
CPPInit()75 static void CPPInit()
76 {
77     void*    arenaLo;
78     void*    arenaHi;
79 
80     if (IsHeapInitialized)
81     {
82         return;
83     }
84 
85 
86     arenaLo = OSGetArenaLo();
87     arenaHi = OSGetArenaHi();
88 
89     // Create a heap
90     // OSInitAlloc should only ever be invoked once.
91     arenaLo = OSInitAlloc(arenaLo, arenaHi, 1); // 1 heap
92     OSSetArenaLo(arenaLo);
93 
94     // Ensure boundaries are 32B aligned
95     arenaLo = (void*)OSRoundUp32B(arenaLo);
96     arenaHi = (void*)OSRoundDown32B(arenaHi);
97 
98     // The boundaries given to OSCreateHeap should be 32B aligned
99     OSSetCurrentHeap(OSCreateHeap(arenaLo, arenaHi));
100     // From here on out, OSAlloc and OSFree behave like malloc and free
101     // respectively
102     OSSetArenaLo(arenaLo=arenaHi);
103     IsHeapInitialized = TRUE;
104 
105 }
106 
operator new(size_t blocksize)107 inline void* operator new       ( size_t blocksize )
108 {
109     if (!IsHeapInitialized)
110     {
111         CPPInit();
112     }
113     return OSAllocFromHeap(HEAP_ID, blocksize);
114 }
115 
operator new[](size_t blocksize)116 inline void* operator new[]     ( size_t blocksize )
117 {
118     if (!IsHeapInitialized)
119     {
120         CPPInit();
121     }
122     return OSAllocFromHeap(HEAP_ID, blocksize);
123 }
124 
operator delete(void * block)125 inline void operator delete     ( void* block )
126 {
127     OSFreeToHeap(HEAP_ID, block);
128 }
129 
operator delete[](void * block)130 inline void operator delete[]   ( void* block )
131 {
132     OSFreeToHeap(HEAP_ID, block);
133 }
134 
135 
136 
137 /*---------------------------------------------------------------------------*
138   Trivial C++ code to test new and delete
139  *---------------------------------------------------------------------------*/
140 
141 
142 class Foo
143 {
144   private:
145     u32 a;
146     u32 b;
147     char* array;
148 
149   public:
150     Foo();
151     ~Foo();
152 
printA(void)153     void printA(void)
154     {
155         OSReport("a = %d\n", a);
156     }
157     void printB(void);
158 };
159 
160 
161 /*---------------------------------------------------------------------------*
162   Name:         Foo::Foo
163 
164   Description:  Constructor for class Foo.  Simply initialize private
165                 members.
166 
167   Arguments:
168 
169   Returns:
170  *---------------------------------------------------------------------------*/
Foo()171 Foo::Foo()
172 {
173     a = 42;
174     b = 24;
175 
176     array = new char[32];
177 }
178 
179 
180 /*---------------------------------------------------------------------------*
181   Name:         Foo::~Foo
182 
183   Description:  Destructor for class Foo.  Performs an OSReport so we know
184                 it got called properly.
185 
186   Arguments:
187 
188   Returns:
189  *---------------------------------------------------------------------------*/
~Foo()190 Foo::~Foo()
191 {
192     OSReport("Foo destructor\n");
193 }
194 
195 
196 
197 /*---------------------------------------------------------------------------*
198   Name:         Foo::printB
199 
200   Description:  function to print out b member
201 
202   Arguments:
203 
204   Returns:
205  *---------------------------------------------------------------------------*/
printB()206 void Foo::printB()
207 {
208     OSReport("b = %d\n", b);
209 }
210 static Foo StaticFoo;
211 
212 
main()213 int main()
214 {
215     Foo * foo;
216 
217     OSInit();
218     CPPInit();
219 
220     foo = new Foo;
221 
222     foo->printA();
223     foo->printB();
224     StaticFoo.printA();
225 
226     delete foo;
227 	return 0;
228 }
229