024fe93790e507a052e14e4990152b9b17c7ea91
[pspp-builds.git] / src / libpspp / range-map.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2007, 2009 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifndef LIBPSPP_RANGE_MAP_H
18 #define LIBPSPP_RANGE_MAP_H
19
20 /* Range map data structure, implemented as a balanced binary
21    tree.
22
23    This is a dictionary data structure that maps from contiguous
24    ranges of "unsigned long int" keys to arbitrary data
25    values.
26
27    The implementation is not robust against ranges that include
28    ULONG_MAX in their ranges.  Such ranges are difficult to deal
29    with in C anyhow, because a range that includes 0 through
30    ULONG_MAX inclusive has a width of ULONG_MAX + 1, which equals
31    0. */
32
33 #include <stdbool.h>
34
35 #include <libpspp/bt.h>
36 #include <libpspp/cast.h>
37
38 /* Returns the data structure corresponding to the given NODE,
39    assuming that NODE is embedded as the given MEMBER name in
40    data type STRUCT. */
41 #define range_map_data(NODE, STRUCT, MEMBER)                            \
42         (CHECK_POINTER_HAS_TYPE (NODE, struct range_map_node *),        \
43          UP_CAST (NODE, STRUCT, MEMBER))
44
45 /* A range map node, to be embedded in the data value. */
46 struct range_map_node
47   {
48     struct bt_node bt_node;     /* Balanced tree node. */
49     unsigned long int start;    /* Start of range. */
50     unsigned long int end;      /* End of range, plus one. */
51   };
52
53 /* Returns the start of the range in the given NODE. */
54 static inline unsigned long int
55 range_map_node_get_start (const struct range_map_node *node)
56 {
57   return node->start;
58 }
59
60 /* Returns the end of the range in the given NODE, plus one. */
61 static inline unsigned long int
62 range_map_node_get_end (const struct range_map_node *node)
63 {
64   return node->end;
65 }
66
67 /* Returns the width of the range in the given NODE. */
68 static inline unsigned long int
69 range_map_node_get_width (const struct range_map_node *node)
70 {
71   return node->end - node->start;
72 }
73 \f
74 /* Range map. */
75 struct range_map
76   {
77     struct bt bt;
78   };
79
80 void range_map_init (struct range_map *);
81
82 bool range_map_is_empty (const struct range_map *);
83
84 void range_map_insert (struct range_map *,
85                        unsigned long int start, unsigned long int width,
86                        struct range_map_node *new);
87 void range_map_delete (struct range_map *, struct range_map_node *);
88
89 struct range_map_node *range_map_lookup (const struct range_map *,
90                                          unsigned long int position);
91 struct range_map_node *range_map_first (const struct range_map *);
92 struct range_map_node *range_map_next (const struct range_map *,
93                                        const struct range_map_node *);
94
95 #endif /* libpspp/range-map.h */