Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ode/ode-0.9/OPCODE/Ice/IceContainer.h @ 216

Last change on this file since 216 was 216, checked in by mathiask, 16 years ago

[Physik] add ode-0.9

File size: 9.3 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 *      Contains a simple container class.
4 *      \file           IceContainer.h
5 *      \author         Pierre Terdiman
6 *      \date           February, 5, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICECONTAINER_H__
13#define __ICECONTAINER_H__
14
15        #define CONTAINER_STATS
16
17        enum FindMode
18        {
19                FIND_CLAMP,
20                FIND_WRAP,
21
22                FIND_FORCE_DWORD = 0x7fffffff
23        };
24
25        class ICECORE_API Container
26        {
27                public:
28                // Constructor / Destructor
29                                                                Container();
30                                                                Container(const Container& object);
31                                                                Container(udword size, float growth_factor);
32                                                                ~Container();
33                // Management
34                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35                /**
36                 *      A O(1) method to add a value in the container. The container is automatically resized if needed.
37                 *      The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
38                 *      costs a lot more than the call overhead...
39                 *
40                 *      \param          entry           [in] a udword to store in the container
41                 *      \see            Add(float entry)
42                 *      \see            Empty()
43                 *      \see            Contains(udword entry)
44                 *      \return         Self-Reference
45                 */
46                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
47                inline_ Container&              Add(udword entry)
48                                                                {
49                                                                        // Resize if needed
50                                                                        if(mCurNbEntries==mMaxNbEntries)        Resize();
51
52                                                                        // Add new entry
53                                                                        mEntries[mCurNbEntries++]       = entry;
54                                                                        return *this;
55                                                                }
56
57                inline_ Container&              Add(const udword* entries, udword nb)
58                                                                {
59                                                                        // Resize if needed
60                                                                        if(mCurNbEntries+nb>mMaxNbEntries)      Resize(nb);
61
62                                                                        // Add new entry
63                                                                        CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword));
64                                                                        mCurNbEntries+=nb;
65                                                                        return *this;
66                                                                }
67
68                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
69                /**
70                 *      A O(1) method to add a value in the container. The container is automatically resized if needed.
71                 *      The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
72                 *      costs a lot more than the call overhead...
73                 *
74                 *      \param          entry           [in] a float to store in the container
75                 *      \see            Add(udword entry)
76                 *      \see            Empty()
77                 *      \see            Contains(udword entry)
78                 *      \return         Self-Reference
79                 */
80                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81                inline_ Container&              Add(float entry)
82                                                                {
83                                                                        // Resize if needed
84                                                                        if(mCurNbEntries==mMaxNbEntries)        Resize();
85
86                                                                        // Add new entry
87                                                                        mEntries[mCurNbEntries++]       = IR(entry);
88                                                                        return *this;
89                                                                }
90
91                inline_ Container&              Add(const float* entries, udword nb)
92                                                                {
93                                                                        // Resize if needed
94                                                                        if(mCurNbEntries+nb>mMaxNbEntries)      Resize(nb);
95
96                                                                        // Add new entry
97                                                                        CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float));
98                                                                        mCurNbEntries+=nb;
99                                                                        return *this;
100                                                                }
101
102                //! Add unique [slow]
103                inline_ Container&              AddUnique(udword entry)
104                                                                {
105                                                                        if(!Contains(entry))    Add(entry);
106                                                                        return *this;
107                                                                }
108
109                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
110                /**
111                 *      Clears the container. All stored values are deleted, and it frees used ram.
112                 *      \see            Reset()
113                 *      \return         Self-Reference
114                 */
115                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116                                Container&              Empty();
117
118                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
119                /**
120                 *      Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again.
121                 *      That's a kind of temporal coherence.
122                 *      \see            Empty()
123                 */
124                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
125                inline_ void                    Reset()
126                                                                {
127                                                                        // Avoid the write if possible
128                                                                        // ### CMOV
129                                                                        if(mCurNbEntries)       mCurNbEntries = 0;
130                                                                }
131
132                // HANDLE WITH CARE
133                inline_ void                    ForceSize(udword size)
134                                                                {
135                                                                        mCurNbEntries = size;
136                                                                }
137
138                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
139                /**
140                 *      Sets the initial size of the container. If it already contains something, it's discarded.
141                 *      \param          nb              [in] Number of entries
142                 *      \return         true if success
143                 */
144                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
145                                bool                    SetSize(udword nb);
146
147                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
148                /**
149                 *      Refits the container and get rid of unused bytes.
150                 *      \return         true if success
151                 */
152                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
153                                bool                    Refit();
154
155                // Checks whether the container already contains a given value.
156                                bool                    Contains(udword entry, udword* location=null) const;
157                // Deletes an entry - doesn't preserve insertion order.
158                                bool                    Delete(udword entry);
159                // Deletes an entry - does preserve insertion order.
160                                bool                    DeleteKeepingOrder(udword entry);
161                //! Deletes the very last entry.
162                inline_ void                    DeleteLastEntry()                                               { if(mCurNbEntries)     mCurNbEntries--;                        }
163                //! Deletes the entry whose index is given
164                inline_ void                    DeleteIndex(udword index)                               { mEntries[index] = mEntries[--mCurNbEntries];  }
165
166                // Helpers
167                                Container&              FindNext(udword& entry, FindMode find_mode=FIND_CLAMP);
168                                Container&              FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP);
169                // Data access.
170                inline_ udword                  GetNbEntries()                                  const   { return mCurNbEntries;                                 }       //!< Returns the current number of entries.
171                inline_ udword                  GetEntry(udword i)                              const   { return mEntries[i];                                   }       //!< Returns ith entry
172                inline_ udword*                 GetEntries()                                    const   { return mEntries;                                              }       //!< Returns the list of entries.
173
174                inline_ udword                  GetFirst()                                              const   { return mEntries[0];                                   }
175                inline_ udword                  GetLast()                                               const   { return mEntries[mCurNbEntries-1];             }
176
177                // Growth control
178                inline_ float                   GetGrowthFactor()                               const   { return mGrowthFactor;                                 }       //!< Returns the growth factor
179                inline_ void                    SetGrowthFactor(float growth)                   { mGrowthFactor = growth;                               }       //!< Sets the growth factor
180                inline_ bool                    IsFull()                                                const   { return mCurNbEntries==mMaxNbEntries;  }       //!< Checks the container is full
181                inline_ BOOL                    IsNotEmpty()                                    const   { return mCurNbEntries;                                 }       //!< Checks the container is empty
182
183                //! Read-access as an array
184                inline_ udword                  operator[](udword i)                    const   { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i];  }
185                //! Write-access as an array
186                inline_ udword&                 operator[](udword i)                                    { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i];  }
187
188                // Stats
189                                udword                  GetUsedRam()                                    const;
190
191                //! Operator for "Container A = Container B"
192                                //void                  operator = (const Container& object);
193
194#ifdef CONTAINER_STATS
195                inline_ udword                  GetNbContainers()                               const   { return mNbContainers;         }
196                inline_ udword                  GetTotalBytes()                                 const   { return mUsedRam;                      }
197                private:
198
199                static  udword                  mNbContainers;          //!< Number of containers around
200                static  udword                  mUsedRam;                       //!< Amount of bytes used by containers in the system
201#endif
202                private:
203                // Resizing
204                                bool                    Resize(udword needed=1);
205                // Data
206                                udword                  mMaxNbEntries;          //!< Maximum possible number of entries
207                                udword                  mCurNbEntries;          //!< Current number of entries
208                                udword*                 mEntries;                       //!< List of entries
209                                float                   mGrowthFactor;          //!< Resize: new number of entries = old number * mGrowthFactor
210        };
211
212#endif // __ICECONTAINER_H__
Note: See TracBrowser for help on using the repository browser.