chiark / gitweb /
Expunge revision histories in files.
[catacomb] / mpscan.h
1 /* -*-c-*-
2  *
3  * $Id: mpscan.h,v 1.5 2004/04/08 01:36:15 mdw Exp $
4  *
5  * Sequential bit scan of multiprecision integers
6  *
7  * (c) 1999 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 #ifndef CATACOMB_MPSCAN_H
31 #define CATACOMB_MPSCAN_H
32
33 #ifdef __cplusplus
34   extern "C" {
35 #endif
36
37 /*----- Header files ------------------------------------------------------*/
38
39 #ifndef CATACOMB_MPW_H
40 #  include "mpw.h"
41 #endif
42
43 /*----- Data structures ---------------------------------------------------*/
44
45 typedef struct mpscan {
46   const mpw *v, *vl;                    /* Vector of words to scan */
47   mpw w;                                /* Current word to scan */
48   int bits;                             /* Number of bits left in @w@ */
49 } mpscan;
50
51 /*----- Right-to-left scanning --------------------------------------------*/
52
53 /* --- @mpscan_initx@ --- *
54  *
55  * Arguments:   @mpscan *m@ = pointer to bitscanner structure
56  *              @const mpw *v, *vl@ = vector of words to scan
57  *
58  * Returns:     ---
59  *
60  * Use:         Initializes a bitscanner from a low-level base-and-limit
61  *              representation of an integer.  Initially no bit is ready; you
62  *              must call @mpscan_step@ before anything useful will come
63  *              out.
64  */
65
66 #define MPSCAN_INITX(m_, v_, vl_) do {                                  \
67   mpscan *_m = (m_);                                                    \
68   _m->v = (v_);                                                         \
69   _m->vl = (vl_);                                                       \
70   _m->bits = 0;                                                         \
71 } while (0)
72
73 extern void mpscan_initx(mpscan */*m*/, const mpw */*v*/, const mpw */*vl*/);
74
75 /* --- @mpscan_step@ --- *
76  *
77  * Arguments:   @mpscan *m@ = pointer to bitscanner
78  *
79  * Returns:     Nonzero if there is another bit to read.
80  *
81  * Use:         Steps on to the next bit in the integer.  The macro version
82  *              evaluates its argument multiple times.
83  */
84
85 #define MPSCAN_STEP(m)                                                  \
86   ((m)->bits ? ((m)->w >>= 1, (m)->bits--, 1) :                         \
87    (m)->v < (m)->vl ? ((m)->w = *(m)->v++,                              \
88                        (m)->bits = MPW_BITS - 1, 1) :                   \
89    0)
90
91 extern int mpscan_step(mpscan */*m*/);
92
93 /* --- @mpscan_bit@ --- *
94  *
95  * Arguments:   @const mpscan *m@ = pointer to bitscanner
96  *
97  * Returns:     The value of the current bit.
98  *
99  * Use:         Reads the value of the current bit looked at by a
100  *              bitscanner.
101  */
102
103 #define MPSCAN_BIT(m) ((m)->w & 1)
104
105 extern int mpscan_bit(const mpscan */*m*/);
106
107 /*----- Left-to right-scanning --------------------------------------------*/
108
109 /* --- @mpscan_rinitx@ --- *
110  *
111  * Arguments:   @mpscan *m@ = pointer to bitscanner structure
112  *              @const mpw *v, *vl@ = vector of words to scan
113  *
114  * Returns:     ---
115  *
116  * Use:         Initializes a reverse bitscanner from a low-level
117  *              vector-and-length representation of an integer.  Initially no
118  *              bit is ready; you must call @mpscan_rstep@ before anything
119  *              useful will come out.
120  */
121
122 #define MPSCAN_RINITX(m_, v_, vl_) do {                                 \
123   mpscan *_m = (m_);                                                    \
124   _m->v = (v_);                                                         \
125   _m->vl = (vl_);                                                       \
126   while (_m->vl > _m->v && !_m->vl[-1])                                 \
127     _m->vl--;                                                           \
128   _m->bits = 0;                                                         \
129 } while (0)
130
131 extern void mpscan_rinitx(mpscan */*m*/,
132                           const mpw */*v*/, const mpw */*vl*/);
133
134 /* --- @mpscan_rstep@ --- *
135  *
136  * Arguments:   @mpscan *m@ = pointer to bitscanner
137  *
138  * Returns:     Nonzero if there is another bit to read.
139  *
140  * Use:         Steps on to the next bit in the integer.  The macro version
141  *              evaluates its argument multiple times.
142  */
143
144 #define MPSCAN_RSTEP(m)                                                 \
145   ((m)->bits ? ((m)->w <<= 1, (m)->bits--, 1) :                         \
146    (m)->vl > (m)->v ? ((m)->w = *--(m)->vl,                             \
147                        (m)->bits = MPW_BITS - 1, 1) :                   \
148    0)
149
150 extern int mpscan_rstep(mpscan */*m*/);
151
152 /* --- @mpscan_rbit@ --- *
153  *
154  * Arguments:   @const mpscan *m@ = pointer to bitscanner
155  *
156  * Returns:     The value of the current bit.
157  *
158  * Use:         Reads the value of the current bit looked at by a
159  *              reverse bitscanner.
160  */
161
162 #define MPSCAN_RBIT(m) (((m)->w >> (MPW_BITS - 1)) & 1)
163
164 extern int mpscan_rbit(const mpscan */*m*/);
165
166 /*----- That's all, folks -------------------------------------------------*/
167
168 #ifdef __cplusplus
169   }
170 #endif
171
172 #endif