ba4119b346bda76a5aa674ebdd2d35fccca9c595
[pspp] / src / data / subcase.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2008, 2009, 2010 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 DATA_SUBCASE_H
18 #define DATA_SUBCASE_H 1
19
20 #include <stdbool.h>
21 #include <stddef.h>
22
23 struct ccase;
24 union value;
25 struct variable;
26
27 /* Sort order. */
28 enum subcase_direction
29   {
30     SC_ASCEND,                  /* A, B, C, ..., X, Y, Z. */
31     SC_DESCEND                  /* Z, Y, X, ..., C, B, A. */
32   };
33
34 /* A value within a case. */
35 struct subcase_field
36   {
37     size_t case_index;          /* Starting position in the case. */
38     int width;                  /* 0=numeric, otherwise string width. */
39     enum subcase_direction direction; /* Sort order. */
40   };
41
42 /* A subcase specifies how to draw values from a case. */
43 struct subcase
44   {
45     struct subcase_field *fields;
46     size_t n_fields;
47
48     struct caseproto *proto;    /* Created lazily. */
49   };
50
51 void subcase_init_empty (struct subcase *);
52 void subcase_init_vars (struct subcase *,
53                         const struct variable *const *, size_t n_vars);
54 void subcase_init_var (struct subcase *,
55                        const struct variable *, enum subcase_direction);
56 void subcase_init (struct subcase *, int index, int width,
57                    enum subcase_direction);
58
59 void subcase_clone (struct subcase *, const struct subcase *);
60 void subcase_clear (struct subcase *);
61 void subcase_destroy (struct subcase *);
62
63 bool subcase_contains (const struct subcase *, int case_index);
64 bool subcase_contains_var (const struct subcase *, const struct variable *);
65
66 bool subcase_add (struct subcase *, int case_index, int width,
67                   enum subcase_direction direction);
68 bool subcase_add_var (struct subcase *, const struct variable *,
69                       enum subcase_direction);
70 bool subcase_add_vars (struct subcase *, const struct variable *const *,
71                        size_t n_vars, enum subcase_direction);
72
73 void subcase_add_always (struct subcase *sc, int case_index, int width,
74                          enum subcase_direction direction);
75 void subcase_add_var_always (struct subcase *, const struct variable *,
76                              enum subcase_direction);
77 bool subcase_add_vars_always (struct subcase *, const struct variable *const *,
78                               size_t n_vars, enum subcase_direction);
79 void subcase_add_proto_always (struct subcase *, const struct caseproto *);
80
81 void subcase_concat (struct subcase *, const struct subcase *);
82 void subcase_concat_always (struct subcase *, const struct subcase *);
83
84 void subcase_project (struct subcase *);
85
86 const struct caseproto *subcase_get_proto (const struct subcase *);
87
88 static inline bool subcase_is_empty (const struct subcase *);
89 static inline size_t subcase_get_n_fields (const struct subcase *);
90
91 static inline size_t subcase_get_case_index (const struct subcase *,
92                                              size_t idx);
93 static inline enum subcase_direction subcase_get_direction (
94   const struct subcase *, size_t idx);
95
96 bool subcase_conformable (const struct subcase *, const struct subcase *);
97
98 void subcase_extract (const struct subcase *, const struct ccase *,
99                       union value *values);
100 void subcase_inject (const struct subcase *,
101                      const union value *values, struct ccase *);
102 void subcase_copy (const struct subcase *src_sc, const struct ccase *src,
103                    const struct subcase *dst_sc, struct ccase *dst);
104
105 int subcase_compare_3way (const struct subcase *a_sc, const struct ccase *a,
106                           const struct subcase *b_sc, const struct ccase *b);
107 int subcase_compare_3way_xc (const struct subcase *,
108                              const union value *a, const struct ccase *b);
109 int subcase_compare_3way_cx (const struct subcase *,
110                              const struct ccase *a, const union value *b);
111 int subcase_compare_3way_xx (const struct subcase *,
112                              const union value *a, const union value *b);
113 bool subcase_equal (const struct subcase *a_sc, const struct ccase *a,
114                     const struct subcase *b_sc, const struct ccase *b);
115 bool subcase_equal_xc (const struct subcase *,
116                        const union value *a, const struct ccase *b);
117 bool subcase_equal_cx (const struct subcase *,
118                        const struct ccase *a, const union value *b);
119 bool subcase_equal_xx (const struct subcase *,
120                        const union value *a, const union value *b);
121
122 static inline size_t
123 subcase_get_case_index (const struct subcase *sc, size_t idx)
124 {
125   return sc->fields[idx].case_index;
126 }
127
128 static inline enum subcase_direction
129 subcase_get_direction (const struct subcase *sc, size_t idx)
130 {
131   return sc->fields[idx].direction;
132 }
133
134 static inline bool
135 subcase_is_empty (const struct subcase *sc)
136 {
137   return sc->n_fields == 0;
138 }
139
140 static inline size_t
141 subcase_get_n_fields (const struct subcase *sc)
142 {
143   return sc->n_fields;
144 }
145
146 #endif /* data/subcase.h */