aboutsummaryrefslogtreecommitdiff
path: root/src/include/nodes/pg_list.h
blob: 31566a29c9f0a83757d341011c5f0205b61ee38e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*-------------------------------------------------------------------------
 *
 * pg_list.h
 *	  interface for PostgreSQL generic linked list package
 *
 *
 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * $PostgreSQL: pgsql/src/include/nodes/pg_list.h,v 1.43 2004/01/07 18:43:36 neilc Exp $
 *
 *-------------------------------------------------------------------------
 */
#ifndef PG_LIST_H
#define PG_LIST_H

#include "nodes/nodes.h"

/* ----------------------------------------------------------------
 *						node definitions
 * ----------------------------------------------------------------
 */

/*----------------------
 *		List node
 *
 * We support three types of lists:
 *	lists of pointers (in practice always pointers to Nodes, but declare as
 *		"void *" to minimize casting annoyances)
 *	lists of integers
 *	lists of Oids
 *
 * (At this writing, ints and Oids are the same size, but they may not always
 * be so; try to be careful to maintain the distinction.)
 *----------------------
 */
typedef struct List
{
	NodeTag		type;
	union
	{
		void	   *ptr_value;
		int			int_value;
		Oid			oid_value;
	}			elem;
	struct List *next;
} List;

#define    NIL			((List *) NULL)

/* ----------------
 *		accessor macros
 *
 * The general naming convention is that the base name xyz() is for the
 * pointer version, xyzi() is for integers, xyzo() is for Oids.  We don't
 * bother with multiple names if the same routine can handle all cases.
 * ----------------
 */

#define lfirst(l)								((l)->elem.ptr_value)
#define lfirsti(l)								((l)->elem.int_value)
#define lfirsto(l)								((l)->elem.oid_value)

#define lnext(l)								((l)->next)

#define lsecond(l)								lfirst(lnext(l))

#define lthird(l)								lfirst(lnext(lnext(l)))

#define lfourth(l)								lfirst(lnext(lnext(lnext(l))))

/*
 * foreach -
 *	  a convenience macro which loops through the list
 */
#define foreach(_elt_,_list_)	\
	for (_elt_ = (_list_); _elt_ != NIL; _elt_ = lnext(_elt_))

/*
 * Convenience macros for building fixed-length lists
 */
#define makeList1(x1)				lcons(x1, NIL)
#define makeList2(x1,x2)			lcons(x1, makeList1(x2))
#define makeList3(x1,x2,x3)			lcons(x1, makeList2(x2,x3))
#define makeList4(x1,x2,x3,x4)		lcons(x1, makeList3(x2,x3,x4))

#define makeListi1(x1)				lconsi(x1, NIL)
#define makeListi2(x1,x2)			lconsi(x1, makeListi1(x2))

#define makeListo1(x1)				lconso(x1, NIL)
#define makeListo2(x1,x2)			lconso(x1, makeListo1(x2))

/*
 * FastList is an optimization for building large lists.  The conventional
 * way to build a list is repeated lappend() operations, but that is O(N^2)
 * in the number of list items, which gets tedious for large lists.
 *
 * Note: there are some hacks in gram.y that rely on the head pointer (the
 * value-as-list) being the first field.
 */
typedef struct FastList
{
	List	   *head;
	List	   *tail;
} FastList;

#define FastListInit(fl)	( (fl)->head = (fl)->tail = NIL )
#define FastListFromList(fl, l)  \
	( (fl)->head = (l), (fl)->tail = llastnode((fl)->head) )
#define FastListValue(fl)	( (fl)->head )

#define makeFastList1(fl, x1)  \
	( (fl)->head = (fl)->tail = makeList1(x1) )

extern List *lcons(void *datum, List *list);
extern List *lconsi(int datum, List *list);
extern List *lconso(Oid datum, List *list);
extern List *lappend(List *list, void *datum);
extern List *lappendi(List *list, int datum);
extern List *lappendo(List *list, Oid datum);
extern List *nconc(List *list1, List *list2);
extern void FastAppend(FastList *fl, void *datum);
extern void FastAppendi(FastList *fl, int datum);
extern void FastAppendo(FastList *fl, Oid datum);
extern void FastConc(FastList *fl, List *cells);
extern void FastConcFast(FastList *fl, FastList *fl2);
extern void *nth(int n, List *l);
extern int	length(List *list);
extern void *llast(List *list);
extern List *llastnode(List *list);
extern bool member(void *datum, List *list);
extern bool ptrMember(void *datum, List *list);
extern bool intMember(int datum, List *list);
extern bool oidMember(Oid datum, List *list);
extern List *lremove(void *elem, List *list);
extern List *LispRemove(void *elem, List *list);
extern List *lremovei(int elem, List *list);
extern List *ltruncate(int n, List *list);

extern List *set_union(List *list1, List *list2);
extern List *set_uniono(List *list1, List *list2);
extern List *set_ptrUnion(List *list1, List *list2);
extern List *set_difference(List *list1, List *list2);
extern List *set_differenceo(List *list1, List *list2);
extern List *set_ptrDifference(List *list1, List *list2);

extern bool equali(List *list1, List *list2);
extern bool equalo(List *list1, List *list2);

extern void freeList(List *list);

/* in copyfuncs.c */
extern List *listCopy(List *list);

#endif   /* PG_LIST_H */