Add the RB_PROTOTYPE_STATIC and RB_GENERATE_STATIC macros.

Approved by:	markm (mentor)
This commit is contained in:
jasone 2006-01-19 07:20:20 +00:00
parent 2622b7ee77
commit 3c01b0047d
3 changed files with 49 additions and 25 deletions

View File

@ -110,6 +110,7 @@ MLINKS+= tree.3 RB_EMPTY.3 \
tree.3 RB_FIND.3 \
tree.3 RB_FOREACH.3 \
tree.3 RB_GENERATE.3 \
tree.3 RB_GENERATE_STATIC.3 \
tree.3 RB_HEAD.3 \
tree.3 RB_INIT.3 \
tree.3 RB_INITIALIZER.3 \
@ -121,6 +122,7 @@ MLINKS+= tree.3 RB_EMPTY.3 \
tree.3 RB_NFIND.3 \
tree.3 RB_PARENT.3 \
tree.3 RB_PROTOTYPE.3 \
tree.3 RB_PROTOTYPE_STATIC.3 \
tree.3 RB_REMOVE.3 \
tree.3 RB_RIGHT.3 \
tree.3 RB_ROOT.3 \

View File

@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 24, 2002
.Dd January 17, 2006
.Dt TREE 3
.Os
.Sh NAME
@ -52,7 +52,9 @@
.Nm SPLAY_INSERT ,
.Nm SPLAY_REMOVE ,
.Nm RB_PROTOTYPE ,
.Nm RB_PROTOTYPE_STATIC ,
.Nm RB_GENERATE ,
.Nm RB_GENERATE_STATIC ,
.Nm RB_ENTRY ,
.Nm RB_HEAD ,
.Nm RB_INITIALIZER ,
@ -102,7 +104,9 @@
.Ft "struct TYPE *"
.Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm"
.Fn RB_PROTOTYPE NAME TYPE FIELD CMP
.Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP
.Fn RB_GENERATE NAME TYPE FIELD CMP
.Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP
.Fn RB_ENTRY TYPE
.Fn RB_HEAD HEADNAME TYPE
.Fn RB_INITIALIZER "RB_HEAD *head"
@ -156,14 +160,16 @@ The argument
.Fa NAME
has to be a unique name prefix for every tree that is defined.
.Pp
The function prototypes are declared with either
The function prototypes are declared with
.Fn SPLAY_PROTOTYPE ,
.Fn RB_PROTOTYPE ,
or
.Fn RB_PROTOTYPE .
The function bodies are generated with either
.Fn RB_PROTOTYPE_STATIC .
The function bodies are generated with
.Fn SPLAY_GENERATE ,
.Fn RB_GENERATE ,
or
.Fn RB_GENERATE .
.Fn RB_GENERATE_STATIC .
See the examples below for further explanation of how these macros are used.
.Sh SPLAY TREES
A splay tree is a self-organizing data structure.
@ -344,6 +350,8 @@ macro declares a structure that allows elements to be connected in the tree.
In order to use the functions that manipulate the tree structure,
their prototypes need to be declared with the
.Fn RB_PROTOTYPE
or
.Fn RB_PROTOTYPE_STATIC
macro,
where
.Fa NAME
@ -359,10 +367,14 @@ argument is the name of the element defined by
.Pp
The function bodies are generated with the
.Fn RB_GENERATE
or
.Fn RB_GENERATE_STATIC
macro.
It takes the same arguments as the
These macros take the same arguments as the
.Fn RB_PROTOTYPE
macro, but should be used only once.
and
.Fn RB_PROTOTYPE_STATIC
macros, but should be used only once.
.Pp
Finally,
the

View File

@ -30,6 +30,8 @@
#ifndef _SYS_TREE_H_
#define _SYS_TREE_H_
#include <sys/cdefs.h>
/*
* This file defines data structures for different types of trees:
* splay trees and red-black trees.
@ -376,22 +378,30 @@ struct { \
} while (/*CONSTCOND*/ 0)
/* Generates prototypes and inline functions */
#define RB_PROTOTYPE(name, type, field, cmp) \
void name##_RB_INSERT_COLOR(struct name *, struct type *); \
void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
struct type *name##_RB_REMOVE(struct name *, struct type *); \
struct type *name##_RB_INSERT(struct name *, struct type *); \
struct type *name##_RB_FIND(struct name *, struct type *); \
struct type *name##_RB_NFIND(struct name *, struct type *); \
struct type *name##_RB_NEXT(struct type *); \
struct type *name##_RB_MINMAX(struct name *, int); \
#define RB_PROTOTYPE(name, type, field, cmp) \
RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
attr struct type *name##_RB_FIND(struct name *, struct type *); \
attr struct type *name##_RB_NFIND(struct name *, struct type *); \
attr struct type *name##_RB_NEXT(struct type *); \
attr struct type *name##_RB_MINMAX(struct name *, int); \
\
/* Main rb operation.
* Moves node close to the key of elm to top
*/
#define RB_GENERATE(name, type, field, cmp) \
void \
#define RB_GENERATE(name, type, field, cmp) \
RB_GENERATE_INTERNAL(name, type, field, cmp,)
#define RB_GENERATE_STATIC(name, type, field, cmp) \
RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
attr void \
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
{ \
struct type *parent, *gparent, *tmp; \
@ -435,7 +445,7 @@ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
} \
\
void \
attr void \
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
{ \
struct type *tmp; \
@ -513,7 +523,7 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm)
RB_COLOR(elm, field) = RB_BLACK; \
} \
\
struct type * \
attr struct type * \
name##_RB_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *child, *parent, *old = elm; \
@ -581,7 +591,7 @@ color: \
} \
\
/* Inserts a node into the RB tree */ \
struct type * \
attr struct type * \
name##_RB_INSERT(struct name *head, struct type *elm) \
{ \
struct type *tmp; \
@ -612,7 +622,7 @@ name##_RB_INSERT(struct name *head, struct type *elm) \
} \
\
/* Finds the node with the same key as elm */ \
struct type * \
attr struct type * \
name##_RB_FIND(struct name *head, struct type *elm) \
{ \
struct type *tmp = RB_ROOT(head); \
@ -630,7 +640,7 @@ name##_RB_FIND(struct name *head, struct type *elm) \
} \
\
/* Finds the first node greater than or equal to the search key */ \
struct type * \
attr struct type * \
name##_RB_NFIND(struct name *head, struct type *elm) \
{ \
struct type *ret = RB_ROOT(head); \
@ -659,7 +669,7 @@ name##_RB_NFIND(struct name *head, struct type *elm) \
} \
\
/* ARGSUSED */ \
struct type * \
attr struct type * \
name##_RB_NEXT(struct type *elm) \
{ \
if (RB_RIGHT(elm, field)) { \
@ -680,7 +690,7 @@ name##_RB_NEXT(struct type *elm) \
return (elm); \
} \
\
struct type * \
attr struct type * \
name##_RB_MINMAX(struct name *head, int val) \
{ \
struct type *tmp = RB_ROOT(head); \