xref: /AOO41X/main/svl/inc/svl/cntnrsrt.hxx (revision 39a19a47feaddbaa21988da8c7bf801707fd3d48)
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 #ifndef _CNTRSRT_HXX
24 #define _CNTRSRT_HXX
25 
26 #if 0
27 ***********************************************************************
28 *
29 *   Hier folgt die Beschreibung fuer die exportierten Makros:
30 *
31 *       DECLARE_CONTAINER_SORT( ClassName, Type )
32 *       IMPL_CONTAINER_SORT( ClassName, Type, SortFunc )
33 *
34 *       Definiert eine von Container abgeleitete Klasse "ClassName",
35 *       in der die Elemente des Typs "Type" sortiert enthalten sind.
36 *       Dazu muss einer Funktion "SortFunc" definiert sein, die als
37 *       Paramter zwei "const Type&" erwartet und 0 zurueckgibt, wenn
38 *       beide gleich sind, -1 wenn der erste Paramter kleiner ist als
39 *       der zweite und +1 wenn der erste Paramter groesser ist als
40 *       der zweite.
41 *
42 *       Die Zugriffs-Methoden entsprechen in etwa denen der Container-
43 *       Klasse, mit Ausnahme von Insert, DeleteAndDestroy und Seek_Entry,
44 *       der den SV-Pointer-Arrays entsprechen.
45 *
46 *       DECLARE_CONTAINER_SORT_DEL( ClassName, Type )
47 *       IMPL_CONTAINER_SORT( ClassName, Type, SortFunc )
48 *
49 *       Wie DECLARE_CONTAINER_SORT, nur dass beim Aufruf des Destruktors
50 *       alle im Conatiner vorhandenen Objekte geloescht werden.
51 *
52 #endif
53 
54 #include <tools/contnr.hxx>
55 
56 #define DECLARE_CONTAINER_SORT_COMMON( ClassName, Type )                        \
57     ClassName( const ClassName& );                                          \
58     ClassName& operator =( const ClassName& );                              \
59 public:                                                                     \
60     using Container::Count;                                                 \
61                                                                             \
62     ClassName( sal_uInt16  InitSize, sal_uInt16  ReSize ) :                         \
63         Container( CONTAINER_MAXBLOCKSIZE, InitSize, ReSize )   {}          \
64                                                                             \
65     sal_Bool Insert( Type* pObj );                                              \
66                                                                             \
67     Type *Remove( sal_uLong nPos )                                              \
68         { return (Type *)Container::Remove( nPos ); }                       \
69                                                                             \
70     Type *Remove( Type* pObj );                                             \
71                                                                             \
72     void DeleteAndDestroy( sal_uLong nPos )                                     \
73     {                                                                       \
74         Type *pObj = Remove( nPos );                                        \
75         if( pObj )                                                          \
76             delete pObj;                                                    \
77     }                                                                       \
78                                                                             \
79     void DeleteAndDestroy()                                                 \
80         { while( Count() ) DeleteAndDestroy( 0 ); }                         \
81                                                                             \
82     Type* GetObject( sal_uLong nPos ) const                                     \
83         { return (Type *)Container::GetObject( nPos ); }                    \
84                                                                             \
85     Type* operator[]( sal_uLong nPos ) const                                    \
86         { return GetObject(nPos); }                                         \
87                                                                             \
88     sal_Bool Seek_Entry( const Type *pObj, sal_uLong* pPos ) const;                 \
89                                                                             \
90     sal_uLong GetPos( const Type* pObj ) const;                                 \
91 
92 
93 #define DECLARE_CONTAINER_SORT( ClassName, Type )                           \
94 class ClassName : private Container                                         \
95 {                                                                           \
96     DECLARE_CONTAINER_SORT_COMMON( ClassName, Type )                        \
97     ~ClassName() {}                                                         \
98 };                                                                          \
99 
100 
101 #define DECLARE_CONTAINER_SORT_DEL( ClassName, Type )                           \
102 class ClassName : private Container                                         \
103 {                                                                           \
104     DECLARE_CONTAINER_SORT_COMMON( ClassName, Type )                            \
105     ~ClassName() { DeleteAndDestroy(); }                                    \
106 };                                                                          \
107 
108 
109 #define IMPL_CONTAINER_SORT( ClassName, Type, SortFunc )                    \
110 sal_Bool ClassName::Insert( Type *pObj )                                        \
111 {                                                                           \
112     sal_uLong nPos;                                                             \
113     sal_Bool bExist = Seek_Entry( pObj, &nPos );                                \
114     if( !bExist )                                                           \
115         Container::Insert( pObj, nPos );                                    \
116     return !bExist;                                                         \
117 }                                                                           \
118                                                                             \
119 Type *ClassName::Remove( Type* pObj )                                       \
120 {                                                                           \
121     sal_uLong nPos;                                                             \
122     if( Seek_Entry( pObj, &nPos ) )                                         \
123         return Remove( nPos );                                              \
124     else                                                                    \
125         return 0;                                                           \
126 }                                                                           \
127                                                                             \
128 sal_uLong ClassName::GetPos( const Type* pObj ) const                           \
129 {                                                                           \
130     sal_uLong nPos;                                                             \
131     if( Seek_Entry( pObj, &nPos ) )                                         \
132         return nPos;                                                        \
133     else                                                                    \
134         return CONTAINER_ENTRY_NOTFOUND;                                    \
135 }                                                                           \
136                                                                             \
137 sal_Bool ClassName::Seek_Entry( const Type* pObj, sal_uLong* pPos ) const           \
138 {                                                                           \
139     register sal_uLong nO  = Count(),                                           \
140             nM,                                                             \
141             nU = 0;                                                         \
142     if( nO > 0 )                                                            \
143     {                                                                       \
144         nO--;                                                               \
145         while( nU <= nO )                                                   \
146         {                                                                   \
147             nM = nU + ( nO - nU ) / 2;                                      \
148             int nCmp = SortFunc( *GetObject(nM), *pObj );                   \
149                                                                             \
150             if( 0 == nCmp )                                                 \
151             {                                                               \
152                 if( pPos ) *pPos = nM;                                      \
153                 return sal_True;                                                \
154             }                                                               \
155             else if( nCmp < 0 )                                             \
156                 nU = nM + 1;                                                \
157             else if( nM == 0 )                                              \
158             {                                                               \
159                 if( pPos ) *pPos = nU;                                      \
160                 return sal_False;                                               \
161             }                                                               \
162             else                                                            \
163                 nO = nM - 1;                                                \
164         }                                                                   \
165     }                                                                       \
166     if( pPos ) *pPos = nU;                                                  \
167     return sal_False;                                                           \
168 }                                                                           \
169 
170 #endif
171