]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/lists.cpp
2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * lists.c - maintain lists of objects
17 static LIST
* freelist
[ 32 ]; /* junkpile for list_dealloc() */
19 static unsigned get_bucket( unsigned size
)
22 while ( size
> ( 1u << bucket
) ) ++bucket
;
26 static LIST
* list_alloc( unsigned const size
)
28 unsigned const bucket
= get_bucket( size
);
29 if ( freelist
[ bucket
] )
31 LIST
* result
= freelist
[ bucket
];
32 freelist
[ bucket
] = result
->impl
.next
;
35 return (LIST
*)BJAM_MALLOC( sizeof( LIST
) + ( 1u << bucket
) *
39 static void list_dealloc( LIST
* l
)
41 unsigned size
= list_length( l
);
45 if ( size
== 0 ) return;
47 bucket
= get_bucket( size
);;
49 #ifdef BJAM_NO_MEM_CACHE
52 node
->impl
.next
= freelist
[ bucket
];
53 freelist
[ bucket
] = node
;
58 * list_append() - append a list onto another one, returning total
61 LIST
* list_append( LIST
* l
, LIST
* nl
)
63 if ( list_empty( l
) )
65 if ( !list_empty( nl
) )
67 int const l_size
= list_length( l
);
68 int const nl_size
= list_length( nl
);
69 int const size
= l_size
+ nl_size
;
70 unsigned const bucket
= get_bucket( size
);
72 /* Do we need to reallocate? */
73 if ( l_size
<= ( 1u << ( bucket
- 1 ) ) )
75 LIST
* result
= list_alloc( size
);
76 memcpy( list_begin( result
), list_begin( l
), l_size
* sizeof(
83 memcpy( list_begin( l
) + l_size
, list_begin( nl
), nl_size
* sizeof(
90 LISTITER
list_begin( LIST
* l
)
92 return l
? (LISTITER
)( (char *)l
+ sizeof( LIST
) ) : 0;
95 LISTITER
list_end( LIST
* l
)
97 return l
? list_begin( l
) + l
->impl
.size
: 0;
100 LIST
* list_new( OBJECT
* value
)
102 LIST
* const head
= list_alloc( 1 ) ;
104 list_begin( head
)[ 0 ] = value
;
109 * list_push_back() - tack a string onto the end of a list of strings
112 LIST
* list_push_back( LIST
* head
, OBJECT
* value
)
114 unsigned int size
= list_length( head
);
118 out_printf( "list > %s <\n", object_str( value
) );
120 /* If the size is a power of 2, reallocate. */
123 head
= list_alloc( 1 );
125 else if ( ( ( size
- 1 ) & size
) == 0 )
127 LIST
* l
= list_alloc( size
+ 1 );
128 memcpy( l
, head
, sizeof( LIST
) + size
* sizeof( OBJECT
* ) );
129 list_dealloc( head
);
133 list_begin( head
)[ size
] = value
;
134 head
->impl
.size
= size
+ 1;
141 * list_copy() - copy a whole list of strings (nl) onto end of another (l).
144 LIST
* list_copy( LIST
* l
)
146 int size
= list_length( l
);
150 if ( size
== 0 ) return L0
;
152 result
= list_alloc( size
);
153 result
->impl
.size
= size
;
154 for ( i
= 0; i
< size
; ++i
)
155 list_begin( result
)[ i
] = object_copy( list_begin( l
)[ i
] );
160 LIST
* list_copy_range( LIST
* l
, LISTITER first
, LISTITER last
)
166 int size
= last
- first
;
167 LIST
* result
= list_alloc( size
);
168 LISTITER dest
= list_begin( result
);
169 result
->impl
.size
= size
;
170 for ( ; first
!= last
; ++first
, ++dest
)
171 *dest
= object_copy( *first
);
178 * list_sublist() - copy a subset of a list of strings.
181 LIST
* list_sublist( LIST
* l
, int start
, int count
)
183 int end
= start
+ count
;
184 int size
= list_length( l
);
185 if ( start
>= size
) return L0
;
186 if ( end
> size
) end
= size
;
187 return list_copy_range( l
, list_begin( l
) + start
, list_begin( l
) + end
);
191 static int str_ptr_compare( void const * va
, void const * vb
)
193 OBJECT
* a
= *( (OBJECT
* *)va
);
194 OBJECT
* b
= *( (OBJECT
* *)vb
);
195 return strcmp( object_str( a
), object_str( b
) );
199 LIST
* list_sort( LIST
* l
)
208 len
= list_length( l
);
209 result
= list_copy( l
);
211 qsort( list_begin( result
), len
, sizeof( OBJECT
* ), str_ptr_compare
);
218 * list_free() - free a list of strings
221 void list_free( LIST
* head
)
223 if ( !list_empty( head
) )
225 LISTITER iter
= list_begin( head
);
226 LISTITER
const end
= list_end( head
);
227 for ( ; iter
!= end
; iter
= list_next( iter
) )
228 object_free( list_item( iter
) );
229 list_dealloc( head
);
235 * list_pop_front() - remove the front element from a list of strings
238 LIST
* list_pop_front( LIST
* l
)
240 unsigned size
= list_length( l
);
243 object_free( list_front( l
) );
251 if ( ( ( size
- 1 ) & size
) == 0 )
253 LIST
* const nl
= list_alloc( size
);
254 nl
->impl
.size
= size
;
255 memcpy( list_begin( nl
), list_begin( l
) + 1, size
* sizeof( OBJECT
* )
262 memmove( list_begin( l
), list_begin( l
) + 1, size
* sizeof( OBJECT
* ) );
266 LIST
* list_reverse( LIST
* l
)
268 int size
= list_length( l
);
269 if ( size
== 0 ) return L0
;
271 LIST
* const result
= list_alloc( size
);
273 result
->impl
.size
= size
;
274 for ( i
= 0; i
< size
; ++i
)
275 list_begin( result
)[ i
] = object_copy( list_begin( l
)[ size
- i
-
281 int list_cmp( LIST
* t
, LIST
* s
)
284 LISTITER t_it
= list_begin( t
);
285 LISTITER
const t_end
= list_end( t
);
286 LISTITER s_it
= list_begin( s
);
287 LISTITER
const s_end
= list_end( s
);
289 while ( !status
&& ( t_it
!= t_end
|| s_it
!= s_end
) )
291 char const * st
= t_it
!= t_end
? object_str( list_item( t_it
) ) : "";
292 char const * ss
= s_it
!= s_end
? object_str( list_item( s_it
) ) : "";
294 status
= strcmp( st
, ss
);
296 t_it
= t_it
!= t_end
? list_next( t_it
) : t_it
;
297 s_it
= s_it
!= s_end
? list_next( s_it
) : s_it
;
303 int list_is_sublist( LIST
* sub
, LIST
* l
)
305 LISTITER iter
= list_begin( sub
);
306 LISTITER
const end
= list_end( sub
);
307 for ( ; iter
!= end
; iter
= list_next( iter
) )
308 if ( !list_in( l
, list_item( iter
) ) )
314 * list_print() - print a list of strings to stdout
317 void list_print( LIST
* l
)
319 LISTITER iter
= list_begin( l
), end
= list_end( l
);
322 out_printf( "%s", object_str( list_item( iter
) ) );
323 iter
= list_next( iter
);
324 for ( ; iter
!= end
; iter
= list_next( iter
) )
325 out_printf( " %s", object_str( list_item( iter
) ) );
331 * list_length() - return the number of items in the list
334 int list_length( LIST
* l
)
336 return l
? l
->impl
.size
: 0;
340 int list_in( LIST
* l
, OBJECT
* value
)
342 LISTITER iter
= list_begin( l
);
343 LISTITER end
= list_end( l
);
344 for ( ; iter
!= end
; iter
= list_next( iter
) )
345 if ( object_equal( list_item( iter
), value
) )
351 LIST
* list_unique( LIST
* sorted_list
)
354 OBJECT
* last_added
= 0;
356 LISTITER iter
= list_begin( sorted_list
), end
= list_end( sorted_list
);
357 for ( ; iter
!= end
; iter
= list_next( iter
) )
359 if ( !last_added
|| !object_equal( list_item( iter
), last_added
) )
361 result
= list_push_back( result
, object_copy( list_item( iter
) ) );
362 last_added
= list_item( iter
);
371 for ( i
= 0; i
< sizeof( freelist
) / sizeof( freelist
[ 0 ] ); ++i
)
373 LIST
* l
= freelist
[ i
];
376 LIST
* const tmp
= l
;
385 * lol_init() - initialize a LOL (list of lists).
388 void lol_init( LOL
* lol
)
395 * lol_add() - append a LIST onto an LOL.
398 void lol_add( LOL
* lol
, LIST
* l
)
400 if ( lol
->count
< LOL_MAX
)
401 lol
->list
[ lol
->count
++ ] = l
;
406 * lol_free() - free the LOL and its LISTs.
409 void lol_free( LOL
* lol
)
412 for ( i
= 0; i
< lol
->count
; ++i
)
413 list_free( lol
->list
[ i
] );
419 * lol_get() - return one of the LISTs in the LOL.
422 LIST
* lol_get( LOL
* lol
, int i
)
424 return i
< lol
->count
? lol
->list
[ i
] : L0
;
429 * lol_print() - debug print LISTS separated by ":".
432 void lol_print( LOL
* lol
)
435 for ( i
= 0; i
< lol
->count
; ++i
)
439 list_print( lol
->list
[ i
] );
445 PyObject
* list_to_python( LIST
* l
)
447 PyObject
* result
= PyList_New( 0 );
448 LISTITER iter
= list_begin( l
);
449 LISTITER
const end
= list_end( l
);
450 for ( ; iter
!= end
; iter
= list_next( iter
) )
452 PyObject
* s
= PyString_FromString( object_str( list_item( iter
) ) );
453 PyList_Append( result
, s
);
460 LIST
* list_from_python( PyObject
* l
)
464 Py_ssize_t n
= PySequence_Size( l
);
466 for ( i
= 0; i
< n
; ++i
)
468 PyObject
* v
= PySequence_GetItem( l
, i
);
469 result
= list_push_back( result
, object_new( PyString_AsString( v
) ) );