1 /***************************************************************************/
5 /* Simple MRU list-cache (specification). */
7 /* Copyright 2000-2001, 2003, 2004, 2005 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
16 /***************************************************************************/
19 /*************************************************************************/
21 /* An MRU is a list that cannot hold more than a certain number of */
22 /* elements (`max_elements'). All elements in the list are sorted in */
23 /* least-recently-used order, i.e., the `oldest' element is at the tail */
26 /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */
27 /* the list is searched for an element with the corresponding key. If */
28 /* it is found, the element is moved to the head of the list and is */
31 /* If no corresponding element is found, the lookup routine will try to */
32 /* obtain a new element with the relevant key. If the list is already */
33 /* full, the oldest element from the list is discarded and replaced by a */
34 /* new one; a new element is added to the list otherwise. */
36 /* Note that it is possible to pre-allocate the element list nodes. */
37 /* This is handy if `max_elements' is sufficiently small, as it saves */
38 /* allocations/releases during the lookup process. */
40 /*************************************************************************/
48 #include FT_FREETYPE_H
51 #error "freetype.h of FreeType 1 has been loaded!"
52 #error "Please fix the directory search order for header files"
53 #error "so that freetype.h of FreeType 2 is found first."
56 #define xxFT_DEBUG_ERROR
61 typedef struct FTC_MruNodeRec_* FTC_MruNode;
63 typedef struct FTC_MruNodeRec_
72 FTC_MruNode_Prepend( FTC_MruNode *plist,
76 FTC_MruNode_Up( FTC_MruNode *plist,
80 FTC_MruNode_Remove( FTC_MruNode *plist,
84 typedef struct FTC_MruListRec_* FTC_MruList;
86 typedef struct FTC_MruListClassRec_ const * FTC_MruListClass;
90 (*FTC_MruNode_CompareFunc)( FTC_MruNode node,
94 (*FTC_MruNode_InitFunc)( FTC_MruNode node,
99 (*FTC_MruNode_ResetFunc)( FTC_MruNode node,
104 (*FTC_MruNode_DoneFunc)( FTC_MruNode node,
108 typedef struct FTC_MruListClassRec_
111 FTC_MruNode_CompareFunc node_compare;
112 FTC_MruNode_InitFunc node_init;
113 FTC_MruNode_ResetFunc node_reset;
114 FTC_MruNode_DoneFunc node_done;
116 } FTC_MruListClassRec;
118 typedef struct FTC_MruListRec_
124 FTC_MruListClassRec clazz;
131 FTC_MruList_Init( FTC_MruList list,
132 FTC_MruListClass clazz,
138 FTC_MruList_Reset( FTC_MruList list );
142 FTC_MruList_Done( FTC_MruList list );
144 FT_EXPORT( FTC_MruNode )
145 FTC_MruList_Find( FTC_MruList list,
148 FT_EXPORT( FT_Error )
149 FTC_MruList_New( FTC_MruList list,
151 FTC_MruNode *anode );
153 FT_EXPORT( FT_Error )
154 FTC_MruList_Lookup( FTC_MruList list,
156 FTC_MruNode *pnode );
160 FTC_MruList_Remove( FTC_MruList list,
164 FTC_MruList_RemoveSelection( FTC_MruList list,
165 FTC_MruNode_CompareFunc selection,
171 #define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error ) \
173 FTC_MruNode* _pfirst = &(list)->nodes; \
174 FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \
175 FTC_MruNode _first, _node, *_pnode; \
179 _first = *(_pfirst); \
187 if ( _compare( _node, (key) ) ) \
189 if ( _node != _first ) \
190 FTC_MruNode_Up( _pfirst, _node ); \
192 _pnode = (FTC_MruNode*)(void*)&(node); \
196 _node = _node->next; \
198 } while ( _node != _first) ; \
201 error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \
206 #define FTC_MRULIST_LOOKUP( list, key, node, error ) \
207 FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error )
209 #else /* !FTC_INLINE */
211 #define FTC_MRULIST_LOOKUP( list, key, node, error ) \
212 error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) )
214 #endif /* !FTC_INLINE */
217 #define FTC_MRULIST_LOOP( list, node ) \
219 FTC_MruNode _first = (list)->nodes; \
224 FTC_MruNode _node = _first; \
229 *(FTC_MruNode*)&(node) = _node;
232 #define FTC_MRULIST_LOOP_END() \
233 _node = _node->next; \
235 } while ( _node != _first ); \
244 #endif /* __FTCMRU_H__ */