fix, initialise auto_remove_nodes upon ase_make_digraph()
[sxemacs] / modules / ase / ase-neighbourhood.h
1 /*
2   ase-neighbourhood.h -- Neighbourhood of ASE objects
3   Copyright (C) 2006, 2007, 2008 Sebastian Freundt
4
5   Author:  Sebastian Freundt <hroptatyr@sxemacs.org>
6
7   * This file is part of SXEmacs.
8   *
9   * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in the
18   *    documentation and/or other materials provided with the distribution.
19   *
20   * 3. Neither the name of the author nor the names of any contributors
21   *    may be used to endorse or promote products derived from this
22   *    software without specific prior written permission.
23   *
24   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
25   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27   * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34   * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35   */
36
37 /* Synched up with: Not in FSF. */
38
39 #ifndef INCLUDED_ase_neighbourhood_h_
40 #define INCLUDED_ase_neighbourhood_h_ 1
41
42 #include "ase.h"
43 #include "ase-interval.h"
44
45 typedef struct ase_neighbourhood_s *ase_neighbourhood_t;
46
47 extern Lisp_Object Qase_neighbourhood, Qase_neighbourhoodp;
48 extern Lisp_Object Qase_empty_neighbourhood;
49
50 extern void LTX_PUBINIT(ase_neighbourhood)(void);
51 extern void LTX_PUBREINIT(ase_neighbourhood)(void);
52 extern void LTX_PUBDEINIT(ase_neighbourhood)(void);
53
54 \f
55 struct ase_neighbourhood_s {
56 #if 0
57         ase_metric_t *metric;
58 #endif
59         bool open_p;
60         Lisp_Object point;
61         Lisp_Object radius;
62
63         /* for metric-dependent implementations */
64         void *data;
65         Lisp_Object ldata;
66
67         Lisp_Object lebesgue_measure;
68         Lisp_Object rational_measure;
69         Lisp_Object colour;
70         /* just a ref counter for those nifty recycled items */
71         struct sxe_refcounter_s refcnt;
72 };
73
74 \f
75 #define ASE_NEIGHBOURHOODP(_i)                                          \
76         (DYNACATP(_i) && EQ(XDYNACAT(_i)->type, Qase_neighbourhood))
77 #define CHECK_ASE_NEIGHBOURHOOD(x)                                      \
78         do {                                                            \
79                 if (!ASE_NEIGHBOURHOODP(x))                             \
80                         dead_wrong_type_argument(Qase_neighbourhoodp, x); \
81         } while (0)
82 #define CONCHECK_ASE_NEIGHBOURHOOD(x)                                   \
83         do {                                                            \
84                 if (!ASE_NEIGHBOURHOODP(x))                             \
85                         x = wrong_type_argument(Qase_neighbourhoodp, x); \
86         } while (0)
87 Lisp_Object _ase_wrap_neighbourhood(ase_neighbourhood_t);
88 #define XSETASE_NEIGHBOURHOOD(_res, _int)       \
89         (_res) = _ase_wrap_neighbourhood((_int))
90 #define XASE_NEIGHBOURHOOD(_x)                  \
91         ((ase_neighbourhood_t)get_dynacat(_x))
92
93 #define ase_neighbourhood_refcnt(_a)    (&((_a)->refcnt))
94 #define ase_neighbourhood_init_refcnt(_a)       \
95         (sxe_refcounter_init(ase_neighbourhood_refcnt(_a)))
96 #define ase_neighbourhood_fini_refcnt(_a)       \
97         (sxe_refcounter_finish(ase_neighbourhood_refcnt(_a)))
98 #define ase_neighbourhood_refval(_a)            \
99         (sxe_refcounter_value(ase_neighbourhood_refcnt(_a)))
100 #define ase_neighbourhood_incref(_a)            \
101         (sxe_refcounter_incref(ase_neighbourhood_refcnt(_a)))
102 #define ase_neighbourhood_decref(_a)            \
103         (sxe_refcounter_decref(ase_neighbourhood_refcnt(_a)))
104 #define XASE_NEIGHBOURHOOD_REFVAL(_a)                   \
105         (ase_neighbourhood_refval(XASE_NEIGHBOURHOOD(_a)))
106 #define XASE_NEIGHBOURHOOD_INCREF(_a)                   \
107         (ase_neighbourhood_incref(XASE_NEIGHBOURHOOD(_a)))
108 #define XASE_NEIGHBOURHOOD_DECREF(_a)                   \
109         (ase_neighbourhood_decref(XASE_NEIGHBOURHOOD(_a)))
110
111 #define ASE_NEIGHBOURHOOD_OR_COMPARABLE_P(_i)                           \
112         (COMPARABLEP(_i) || ASE_NEIGHBOURHOODP(_i))
113 #define CHECK_ASE_NEIGHBOURHOOD_OR_COMPARABLE(x)                        \
114         do {                                                            \
115                 if (!ASE_NEIGHBOURHOOD_OR_COMPARABLE_P(x))              \
116                         dead_wrong_type_argument(Qcomparablep, x);      \
117         } while (0)
118 #define CONCHECK_ASE_NEIGHBOURHOOD_OR_COMPARABLE(x)                     \
119         do {                                                            \
120                 if (!ASE_NEIGHBOURHOOD_OR_COMPARABLE_P(x))              \
121                         x = wrong_type_argument(Qcomparable, x);        \
122         } while (0)
123
124 \f
125 /* constructors */
126 extern Lisp_Object
127 ase_make_neighbourhood(Lisp_Object pt, Lisp_Object rad, Lisp_Object metric);
128 extern Lisp_Object ase_copy_neighbourhood(Lisp_Object nbh);
129 extern Lisp_Object ase_neighbourhood_boundary(Lisp_Object nbh);
130 extern Lisp_Object ase_neighbourhood_closure(Lisp_Object nbh);
131 extern Lisp_Object ase_neighbourhood_interior(Lisp_Object nbh);
132
133 /* predicates */
134 static inline bool
135 ase_neighbourhood_contains_obj_p(ase_neighbourhood_t, Lisp_Object);
136 static inline bool
137 ase_neighbourhood_contains_nbh_p(ase_neighbourhood_t, ase_neighbourhood_t);
138 static inline bool ase_neighbourhood_open_p(ase_neighbourhood_t);
139 static inline bool ase_neighbourhood_closed_p(ase_neighbourhood_t);
140 static inline bool
141 ase_neighbourhood_less_obj_p(ase_neighbourhood_t, Lisp_Object);
142 static inline bool
143 ase_neighbourhood_less_nbh_p(ase_neighbourhood_t, ase_neighbourhood_t);
144 static inline bool
145 ase_neighbourhood_greater_obj_p(ase_neighbourhood_t, Lisp_Object);
146 static inline bool
147 ase_neighbourhood_greater_nbh_p(ase_neighbourhood_t, ase_neighbourhood_t);
148
149 static inline Lisp_Object
150 ase_neighbourhood_point(ase_neighbourhood_t);
151 static inline Lisp_Object
152 ase_neighbourhood_radius(ase_neighbourhood_t);
153
154 /* measures */
155 static inline Lisp_Object
156 ase_neighbourhood_lebesgue_measure(ase_neighbourhood_t);
157 static inline Lisp_Object
158 ase_neighbourhood_rational_measure(ase_neighbourhood_t);
159
160 /* inlines */
161 static inline bool
162 ase_neighbourhood_contains_obj_p(ase_neighbourhood_t n, Lisp_Object obj)
163 {
164         /* we _know_ atm that n->ldata points to an ase_interval_t */
165         Lisp_Object intv = n->ldata;
166         return !NILP(Fase_interval_contains_p(intv, obj));
167 }
168
169 static inline bool
170 ase_neighbourhood_contains_nbh_p(ase_neighbourhood_t n1, ase_neighbourhood_t n2)
171 {
172         /* we _know_ atm that {n1,n2}->data points to an ase_interval_t */
173         Lisp_Object i1 = n1->ldata;
174         Lisp_Object i2 = n2->ldata;
175         return !NILP(Fase_interval_contains_p(i1, i2));
176 }
177
178 static inline bool
179 ase_neighbourhood_open_p(ase_neighbourhood_t n)
180 {
181         return n->open_p;
182 }
183
184 static inline bool
185 ase_neighbourhood_closed_p(ase_neighbourhood_t n)
186 {
187         return !n->open_p;
188 }
189
190 static inline bool
191 ase_neighbourhood_less_obj_p(ase_neighbourhood_t n, Lisp_Object obj)
192 {
193         /* we _know_ atm that {n1,n2}->data points to an ase_interval_t */
194         ase_interval_t a = XASE_INTERVAL(n->ldata);
195
196         return (_ase_less_p(a->upper, obj) || _ase_equal_p(a->upper, obj));
197 }
198
199 static inline bool
200 ase_neighbourhood_less_nbh_p(ase_neighbourhood_t n1, ase_neighbourhood_t n2)
201 {
202         /* we _know_ atm that {n1,n2}->data points to an ase_interval_t */
203         ase_interval_t a1 = XASE_INTERVAL(n1->ldata);
204         ase_interval_t a2 = XASE_INTERVAL(n2->ldata);
205         return (_ase_less_p(a1->upper, a2->lower) ||
206                 _ase_equal_p(a1->upper, a2->lower));
207 }
208
209 static inline bool
210 ase_neighbourhood_greater_obj_p(ase_neighbourhood_t n, Lisp_Object obj)
211 {
212         /* we _know_ atm that {n1,n2}->data points to an ase_interval_t */
213         ase_interval_t a = XASE_INTERVAL(n->ldata);
214         return (_ase_less_p(obj, a->lower) || _ase_equal_p(obj, a->lower));
215 }
216
217 static inline bool
218 ase_neighbourhood_greater_nbh_p(ase_neighbourhood_t n1, ase_neighbourhood_t n2)
219 {
220         /* we _know_ atm that {n1,n2}->data points to an ase_interval_t */
221         ase_interval_t a1 = XASE_INTERVAL(n1->ldata);
222         ase_interval_t a2 = XASE_INTERVAL(n2->ldata);
223         return (_ase_less_p(a2->upper, a1->lower) ||
224                 _ase_equal_p(a2->upper, a1->lower));
225 }
226
227 #endif