coan 4.2.4
ptr_vector.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004, 2006 Symbian Software Ltd.                        *
00003  *   All rights reserved.                                                  *
00004  *                                                                         *
00005  *   Contributed originally by Mike Kinghan, imk@strudl.org                *
00006  *                                                                         *
00007  *   Redistribution and use in source and binary forms, with or without    *
00008  *   modification, are permitted provided that the following conditions    *
00009  *   are met:                                                              *
00010  *                                                                         *
00011  *   Redistributions of source code must retain the above copyright        *
00012  *   notice, this list of conditions and the following disclaimer.         *
00013  *                                                                         *
00014  *   Redistributions in binary form must reproduce the above copyright     *
00015  *   notice, this list of conditions and the following disclaimer in the   *
00016  *   documentation and/or other materials provided with the distribution.  *
00017  *                                                                         *
00018  *   Neither the name of Symbian Software Ltd. nor the names of its        *
00019  *   contributors may be used to endorse or promote products derived from  *
00020  *   this software without specific prior written permission.              *
00021  *                                                                         *
00022  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   *
00023  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     *
00024  *   LIMITED TO, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS    *
00025  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        *
00026  *   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,   *
00027  *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  *
00028  *   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
00029  *   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    *
00030  *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,*
00031  *   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
00032  *   THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  *
00033  *   DAMAGE.                                                               *
00034  *                                                                         *
00035  **************************************************************************/
00036 #include "ptr_vector.h"
00037 #include "report.h"
00038 #include "swiss_army.h"
00039 
00047 
00049 struct ptr_vector {
00052     size_t tranch;
00054     size_t count;
00057     size_t cap;
00059     dtor_t dtor;
00061     cloner_t cloner;
00063     void **ptrs;
00064 };
00065 
00071 static void *
00072 default_cloner(void const * src)
00073 {
00074     return clone(src,0);
00075 }
00076 
00086 static void
00087 ptr_vector_init(ptr_vector_h pv, dtor_t dtor, cloner_t cloner)
00088 {
00089     pv->cap = pv->count = 0;
00090     pv->tranch = 16 * sizeof(void *);
00091     pv->dtor = dtor ? dtor : free;
00092     pv->cloner = cloner ? cloner : default_cloner;
00093     pv->ptrs = NULL;
00094 }
00095 
00103 static void
00104 ptr_vector_copy_init(ptr_vector_h dest, ptr_vector_const_h src)
00105 {
00106     void const ** begin = ptr_vector_begin_const(src);
00107     void const **end = ptr_vector_end_const(src);
00108     cloner_t cloner = src->cloner;
00109     ptr_vector_init(dest,src->dtor,src->cloner);
00110     begin = ptr_vector_begin_const(src);
00111     end = ptr_vector_end_const(src);
00112     for (       ; begin != end; ++begin) {
00113         ptr_vector_append(dest,cloner(*begin));
00114     }
00115 }
00116 
00120 static void
00121 ptr_vector_finis(ptr_vector_h pv)
00122 {
00123     if (pv->ptrs) {
00124         void **begin = pv->ptrs;
00125         void **end = pv->ptrs + pv->count;
00126         for (   ; begin != end; ++begin) {
00127             pv->dtor(*begin);
00128         }
00129         free(pv->ptrs);
00130         pv->ptrs = NULL;
00131     }
00132 }
00133 
00136 /* API **************************************************************/
00137 
00140 
00141 ptr_vector_h
00142 ptr_vector_new(dtor_t dtor, cloner_t cloner)
00143 {
00144     ptr_vector_h  pv = zallocate(sizeof(struct ptr_vector));
00145     ptr_vector_init(pv,dtor,cloner);
00146     return pv;
00147 }
00148 
00149 void
00150 ptr_vector_dispose(ptr_vector_h pv)
00151 {
00152     if (pv) {
00153         ptr_vector_finis(pv);
00154         free(pv);
00155     }
00156 }
00157 
00158 void
00159 ptr_vector_drop(ptr_vector_h pv)
00160 {
00161     if (pv) {
00162         free(pv);
00163     }
00164 }
00165 
00166 ptr_vector_h
00167 ptr_vector_copy(ptr_vector_const_h src)
00168 {
00169     ptr_vector_h pv;
00170     assert(src);
00171     pv = zallocate(sizeof(struct ptr_vector));
00172     ptr_vector_copy_init(pv,src);
00173     return pv;
00174 }
00175 
00176 void
00177 ptr_vector_swap(ptr_vector_h lhs, ptr_vector_h rhs)
00178 {
00179     assert(lhs);
00180     assert(rhs);
00181     PODSWAP(size_t,&lhs->tranch,&rhs->tranch);
00182     PODSWAP(size_t,&lhs->count,&rhs->count);
00183     PODSWAP(size_t,&lhs->cap,&rhs->cap);
00184     PODSWAP(dtor_t,&lhs->dtor,&rhs->dtor);
00185     PODSWAP(cloner_t,&lhs->cloner,&rhs->cloner);
00186     PODSWAP(void **,&lhs->ptrs,&rhs->ptrs);
00187 }
00188 
00189 void
00190 ptr_vector_assign(ptr_vector_h dest, ptr_vector_const_h src)
00191 {
00192     if (dest != src) {
00193         ptr_vector_h tmp = ptr_vector_copy(src);
00194         ptr_vector_swap(dest,tmp);
00195         ptr_vector_dispose(tmp);
00196     }
00197 }
00198 
00199 void
00200 ptr_vector_insert(ptr_vector_h pv, size_t pos, void const *ptr)
00201 {
00202     if (pv->count == pv->cap) {
00203         pv->cap += pv->tranch;
00204         pv->ptrs = reallocate(pv->ptrs,pv->cap * sizeof(void *));
00205         pv->tranch <<= 1;
00206     }
00207     if (pos >= pv->count) {
00208         pv->ptrs[pv->count++] = (void*)ptr;
00209     } else {
00210         memmove(pv->ptrs + pos + 1,
00211                 pv->ptrs + pos,
00212                 ((pv->count - pos) * sizeof(void *)));
00213         pv->ptrs[pos] = (void *)ptr;
00214         ++pv->count;
00215     }
00216 }
00217 
00218 bool
00219 ptr_vector_delete(ptr_vector_h pv, size_t pos)
00220 {
00221     if (pos < pv->count) {
00222         memmove(pv->ptrs + pos,
00223         pv->ptrs + pos + 1,
00224         ((pv->count - 1 + pos) * sizeof(void *)));
00225         --pv->count;
00226         return true;
00227     }
00228     return false;
00229 }
00230 
00231 bool
00232 ptr_vector_equal(       ptr_vector_const_h lhs,
00233                     ptr_vector_const_h rhs,
00234                     comparator_t compare)
00235 {
00236     if (lhs != rhs) {
00237         assert(lhs);
00238         assert(rhs);
00239         if (lhs->dtor == rhs->dtor && lhs->cloner == rhs->cloner) {
00240             if (ptr_vector_count(lhs) == ptr_vector_count(rhs)) {
00241                 void const ** lh_iter = ptr_vector_begin_const(lhs);
00242                 void const ** rh_iter = ptr_vector_begin_const(rhs);
00243                 void const ** lh_end = ptr_vector_end_const(lhs);
00244                 for     (       ; lh_iter != lh_end; ++lh_iter,++rh_iter) {
00245                     if (compare(*lh_iter,*rh_iter,0)) {
00246                         return false;
00247                     }
00248                 }
00249                 return true;
00250             }
00251         }
00252         return false;
00253     }
00254     return true;
00255 }
00256 
00257 dtor_t
00258 ptr_vector_dtor(ptr_vector_const_h pv)
00259 {
00260     assert(pv);
00261     return pv->dtor;
00262 }
00263 
00264 cloner_t
00265 ptr_vector_cloner(ptr_vector_const_h pv)
00266 {
00267     assert(pv);
00268     return pv->cloner;
00269 }
00270 
00271 
00272 void
00273 ptr_vector_append(ptr_vector_h pv, void *ptr)
00274 {
00275     ptr_vector_insert(pv,(size_t)-1,ptr);
00276 }
00277 
00278 size_t
00279 ptr_vector_count(ptr_vector_const_h pv)
00280 {
00281     return pv->count;
00282 }
00283 
00284 void **
00285 ptr_vector_begin(ptr_vector_h pv)
00286 {
00287     return pv->ptrs;
00288 }
00289 
00290 void const **
00291 ptr_vector_begin_const(ptr_vector_const_h pv)
00292 {
00293     return (void const **)ptr_vector_begin((ptr_vector_h)pv);
00294 }
00295 
00296 void **
00297 ptr_vector_end(ptr_vector_h pv)
00298 {
00299     return pv->ptrs + pv->count;
00300 }
00301 
00302 void const **
00303 ptr_vector_end_const(ptr_vector_const_h pv)
00304 {
00305     return (void const **)ptr_vector_end((ptr_vector_h)pv);
00306 }
00307 
00308 void *
00309 ptr_vector_at(ptr_vector_h pv, size_t pos)
00310 {
00311     return (pos < pv->count) ? pv->ptrs[pos] : 0;
00312 }
00313 
00314 void const *
00315 ptr_vector_at_const(ptr_vector_const_h pv, size_t pos)
00316 {
00317     return (void const *)ptr_vector_at((ptr_vector_h)pv,pos);
00318 }
00319 
00320 locator_t
00321 ptr_vector_search(      ptr_vector_const_h pv,
00322                     void const *key,
00323                     locator_t keylen,
00324                     comparator_t compare,
00325                     bool ordered)
00326 {
00327     locator_t comp = 1;
00328     void const ** begin = ptr_vector_begin_const(pv);
00329     void const ** end = ptr_vector_end_const(pv);
00330     void const ** iter = begin;
00331     if (!ordered) {
00332         for ( iter = begin; iter != end; ++iter) {
00333             comp = compare(*iter,key,keylen);
00334             if (!comp) {
00335                 break;
00336             }
00337         }
00338     } else {
00339         for ( iter = begin; iter != end; ++iter) {
00340             comp = compare(*iter,key,keylen);
00341             if (comp >= 0) {
00342                 break;
00343             }
00344         }
00345     }
00346     comp = comp ? ~(iter - begin) : iter - begin;
00347     return comp;
00348 }
00349 
00352 /* EOF*/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines