coan 4.2.4
ptr_set.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007-2011 Mike Kinghan, imk@strudl.org                  *
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 
00037 #include "ptr_set.h"
00038 #include "memory.h"
00039 #include "swiss_army.h"
00040 #include <string.h>
00041 #include <assert.h>
00042 #include <stddef.h>
00043 
00044 
00052 
00054 #define SOMEWHERE(loc)  ((loc) >= 0)
00055 
00057 #define NOWHERE(loc)    ((loc) < 0)
00058 
00060 #define POINTER(loc) (NOWHERE(loc) ? ~(loc) : (loc))
00061 
00063 struct ptr_set {
00065     ptr_vector_h pv;
00067     comparator_t compare;
00071     locator_t cached_pos;
00072 };
00073 
00074 /* Helpers */
00075 
00082 static int
00083 default_comparator(void const *obj, void const *key, locator_t ignore)
00084 {
00085     (void)ignore;
00086     return strcmp(obj,key);
00087 
00088 }
00089 
00097 static void
00098 ptr_set_init(   ptr_set_h ps,
00099                 comparator_t compare,
00100                 dtor_t dtor,
00101                 cloner_t cloner)
00102 {
00103     ps->pv = ptr_vector_new(dtor,cloner);
00104     ps->compare = compare ? compare : default_comparator;
00105     ps->cached_pos = -1;
00106 }
00107 
00115 static void
00116 ptr_set_copy_init(ptr_set_h dest, ptr_set_const_h src)
00117 {
00118     dest->pv = ptr_vector_copy(src->pv);
00119     dest->compare = src->compare;
00120     dest->cached_pos = src->cached_pos;
00121 }
00122 
00125 /* API **************************************************************/
00126 
00127 ptr_set_h
00128 ptr_set_new(comparator_t compare, dtor_t dtor, cloner_t cloner)
00129 {
00130     ptr_set_h ps = allocate(sizeof(struct ptr_set));
00131     ptr_set_init(ps,compare,dtor,cloner);
00132     return ps;
00133 }
00134 
00135 void
00136 ptr_set_dispose(ptr_set_h ps)
00137 {
00138     if (ps) {
00139         ptr_vector_dispose(ps->pv);
00140         free(ps);
00141     }
00142 }
00143 
00144 ptr_set_h
00145 ptr_set_copy(ptr_set_const_h src)
00146 {
00147     ptr_set_h ps;
00148     assert(src);
00149     ps = allocate(sizeof(struct ptr_set));
00150     ptr_set_copy_init(ps,src);
00151     return ps;
00152 }
00153 
00154 void
00155 ptr_set_swap(ptr_set_h lhs, ptr_set_h rhs)
00156 {
00157     assert(lhs);
00158     assert(rhs);
00159     ptr_vector_swap(lhs->pv,rhs->pv);
00160     PODSWAP(comparator_t,&lhs->compare,&rhs->compare);
00161     PODSWAP(locator_t,&lhs->cached_pos,&rhs->cached_pos);
00162 }
00163 
00164 void
00165 ptr_set_assign(ptr_set_h dest, ptr_set_const_h src)
00166 {
00167     if (dest != src) {
00168         ptr_set_h tmp = ptr_set_copy(src);
00169         ptr_set_swap(dest,tmp);
00170         ptr_set_dispose(tmp);
00171     }
00172 }
00173 
00174 bool
00175 ptr_set_equal(  ptr_set_const_h lhs,
00176                 ptr_set_const_h rhs)
00177 {
00178     bool eq = lhs == rhs;
00179     if (!eq) {
00180         eq = lhs->compare == rhs->compare;
00181         if (eq) {
00182             eq = ptr_vector_equal(lhs->pv,rhs->pv,lhs->compare);
00183         }
00184     }
00185     return eq;
00186 }
00187 
00188 
00189 comparator_t
00190 ptr_set_comparator(ptr_set_const_h ps)
00191 {
00192     assert(ps);
00193     return ps->compare;
00194 }
00195 
00196 dtor_t
00197 ptr_set_dtor(ptr_set_const_h ps)
00198 {
00199     return ptr_vector_dtor(ps->pv);
00200 }
00201 
00202 cloner_t
00203 ptr_set_cloner(ptr_set_const_h ps)
00204 {
00205     return ptr_vector_cloner(ps->pv);
00206 }
00207 
00208 size_t
00209 ptr_set_count(ptr_set_const_h ps)
00210 {
00211     return ptr_vector_count(ps->pv);
00212 }
00213 
00214 void *
00215 ptr_set_search(ptr_set_h ps, char const *key, locator_t keylen)
00216 {
00217     locator_t loc;
00218     assert(ps);
00219     loc = ptr_vector_search(ps->pv,key,keylen,ps->compare,true);
00220     if (NOWHERE(loc)) {
00221         ps->cached_pos = ~loc;
00222         return NULL;
00223     }
00224     ps->cached_pos = -1;
00225     return ptr_vector_at(ps->pv,(size_t)loc);
00226 }
00227 
00228 void const *
00229 ptr_set_search_const(ptr_set_const_h ps, char const *key, locator_t keylen)
00230 {
00231     return ptr_set_search((ptr_set_h)ps,key,keylen);
00232 }
00233 
00234 
00235 bool
00236 ptr_set_insert(ptr_set_h ps, void const *obj)
00237 {
00238         size_t nelems;
00239         locator_t loc;
00240     assert(ps);
00241     assert(obj);
00242     nelems = ptr_vector_count(ps->pv);
00243     loc = ps->cached_pos;
00244     ps->cached_pos = -1;
00245     if (!nelems) {
00246         ptr_vector_append(ps->pv,(void *)obj);
00247         return true;
00248     } else {
00249         if (SOMEWHERE(loc)) {
00250             int prev_comp = -1, next_comp = 1;
00251             void const *other;
00252             if (loc > 0) {
00253                 other = ptr_vector_at(ps->pv,loc - 1);
00254                 prev_comp = ps->compare(other,obj,0);
00255                 if (!prev_comp) {
00256                     return false;
00257                 }
00258             }
00259             if ((size_t)(loc + 1 )< nelems) {
00260                 other = ptr_vector_at(ps->pv,loc + 1);
00261                 next_comp = ps->compare(other,obj,0);
00262                 if (!next_comp) {
00263                     return false;
00264                 }
00265             }
00266             if (prev_comp > 0 || next_comp < 0) {
00267                 loc = -1;
00268             }
00269         }
00270         if (NOWHERE(loc)) {
00271             loc = ptr_vector_search(ps->pv,obj,0,ps->compare,true);
00272             if (SOMEWHERE(loc)) {
00273                 return false;
00274             }
00275             loc = ~loc;
00276         }
00277         ptr_vector_insert(ps->pv,loc,obj);
00278         return true;
00279     }
00280 }
00281 
00282 bool
00283 ptr_set_delete(ptr_set_h ps, locator_t pos)
00284 {
00285     assert(ps);
00286     return ptr_vector_delete(ps->pv,(size_t)pos);
00287 }
00288 
00289 void **
00290 ptr_set_begin(ptr_set_const_h ps)
00291 {
00292     assert(ps);
00293     return ptr_vector_begin(ps->pv);
00294 }
00295 
00296 void **
00297 ptr_set_end(ptr_set_const_h ps)
00298 {
00299     assert(ps);
00300     return ptr_vector_end(ps->pv);
00301 }
00302 
00303 void const **
00304 ptr_set_begin_const(ptr_set_const_h ps)
00305 {
00306     return (void const **)ptr_set_begin(ps);
00307 }
00308 
00309 void const **
00310 ptr_set_end_const(ptr_set_const_h ps)
00311 {
00312     return (void const **)ptr_set_end(ps);
00313 }
00314 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines