1 /*** category.h -- categorial view on objects, this is NOT OO
3 * Copyright (C) 2008 Sebastian Freundt
5 * Author: Sebastian Freundt <hroptatyr@sxemacs.org>
7 * This file is part of SXEmacs.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
38 #ifndef INCLUDED_category_h_
39 #define INCLUDED_category_h_
43 enum cat_morphism_kind_e {
45 cat_mk_lc = 0, /* whether or not lcrecord header is used */
48 cat_mk_aseq, /* associative seqs */
49 cat_mk_aset, /* associative sets aka dicts */
50 number_of_cat_morphism_kinds,
53 typedef struct cat_morphism_s *cat_morphism_t;
54 typedef enum cat_morphism_kind_e cat_morphism_kind_t;
56 extern_inline bool __bit_set_p(int number, char bit);
57 extern_inline char __nbits_right_of(int number, char bit);
58 extern cat_morphism_t morphisms;
61 /* a double lookup approach
62 * this is the complete list of morphisms (views) that an object can have */
63 struct cat_morphism_s {
71 struct __cat_morphism_lrec_s {
72 struct lrecord_header lh;
76 struct __cat_morphism_lcrec_s {
77 struct lcrecord_header lch;
83 __bit_set_p(int number, char bit)
85 /* return whether bit BIT is set in NUMBER
87 * the right most bit has bit number 0 */
88 return ((1<<bit) & number) != 0;
91 #if defined HAVE_ASM_EAX && defined HAVE_ASM_CL && \
92 defined HAVE_ASM_ADCB && defined HAVE_ASM_SARL
94 __nbits_right_of(int number, char bit)
96 /* return the number of set bits in NUMBER right of BIT
98 * bit count starts at 0 and on the right */
99 /* we just stuff `BIT' into CNT which goes to cx */
100 register char cnt = bit;
103 #if !defined HAVE_ASM_RETVAL_IN_EBX
104 " pushl %%ebx /* save EBX ([nmsk]) */\n"
105 #endif /* HAVE_ASM_RETVAL_IN_EBX */
106 /* initialise AX directly */
108 " sall %[cnt], %%eax /* CL has value of BIT */\n"
110 " andl %%eax, %[nmsk] /* nmsk <- 1<<bit - 1*/\n"
111 " xorb %[cnt], %[cnt] /* cnt <- 0 */\n"
114 " sarl $1, %[nmsk] /* shift right and */\n"
115 " adcb $0, %[cnt] /* add 1 if carry was set*/\n"
117 " sarl $1, %[nmsk] /* shift right and */\n"
118 " adcb $0, %[cnt] /* add 1 if carry was set*/\n"
120 " sarl $1, %[nmsk] /* shift right and */\n"
121 " adcb $0, %[cnt] /* add 1 if carry was set*/\n"
123 " sarl $1, %[nmsk] /* shift right and */\n"
124 /* maybe %[nmsk] is zero meanwhile, check for it and
127 " adcb $0, %[cnt] /* add 1 if carry was set*/\n"
129 " sarl $1, %[nmsk] /* shift right and */\n"
130 " adcb $0, %[cnt] /* add 1 if carry was set*/\n"
132 " sarl $1, %[nmsk] /* shift right and */\n"
133 /* maybe %[nmsk] is zero meanwhile, check for it and
136 " adcb $0, %[cnt] /* add 1 if carry was set*/\n"
138 " sarl $1, %[nmsk] /* shift right and */\n"
139 /* maybe %[nmsk] is zero meanwhile, check for it and
142 " adcb $0, %[cnt] /* add 1 if carry was set*/\n"
144 " sarl $1, %[nmsk] /* shift right and */\n"
146 " adcb $0, %[cnt] /* add 1 if carry was set*/\n"
147 #if !defined HAVE_ASM_RETVAL_IN_EBX
148 " popl %%ebx /* restore EBX */\n"
150 : [cnt] "+c" (cnt) /* <- bit is in here */
151 : [nmsk] "d" (number)
155 #else /* !all the above */
157 __nbits_right_of(int number, char bit)
159 register char cnt = 0;
161 for(n = number & ((1<<bit)-1); n ; n >>= 1)
167 #if 1 /* using the global shit */
168 static inline void*const*
169 cat_morphisms(const void *obj)
171 /* returns a pointer to the array of implementations or
172 * NULL if there are none */
173 if (((const struct lrecord_header*)obj)->morphisms & cat_mk_lc) {
174 return &((const struct __cat_morphism_lcrec_s*)obj)->foo;
176 return &((const struct __cat_morphism_lrec_s*)obj)->foo;
181 cat_morphism(const void *obj, cat_morphism_kind_t kind)
183 unsigned int flags = ((const struct lrecord_header*)obj)->morphisms;
185 if (!__bit_set_p(flags, kind)) {
186 int type = ((const struct lrecord_header*)obj)->type;
189 return morphisms[type].seq_impl;
191 return morphisms[type].set_impl;
193 return morphisms[type].aseq_impl;
195 return morphisms[type].aset_impl;
196 /* list them all here */
199 case number_of_cat_morphism_kinds:
204 void *const*mph = cat_morphisms(obj);
205 return mph[__nbits_right_of(flags, kind)-(flags&1)];
208 #else /* use definition in category.c */
209 extern void *cat_morphism(const void*, cat_morphism_kind_t);
210 extern void *const*cat_morphisms(const void*);
212 #endif /* INCLUDED_category_h_ */