xref: /trunk/main/svl/inc/svl/cntnrsrt.hxx (revision 0c72d66f1a33589bfa5729d3fc3bdd5e807826ac)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _CNTRSRT_HXX
25 #define _CNTRSRT_HXX
26 
27 #if 0
28 ***********************************************************************
29 *
30 *   Hier folgt die Beschreibung fuer die exportierten Makros:
31 *
32 *       DECLARE_CONTAINER_SORT( ClassName, Type )
33 *       IMPL_CONTAINER_SORT( ClassName, Type, SortFunc )
34 *
35 *       Definiert eine von Container abgeleitete Klasse "ClassName",
36 *       in der die Elemente des Typs "Type" sortiert enthalten sind.
37 *       Dazu muss einer Funktion "SortFunc" definiert sein, die als
38 *       Parameter zwei "const Type&" erwartet und 0 zurueckgibt, wenn
39 *       beide gleich sind, -1 wenn der erste Parameter kleiner ist als
40 *       der zweite und +1 wenn der erste Parameter groesser ist als
41 *       der zweite.
42 *
43 *       Die Zugriffs-Methoden entsprechen in etwa denen der Container-
44 *       Klasse, mit Ausnahme von Insert, DeleteAndDestroy und Seek_Entry,
45 *       der den SV-Pointer-Arrays entsprechen.
46 *
47 *       DECLARE_CONTAINER_SORT_DEL( ClassName, Type )
48 *       IMPL_CONTAINER_SORT( ClassName, Type, SortFunc )
49 *
50 *       Wie DECLARE_CONTAINER_SORT, nur dass beim Aufruf des Destruktors
51 *       alle im Conatiner vorhandenen Objekte geloescht werden.
52 *
53 #endif
54 
55 #include <tools/contnr.hxx>
56 
57 #define DECLARE_CONTAINER_SORT_COMMON( ClassName, Type )                        \
58     ClassName( const ClassName& );                                          \
59     ClassName& operator =( const ClassName& );                              \
60 public:                                                                     \
61     using Container::Count;                                                 \
62                                                                             \
63     ClassName( sal_uInt16  InitSize, sal_uInt16  ReSize ) :                         \
64         Container( CONTAINER_MAXBLOCKSIZE, InitSize, ReSize )   {}          \
65                                                                             \
66     sal_Bool Insert( Type* pObj );                                              \
67                                                                             \
68     Type *Remove( sal_uLong nPos )                                              \
69         { return (Type *)Container::Remove( nPos ); }                       \
70                                                                             \
71     Type *Remove( Type* pObj );                                             \
72                                                                             \
73     void DeleteAndDestroy( sal_uLong nPos )                                     \
74     {                                                                       \
75         Type *pObj = Remove( nPos );                                        \
76         if( pObj )                                                          \
77             delete pObj;                                                    \
78     }                                                                       \
79                                                                             \
80     void DeleteAndDestroy()                                                 \
81         { while( Count() ) DeleteAndDestroy( 0 ); }                         \
82                                                                             \
83     Type* GetObject( sal_uLong nPos ) const                                     \
84         { return (Type *)Container::GetObject( nPos ); }                    \
85                                                                             \
86     Type* operator[]( sal_uLong nPos ) const                                    \
87         { return GetObject(nPos); }                                         \
88                                                                             \
89     sal_Bool Seek_Entry( const Type *pObj, sal_uLong* pPos ) const;                 \
90                                                                             \
91     sal_uLong GetPos( const Type* pObj ) const;                                 \
92 
93 
94 #define DECLARE_CONTAINER_SORT( ClassName, Type )                           \
95 class ClassName : private Container                                         \
96 {                                                                           \
97     DECLARE_CONTAINER_SORT_COMMON( ClassName, Type )                        \
98     ~ClassName() {}                                                         \
99 };                                                                          \
100 
101 
102 #define DECLARE_CONTAINER_SORT_DEL( ClassName, Type )                           \
103 class ClassName : private Container                                         \
104 {                                                                           \
105     DECLARE_CONTAINER_SORT_COMMON( ClassName, Type )                            \
106     ~ClassName() { DeleteAndDestroy(); }                                    \
107 };                                                                          \
108 
109 
110 #define IMPL_CONTAINER_SORT( ClassName, Type, SortFunc )                    \
111 sal_Bool ClassName::Insert( Type *pObj )                                        \
112 {                                                                           \
113     sal_uLong nPos;                                                             \
114     sal_Bool bExist = Seek_Entry( pObj, &nPos );                                \
115     if( !bExist )                                                           \
116         Container::Insert( pObj, nPos );                                    \
117     return !bExist;                                                         \
118 }                                                                           \
119                                                                             \
120 Type *ClassName::Remove( Type* pObj )                                       \
121 {                                                                           \
122     sal_uLong nPos;                                                             \
123     if( Seek_Entry( pObj, &nPos ) )                                         \
124         return Remove( nPos );                                              \
125     else                                                                    \
126         return 0;                                                           \
127 }                                                                           \
128                                                                             \
129 sal_uLong ClassName::GetPos( const Type* pObj ) const                           \
130 {                                                                           \
131     sal_uLong nPos;                                                             \
132     if( Seek_Entry( pObj, &nPos ) )                                         \
133         return nPos;                                                        \
134     else                                                                    \
135         return CONTAINER_ENTRY_NOTFOUND;                                    \
136 }                                                                           \
137                                                                             \
138 sal_Bool ClassName::Seek_Entry( const Type* pObj, sal_uLong* pPos ) const           \
139 {                                                                           \
140     sal_uLong nO  = Count(),                                           \
141             nM,                                                             \
142             nU = 0;                                                         \
143     if( nO > 0 )                                                            \
144     {                                                                       \
145         nO--;                                                               \
146         while( nU <= nO )                                                   \
147         {                                                                   \
148             nM = nU + ( nO - nU ) / 2;                                      \
149             int nCmp = SortFunc( *GetObject(nM), *pObj );                   \
150                                                                             \
151             if( 0 == nCmp )                                                 \
152             {                                                               \
153                 if( pPos ) *pPos = nM;                                      \
154                 return sal_True;                                                \
155             }                                                               \
156             else if( nCmp < 0 )                                             \
157                 nU = nM + 1;                                                \
158             else if( nM == 0 )                                              \
159             {                                                               \
160                 if( pPos ) *pPos = nU;                                      \
161                 return sal_False;                                               \
162             }                                                               \
163             else                                                            \
164                 nO = nM - 1;                                                \
165         }                                                                   \
166     }                                                                       \
167     if( pPos ) *pPos = nU;                                                  \
168     return sal_False;                                                           \
169 }                                                                           \
170 
171 #endif
172