1 /* 2 * Copyright 1993, 1995 Christopher Seiwald. 3 * 4 * This file is part of Jam - see jam.c for Copyright information. 5 */ 6 7 /* This file is ALSO: 8 * Copyright 2001-2004 David Abrahams. 9 * Distributed under the Boost Software License, Version 1.0. 10 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 11 */ 12 13 /* 14 * lists.h - the LIST structure and routines to manipulate them 15 * 16 * The whole of jam relies on lists of objects as a datatype. This module, in 17 * conjunction with object.c, handles these relatively efficiently. 18 * 19 * Structures defined: 20 * 21 * LIST - list of OBJECTs 22 * LOL - list of LISTs 23 * 24 * External routines: 25 * 26 * list_append() - append a list onto another one, returning total 27 * list_new() - tack an object onto the end of a list of objects 28 * list_copy() - copy a whole list of objects 29 * list_sublist() - copy a subset of a list of objects 30 * list_free() - free a list of objects 31 * list_print() - print a list of objects to stdout 32 * list_length() - return the number of items in the list 33 * 34 * lol_init() - initialize a LOL (list of lists) 35 * lol_add() - append a LIST onto an LOL 36 * lol_free() - free the LOL and its LISTs 37 * lol_get() - return one of the LISTs in the LOL 38 * lol_print() - debug print LISTS separated by ":" 39 */ 40 41 #ifndef LISTS_DWA20011022_H 42 #define LISTS_DWA20011022_H 43 44 #include "config.h" 45 #include "object.h" 46 47 #ifdef HAVE_PYTHON 48 # include <Python.h> 49 #endif 50 51 /* 52 * LIST - list of strings 53 */ 54 55 typedef struct _list { 56 union { 57 int size; 58 struct _list * next; 59 OBJECT * align; 60 } impl; 61 } LIST; 62 63 typedef OBJECT * * LISTITER; 64 65 /* 66 * LOL - list of LISTs 67 */ 68 69 #define LOL_MAX 19 70 typedef struct _lol { 71 int count; 72 LIST * list[ LOL_MAX ]; 73 } LOL; 74 75 LIST * list_new( OBJECT * value ); 76 LIST * list_append( LIST * destination, LIST * source ); 77 LIST * list_copy( LIST * ); 78 LIST * list_copy_range( LIST * destination, LISTITER first, LISTITER last ); 79 void list_free( LIST * head ); 80 LIST * list_push_back( LIST * head, OBJECT * value ); 81 void list_print( LIST * ); 82 int list_length( LIST * ); 83 LIST * list_sublist( LIST *, int start, int count ); 84 LIST * list_pop_front( LIST * ); 85 LIST * list_sort( LIST * ); 86 LIST * list_unique( LIST * sorted_list ); 87 int list_in( LIST *, OBJECT * value ); 88 LIST * list_reverse( LIST * ); 89 int list_cmp( LIST * lhs, LIST * rhs ); 90 int list_is_sublist( LIST * sub, LIST * l ); 91 void list_done(); 92 93 LISTITER list_begin( LIST * ); 94 LISTITER list_end( LIST * ); 95 #define list_next( it ) ((it) + 1) 96 #define list_item( it ) (*(it)) 97 #define list_empty( l ) ((l) == L0) 98 #define list_front( l ) list_item( list_begin( l ) ) 99 100 #define L0 ((LIST *)0) 101 102 void lol_add( LOL *, LIST * ); 103 void lol_init( LOL * ); 104 void lol_free( LOL * ); 105 LIST * lol_get( LOL *, int i ); 106 void lol_print( LOL * ); 107 void lol_build( LOL *, char const * * elements ); 108 109 #ifdef HAVE_PYTHON 110 PyObject * list_to_python( LIST * ); 111 LIST * list_from_python( PyObject * ); 112 #endif 113 114 namespace b2 { namespace jam { 115 struct list 116 { 117 struct iterator 118 { iteratorlist::iterator119 inline explicit iterator(LISTITER i) : list_i(i) {} 120 121 inline iterator operator++() 122 { 123 list_i = list_next(list_i); 124 return *this; 125 } 126 inline iterator operator++(int) 127 { 128 iterator result{*this}; 129 list_i = list_next(list_i); 130 return result; 131 } 132 inline bool operator==(iterator other) const { return list_i == other.list_i; } 133 inline bool operator!=(iterator other) const { return list_i != other.list_i; } 134 inline OBJECT *& operator*() const { return list_item(list_i); } 135 inline OBJECT ** operator->() const { return &list_item(list_i); } 136 137 private: 138 139 LISTITER list_i; 140 }; 141 142 friend struct iterator; 143 listlist144 inline list(const list &other) 145 : list_obj(list_copy(other.list_obj)) {} listlist146 inline explicit list(const object &o) 147 : list_obj(list_new(object_copy(o))) {} listlist148 inline explicit list(LIST *l) 149 : list_obj(list_copy(l)) {} 150 ~listlist151 inline ~list() { if (list_obj) list_free(list_obj); } releaselist152 inline LIST* release() 153 { 154 LIST* r = list_obj; 155 list_obj = nullptr; 156 return r; 157 } 158 beginlist159 inline iterator begin() { return iterator(list_begin(list_obj)); } endlist160 inline iterator end() { return iterator(list_end(list_obj)); } emptylist161 inline bool empty() const { return list_empty(list_obj) || length() == 0; } lengthlist162 inline int length() const { return list_length(list_obj); } appendlist163 inline list &append(const list &other) 164 { 165 list_obj = list_append(list_obj, list_copy(other.list_obj)); 166 return *this; 167 } 168 169 private: 170 171 LIST *list_obj = nullptr; 172 }; 173 }} 174 175 #endif 176