annotate gcc/poly-int.h @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1 /* Polynomial integer classes.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2014-2020 Free Software Foundation, Inc.
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4 This file is part of GCC.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
5
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
9 version.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
10
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
14 for more details.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
15
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
19
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
20 /* This file provides a representation of sizes and offsets whose exact
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
21 values depend on certain runtime properties. The motivating example
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
22 is the Arm SVE ISA, in which the number of vector elements is only
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
23 known at runtime. See doc/poly-int.texi for more details.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
24
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
25 Tests for poly-int.h are located in testsuite/gcc.dg/plugin,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
26 since they are too expensive (in terms of binary size) to be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
27 included as selftests. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
28
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
29 #ifndef HAVE_POLY_INT_H
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
30 #define HAVE_POLY_INT_H
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
31
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
32 template<unsigned int N, typename T> struct poly_int_pod;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
33 template<unsigned int N, typename T> class poly_int;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
34
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
35 /* poly_coeff_traiits<T> describes the properties of a poly_int
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
36 coefficient type T:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
37
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
38 - poly_coeff_traits<T1>::rank is less than poly_coeff_traits<T2>::rank
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
39 if T1 can promote to T2. For C-like types the rank is:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
40
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
41 (2 * number of bytes) + (unsigned ? 1 : 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
42
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
43 wide_ints don't have a normal rank and so use a value of INT_MAX.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
44 Any fixed-width integer should be promoted to wide_int if possible
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
45 and lead to an error otherwise.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
46
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
47 - poly_coeff_traits<T>::int_type is the type to which an integer
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
48 literal should be cast before comparing it with T.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
49
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
50 - poly_coeff_traits<T>::precision is the number of bits that T can hold.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
51
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
52 - poly_coeff_traits<T>::signedness is:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
53 0 if T is unsigned
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
54 1 if T is signed
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
55 -1 if T has no inherent sign (as for wide_int).
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
56
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
57 - poly_coeff_traits<T>::max_value, if defined, is the maximum value of T.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
58
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
59 - poly_coeff_traits<T>::result is a type that can hold results of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
60 operations on T. This is different from T itself in cases where T
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
61 is the result of an accessor like wi::to_offset. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
62 template<typename T, wi::precision_type = wi::int_traits<T>::precision_type>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
63 struct poly_coeff_traits;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
64
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
65 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
66 struct poly_coeff_traits<T, wi::FLEXIBLE_PRECISION>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
67 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
68 typedef T result;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
69 typedef T int_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
70 static const int signedness = (T (0) >= T (-1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
71 static const int precision = sizeof (T) * CHAR_BIT;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
72 static const T max_value = (signedness
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
73 ? ((T (1) << (precision - 2))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
74 + ((T (1) << (precision - 2)) - 1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
75 : T (-1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
76 static const int rank = sizeof (T) * 2 + !signedness;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
77 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
78
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
79 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
80 struct poly_coeff_traits<T, wi::VAR_PRECISION>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
81 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
82 typedef T result;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
83 typedef int int_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
84 static const int signedness = -1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
85 static const int precision = WIDE_INT_MAX_PRECISION;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
86 static const int rank = INT_MAX;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
87 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
88
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
89 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
90 struct poly_coeff_traits<T, wi::CONST_PRECISION>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
91 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
92 typedef WI_UNARY_RESULT (T) result;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
93 typedef int int_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
94 /* These types are always signed. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
95 static const int signedness = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
96 static const int precision = wi::int_traits<T>::precision;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
97 static const int rank = precision * 2 / CHAR_BIT;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
98 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
99
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
100 /* Information about a pair of coefficient types. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
101 template<typename T1, typename T2>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
102 struct poly_coeff_pair_traits
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
103 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
104 /* True if T1 can represent all the values of T2.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
105
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
106 Either:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
107
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
108 - T1 should be a type with the same signedness as T2 and no less
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
109 precision. This allows things like int16_t -> int16_t and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
110 uint32_t -> uint64_t.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
111
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
112 - T1 should be signed, T2 should be unsigned, and T1 should be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
113 wider than T2. This allows things like uint16_t -> int32_t.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
114
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
115 This rules out cases in which T1 has less precision than T2 or where
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
116 the conversion would reinterpret the top bit. E.g. int16_t -> uint32_t
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
117 can be dangerous and should have an explicit cast if deliberate. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
118 static const bool lossless_p = (poly_coeff_traits<T1>::signedness
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
119 == poly_coeff_traits<T2>::signedness
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
120 ? (poly_coeff_traits<T1>::precision
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
121 >= poly_coeff_traits<T2>::precision)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
122 : (poly_coeff_traits<T1>::signedness == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
123 && poly_coeff_traits<T2>::signedness == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
124 && (poly_coeff_traits<T1>::precision
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
125 > poly_coeff_traits<T2>::precision)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
126
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
127 /* 0 if T1 op T2 should promote to HOST_WIDE_INT,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
128 1 if T1 op T2 should promote to unsigned HOST_WIDE_INT,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
129 2 if T1 op T2 should use wide-int rules. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
130 #define RANK(X) poly_coeff_traits<X>::rank
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
131 static const int result_kind
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
132 = ((RANK (T1) <= RANK (HOST_WIDE_INT)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
133 && RANK (T2) <= RANK (HOST_WIDE_INT))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
134 ? 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
135 : (RANK (T1) <= RANK (unsigned HOST_WIDE_INT)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
136 && RANK (T2) <= RANK (unsigned HOST_WIDE_INT))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
137 ? 1 : 2);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
138 #undef RANK
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
139 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
140
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
141 /* SFINAE class that makes T3 available as "type" if T2 can represent all the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
142 values in T1. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
143 template<typename T1, typename T2, typename T3,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
144 bool lossless_p = poly_coeff_pair_traits<T1, T2>::lossless_p>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
145 struct if_lossless;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
146 template<typename T1, typename T2, typename T3>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
147 struct if_lossless<T1, T2, T3, true>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
148 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
149 typedef T3 type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
150 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
151
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
152 /* poly_int_traits<T> describes an integer type T that might be polynomial
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
153 or non-polynomial:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
154
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
155 - poly_int_traits<T>::is_poly is true if T is a poly_int-based type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
156 and false otherwise.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
157
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
158 - poly_int_traits<T>::num_coeffs gives the number of coefficients in T
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
159 if T is a poly_int and 1 otherwise.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
160
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
161 - poly_int_traits<T>::coeff_type gives the coefficent type of T if T
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
162 is a poly_int and T itself otherwise
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
163
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
164 - poly_int_traits<T>::int_type is a shorthand for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
165 typename poly_coeff_traits<coeff_type>::int_type. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
166 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
167 struct poly_int_traits
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
168 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
169 static const bool is_poly = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
170 static const unsigned int num_coeffs = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
171 typedef T coeff_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
172 typedef typename poly_coeff_traits<T>::int_type int_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
173 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
174 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
175 struct poly_int_traits<poly_int_pod<N, C> >
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
176 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
177 static const bool is_poly = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
178 static const unsigned int num_coeffs = N;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
179 typedef C coeff_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
180 typedef typename poly_coeff_traits<C>::int_type int_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
181 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
182 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
183 struct poly_int_traits<poly_int<N, C> > : poly_int_traits<poly_int_pod<N, C> >
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
184 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
185 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
186
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
187 /* SFINAE class that makes T2 available as "type" if T1 is a non-polynomial
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
188 type. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
189 template<typename T1, typename T2 = T1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
190 bool is_poly = poly_int_traits<T1>::is_poly>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
191 struct if_nonpoly {};
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
192 template<typename T1, typename T2>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
193 struct if_nonpoly<T1, T2, false>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
194 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
195 typedef T2 type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
196 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
197
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
198 /* SFINAE class that makes T3 available as "type" if both T1 and T2 are
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
199 non-polynomial types. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
200 template<typename T1, typename T2, typename T3,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
201 bool is_poly1 = poly_int_traits<T1>::is_poly,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
202 bool is_poly2 = poly_int_traits<T2>::is_poly>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
203 struct if_nonpoly2 {};
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
204 template<typename T1, typename T2, typename T3>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
205 struct if_nonpoly2<T1, T2, T3, false, false>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
206 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
207 typedef T3 type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
208 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
209
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
210 /* SFINAE class that makes T2 available as "type" if T1 is a polynomial
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
211 type. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
212 template<typename T1, typename T2 = T1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
213 bool is_poly = poly_int_traits<T1>::is_poly>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
214 struct if_poly {};
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
215 template<typename T1, typename T2>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
216 struct if_poly<T1, T2, true>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
217 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
218 typedef T2 type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
219 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
220
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
221 /* poly_result<T1, T2> describes the result of an operation on two
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
222 types T1 and T2, where at least one of the types is polynomial:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
223
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
224 - poly_result<T1, T2>::type gives the result type for the operation.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
225 The intention is to provide normal C-like rules for integer ranks,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
226 except that everything smaller than HOST_WIDE_INT promotes to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
227 HOST_WIDE_INT.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
228
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
229 - poly_result<T1, T2>::cast is the type to which an operand of type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
230 T1 should be cast before doing the operation, to ensure that
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
231 the operation is done at the right precision. Casting to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
232 poly_result<T1, T2>::type would also work, but casting to this
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
233 type is more efficient. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
234 template<typename T1, typename T2 = T1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
235 int result_kind = poly_coeff_pair_traits<T1, T2>::result_kind>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
236 struct poly_result;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
237
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
238 /* Promote pair to HOST_WIDE_INT. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
239 template<typename T1, typename T2>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
240 struct poly_result<T1, T2, 0>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
241 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
242 typedef HOST_WIDE_INT type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
243 /* T1 and T2 are primitive types, so cast values to T before operating
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
244 on them. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
245 typedef type cast;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
246 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
247
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
248 /* Promote pair to unsigned HOST_WIDE_INT. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
249 template<typename T1, typename T2>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
250 struct poly_result<T1, T2, 1>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
251 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
252 typedef unsigned HOST_WIDE_INT type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
253 /* T1 and T2 are primitive types, so cast values to T before operating
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
254 on them. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
255 typedef type cast;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
256 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
257
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
258 /* Use normal wide-int rules. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
259 template<typename T1, typename T2>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
260 struct poly_result<T1, T2, 2>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
261 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
262 typedef WI_BINARY_RESULT (T1, T2) type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
263 /* Don't cast values before operating on them; leave the wi:: routines
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
264 to handle promotion as necessary. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
265 typedef const T1 &cast;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
266 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
267
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
268 /* The coefficient type for the result of a binary operation on two
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
269 poly_ints, the first of which has coefficients of type C1 and the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
270 second of which has coefficients of type C2. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
271 #define POLY_POLY_COEFF(C1, C2) typename poly_result<C1, C2>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
272
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
273 /* Enforce that T2 is non-polynomial and provide the cofficient type of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
274 the result of a binary operation in which the first operand is a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
275 poly_int with coefficients of type C1 and the second operand is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
276 a constant of type T2. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
277 #define POLY_CONST_COEFF(C1, T2) \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
278 POLY_POLY_COEFF (C1, typename if_nonpoly<T2>::type)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
279
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
280 /* Likewise in reverse. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
281 #define CONST_POLY_COEFF(T1, C2) \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
282 POLY_POLY_COEFF (typename if_nonpoly<T1>::type, C2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
283
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
284 /* The result type for a binary operation on poly_int<N, C1> and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
285 poly_int<N, C2>. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
286 #define POLY_POLY_RESULT(N, C1, C2) poly_int<N, POLY_POLY_COEFF (C1, C2)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
287
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
288 /* Enforce that T2 is non-polynomial and provide the result type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
289 for a binary operation on poly_int<N, C1> and T2. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
290 #define POLY_CONST_RESULT(N, C1, T2) poly_int<N, POLY_CONST_COEFF (C1, T2)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
291
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
292 /* Enforce that T1 is non-polynomial and provide the result type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
293 for a binary operation on T1 and poly_int<N, C2>. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
294 #define CONST_POLY_RESULT(N, T1, C2) poly_int<N, CONST_POLY_COEFF (T1, C2)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
295
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
296 /* Enforce that T1 and T2 are non-polynomial and provide the result type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
297 for a binary operation on T1 and T2. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
298 #define CONST_CONST_RESULT(N, T1, T2) \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
299 POLY_POLY_COEFF (typename if_nonpoly<T1>::type, \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
300 typename if_nonpoly<T2>::type)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
301
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
302 /* The type to which a coefficient of type C1 should be cast before
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
303 using it in a binary operation with a coefficient of type C2. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
304 #define POLY_CAST(C1, C2) typename poly_result<C1, C2>::cast
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
305
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
306 /* Provide the coefficient type for the result of T1 op T2, where T1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
307 and T2 can be polynomial or non-polynomial. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
308 #define POLY_BINARY_COEFF(T1, T2) \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
309 typename poly_result<typename poly_int_traits<T1>::coeff_type, \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
310 typename poly_int_traits<T2>::coeff_type>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
311
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
312 /* The type to which an integer constant should be cast before
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
313 comparing it with T. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
314 #define POLY_INT_TYPE(T) typename poly_int_traits<T>::int_type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
315
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
316 /* RES is a poly_int result that has coefficients of type C and that
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
317 is being built up a coefficient at a time. Set coefficient number I
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
318 to VALUE in the most efficient way possible.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
319
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
320 For primitive C it is better to assign directly, since it avoids
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
321 any further calls and so is more efficient when the compiler is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
322 built at -O0. But for wide-int based C it is better to construct
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
323 the value in-place. This means that calls out to a wide-int.cc
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
324 routine can take the address of RES rather than the address of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
325 a temporary.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
326
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
327 The dummy comparison against a null C * is just a way of checking
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
328 that C gives the right type. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
329 #define POLY_SET_COEFF(C, RES, I, VALUE) \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
330 ((void) (&(RES).coeffs[0] == (C *) 0), \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
331 wi::int_traits<C>::precision_type == wi::FLEXIBLE_PRECISION \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
332 ? (void) ((RES).coeffs[I] = VALUE) \
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
333 : (void) ((RES).coeffs[I].~C (), new (&(RES).coeffs[I]) C (VALUE)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
334
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
335 /* A base POD class for polynomial integers. The polynomial has N
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
336 coefficients of type C. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
337 template<unsigned int N, typename C>
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
338 struct poly_int_pod
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
339 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
340 public:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
341 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
342 poly_int_pod &operator = (const poly_int_pod<N, Ca> &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
343 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
344 typename if_nonpoly<Ca, poly_int_pod>::type &operator = (const Ca &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
345
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
346 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
347 poly_int_pod &operator += (const poly_int_pod<N, Ca> &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
348 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
349 typename if_nonpoly<Ca, poly_int_pod>::type &operator += (const Ca &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
350
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
351 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
352 poly_int_pod &operator -= (const poly_int_pod<N, Ca> &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
353 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
354 typename if_nonpoly<Ca, poly_int_pod>::type &operator -= (const Ca &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
355
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
356 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
357 typename if_nonpoly<Ca, poly_int_pod>::type &operator *= (const Ca &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
358
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
359 poly_int_pod &operator <<= (unsigned int);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
360
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
361 bool is_constant () const;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
362
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
363 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
364 typename if_lossless<T, C, bool>::type is_constant (T *) const;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
365
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
366 C to_constant () const;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
367
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
368 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
369 static poly_int<N, C> from (const poly_int_pod<N, Ca> &, unsigned int,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
370 signop);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
371 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
372 static poly_int<N, C> from (const poly_int_pod<N, Ca> &, signop);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
373
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
374 bool to_shwi (poly_int_pod<N, HOST_WIDE_INT> *) const;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
375 bool to_uhwi (poly_int_pod<N, unsigned HOST_WIDE_INT> *) const;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
376 poly_int<N, HOST_WIDE_INT> force_shwi () const;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
377 poly_int<N, unsigned HOST_WIDE_INT> force_uhwi () const;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
378
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
379 #if POLY_INT_CONVERSION
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
380 operator C () const;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
381 #endif
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
382
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
383 C coeffs[N];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
384 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
385
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
386 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
387 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
388 inline poly_int_pod<N, C>&
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
389 poly_int_pod<N, C>::operator = (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
390 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
391 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
392 POLY_SET_COEFF (C, *this, i, a.coeffs[i]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
393 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
394 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
395
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
396 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
397 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
398 inline typename if_nonpoly<Ca, poly_int_pod<N, C> >::type &
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
399 poly_int_pod<N, C>::operator = (const Ca &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
400 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
401 POLY_SET_COEFF (C, *this, 0, a);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
402 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
403 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
404 POLY_SET_COEFF (C, *this, i, wi::ints_for<C>::zero (this->coeffs[0]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
405 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
406 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
407
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
408 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
409 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
410 inline poly_int_pod<N, C>&
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
411 poly_int_pod<N, C>::operator += (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
412 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
413 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
414 this->coeffs[i] += a.coeffs[i];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
415 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
416 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
417
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
418 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
419 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
420 inline typename if_nonpoly<Ca, poly_int_pod<N, C> >::type &
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
421 poly_int_pod<N, C>::operator += (const Ca &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
422 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
423 this->coeffs[0] += a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
424 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
425 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
426
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
427 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
428 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
429 inline poly_int_pod<N, C>&
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
430 poly_int_pod<N, C>::operator -= (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
431 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
432 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
433 this->coeffs[i] -= a.coeffs[i];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
434 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
435 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
436
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
437 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
438 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
439 inline typename if_nonpoly<Ca, poly_int_pod<N, C> >::type &
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
440 poly_int_pod<N, C>::operator -= (const Ca &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
441 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
442 this->coeffs[0] -= a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
443 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
444 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
445
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
446 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
447 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
448 inline typename if_nonpoly<Ca, poly_int_pod<N, C> >::type &
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
449 poly_int_pod<N, C>::operator *= (const Ca &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
450 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
451 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
452 this->coeffs[i] *= a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
453 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
454 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
455
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
456 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
457 inline poly_int_pod<N, C>&
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
458 poly_int_pod<N, C>::operator <<= (unsigned int a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
459 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
460 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
461 this->coeffs[i] <<= a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
462 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
463 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
464
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
465 /* Return true if the polynomial value is a compile-time constant. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
466
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
467 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
468 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
469 poly_int_pod<N, C>::is_constant () const
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
470 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
471 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
472 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
473 if (this->coeffs[i] != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
474 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
475 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
476 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
477
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
478 /* Return true if the polynomial value is a compile-time constant,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
479 storing its value in CONST_VALUE if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
480
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
481 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
482 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
483 inline typename if_lossless<T, C, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
484 poly_int_pod<N, C>::is_constant (T *const_value) const
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
485 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
486 if (is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
487 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
488 *const_value = this->coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
489 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
490 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
491 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
492 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
493
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
494 /* Return the value of a polynomial that is already known to be a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
495 compile-time constant.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
496
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
497 NOTE: When using this function, please add a comment above the call
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
498 explaining why we know the value is constant in that context. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
499
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
500 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
501 inline C
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
502 poly_int_pod<N, C>::to_constant () const
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
503 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
504 gcc_checking_assert (is_constant ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
505 return this->coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
506 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
507
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
508 /* Convert X to a wide_int-based polynomial in which each coefficient
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
509 has BITSIZE bits. If X's coefficients are smaller than BITSIZE,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
510 extend them according to SGN. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
511
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
512 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
513 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
514 inline poly_int<N, C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
515 poly_int_pod<N, C>::from (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
516 unsigned int bitsize, signop sgn)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
517 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
518 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
519 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
520 POLY_SET_COEFF (C, r, i, C::from (a.coeffs[i], bitsize, sgn));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
521 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
522 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
523
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
524 /* Convert X to a fixed_wide_int-based polynomial, extending according
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
525 to SGN. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
526
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
527 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
528 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
529 inline poly_int<N, C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
530 poly_int_pod<N, C>::from (const poly_int_pod<N, Ca> &a, signop sgn)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
531 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
532 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
533 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
534 POLY_SET_COEFF (C, r, i, C::from (a.coeffs[i], sgn));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
535 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
536 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
537
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
538 /* Return true if the coefficients of this generic_wide_int-based
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
539 polynomial can be represented as signed HOST_WIDE_INTs without loss
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
540 of precision. Store the HOST_WIDE_INT representation in *R if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
541
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
542 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
543 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
544 poly_int_pod<N, C>::to_shwi (poly_int_pod<N, HOST_WIDE_INT> *r) const
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
545 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
546 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
547 if (!wi::fits_shwi_p (this->coeffs[i]))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
548 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
549 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
550 r->coeffs[i] = this->coeffs[i].to_shwi ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
551 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
552 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
553
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
554 /* Return true if the coefficients of this generic_wide_int-based
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
555 polynomial can be represented as unsigned HOST_WIDE_INTs without
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
556 loss of precision. Store the unsigned HOST_WIDE_INT representation
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
557 in *R if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
558
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
559 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
560 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
561 poly_int_pod<N, C>::to_uhwi (poly_int_pod<N, unsigned HOST_WIDE_INT> *r) const
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
562 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
563 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
564 if (!wi::fits_uhwi_p (this->coeffs[i]))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
565 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
566 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
567 r->coeffs[i] = this->coeffs[i].to_uhwi ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
568 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
569 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
570
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
571 /* Force a generic_wide_int-based constant to HOST_WIDE_INT precision,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
572 truncating if necessary. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
573
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
574 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
575 inline poly_int<N, HOST_WIDE_INT>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
576 poly_int_pod<N, C>::force_shwi () const
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
577 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
578 poly_int_pod<N, HOST_WIDE_INT> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
579 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
580 r.coeffs[i] = this->coeffs[i].to_shwi ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
581 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
582 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
583
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
584 /* Force a generic_wide_int-based constant to unsigned HOST_WIDE_INT precision,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
585 truncating if necessary. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
586
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
587 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
588 inline poly_int<N, unsigned HOST_WIDE_INT>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
589 poly_int_pod<N, C>::force_uhwi () const
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
590 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
591 poly_int_pod<N, unsigned HOST_WIDE_INT> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
592 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
593 r.coeffs[i] = this->coeffs[i].to_uhwi ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
594 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
595 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
596
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
597 #if POLY_INT_CONVERSION
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
598 /* Provide a conversion operator to constants. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
599
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
600 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
601 inline
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
602 poly_int_pod<N, C>::operator C () const
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
603 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
604 gcc_checking_assert (this->is_constant ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
605 return this->coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
606 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
607 #endif
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
608
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
609 /* The main class for polynomial integers. The class provides
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
610 constructors that are necessarily missing from the POD base. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
611 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
612 class poly_int : public poly_int_pod<N, C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
613 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
614 public:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
615 poly_int () {}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
616
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
617 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
618 poly_int (const poly_int<N, Ca> &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
619 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
620 poly_int (const poly_int_pod<N, Ca> &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
621 template<typename C0>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
622 poly_int (const C0 &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
623 template<typename C0, typename C1>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
624 poly_int (const C0 &, const C1 &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
625
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
626 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
627 poly_int &operator = (const poly_int_pod<N, Ca> &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
628 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
629 typename if_nonpoly<Ca, poly_int>::type &operator = (const Ca &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
630
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
631 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
632 poly_int &operator += (const poly_int_pod<N, Ca> &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
633 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
634 typename if_nonpoly<Ca, poly_int>::type &operator += (const Ca &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
635
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
636 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
637 poly_int &operator -= (const poly_int_pod<N, Ca> &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
638 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
639 typename if_nonpoly<Ca, poly_int>::type &operator -= (const Ca &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
640
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
641 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
642 typename if_nonpoly<Ca, poly_int>::type &operator *= (const Ca &);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
643
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
644 poly_int &operator <<= (unsigned int);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
645 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
646
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
647 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
648 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
649 inline
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
650 poly_int<N, C>::poly_int (const poly_int<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
651 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
652 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
653 POLY_SET_COEFF (C, *this, i, a.coeffs[i]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
654 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
655
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
656 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
657 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
658 inline
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
659 poly_int<N, C>::poly_int (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
660 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
661 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
662 POLY_SET_COEFF (C, *this, i, a.coeffs[i]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
663 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
664
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
665 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
666 template<typename C0>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
667 inline
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
668 poly_int<N, C>::poly_int (const C0 &c0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
669 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
670 POLY_SET_COEFF (C, *this, 0, c0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
671 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
672 POLY_SET_COEFF (C, *this, i, wi::ints_for<C>::zero (this->coeffs[0]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
673 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
674
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
675 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
676 template<typename C0, typename C1>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
677 inline
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
678 poly_int<N, C>::poly_int (const C0 &c0, const C1 &c1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
679 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
680 STATIC_ASSERT (N >= 2);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
681 POLY_SET_COEFF (C, *this, 0, c0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
682 POLY_SET_COEFF (C, *this, 1, c1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
683 for (unsigned int i = 2; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
684 POLY_SET_COEFF (C, *this, i, wi::ints_for<C>::zero (this->coeffs[0]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
685 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
686
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
687 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
688 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
689 inline poly_int<N, C>&
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
690 poly_int<N, C>::operator = (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
691 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
692 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
693 this->coeffs[i] = a.coeffs[i];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
694 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
695 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
696
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
697 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
698 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
699 inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
700 poly_int<N, C>::operator = (const Ca &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
701 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
702 this->coeffs[0] = a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
703 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
704 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
705 this->coeffs[i] = wi::ints_for<C>::zero (this->coeffs[0]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
706 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
707 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
708
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
709 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
710 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
711 inline poly_int<N, C>&
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
712 poly_int<N, C>::operator += (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
713 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
714 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
715 this->coeffs[i] += a.coeffs[i];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
716 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
717 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
718
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
719 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
720 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
721 inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
722 poly_int<N, C>::operator += (const Ca &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
723 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
724 this->coeffs[0] += a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
725 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
726 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
727
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
728 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
729 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
730 inline poly_int<N, C>&
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
731 poly_int<N, C>::operator -= (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
732 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
733 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
734 this->coeffs[i] -= a.coeffs[i];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
735 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
736 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
737
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
738 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
739 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
740 inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
741 poly_int<N, C>::operator -= (const Ca &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
742 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
743 this->coeffs[0] -= a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
744 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
745 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
746
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
747 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
748 template<typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
749 inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
750 poly_int<N, C>::operator *= (const Ca &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
751 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
752 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
753 this->coeffs[i] *= a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
754 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
755 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
756
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
757 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
758 inline poly_int<N, C>&
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
759 poly_int<N, C>::operator <<= (unsigned int a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
760 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
761 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
762 this->coeffs[i] <<= a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
763 return *this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
764 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
765
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
766 /* Return true if every coefficient of A is in the inclusive range [B, C]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
767
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
768 template<typename Ca, typename Cb, typename Cc>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
769 inline typename if_nonpoly<Ca, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
770 coeffs_in_range_p (const Ca &a, const Cb &b, const Cc &c)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
771 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
772 return a >= b && a <= c;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
773 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
774
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
775 template<unsigned int N, typename Ca, typename Cb, typename Cc>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
776 inline typename if_nonpoly<Ca, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
777 coeffs_in_range_p (const poly_int_pod<N, Ca> &a, const Cb &b, const Cc &c)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
778 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
779 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
780 if (a.coeffs[i] < b || a.coeffs[i] > c)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
781 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
782 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
783 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
784
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
785 namespace wi {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
786 /* Poly version of wi::shwi, with the same interface. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
787
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
788 template<unsigned int N>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
789 inline poly_int<N, hwi_with_prec>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
790 shwi (const poly_int_pod<N, HOST_WIDE_INT> &a, unsigned int precision)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
791 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
792 poly_int<N, hwi_with_prec> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
793 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
794 POLY_SET_COEFF (hwi_with_prec, r, i, wi::shwi (a.coeffs[i], precision));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
795 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
796 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
797
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
798 /* Poly version of wi::uhwi, with the same interface. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
799
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
800 template<unsigned int N>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
801 inline poly_int<N, hwi_with_prec>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
802 uhwi (const poly_int_pod<N, unsigned HOST_WIDE_INT> &a, unsigned int precision)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
803 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
804 poly_int<N, hwi_with_prec> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
805 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
806 POLY_SET_COEFF (hwi_with_prec, r, i, wi::uhwi (a.coeffs[i], precision));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
807 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
808 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
809
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
810 /* Poly version of wi::sext, with the same interface. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
811
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
812 template<unsigned int N, typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
813 inline POLY_POLY_RESULT (N, Ca, Ca)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
814 sext (const poly_int_pod<N, Ca> &a, unsigned int precision)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
815 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
816 typedef POLY_POLY_COEFF (Ca, Ca) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
817 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
818 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
819 POLY_SET_COEFF (C, r, i, wi::sext (a.coeffs[i], precision));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
820 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
821 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
822
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
823 /* Poly version of wi::zext, with the same interface. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
824
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
825 template<unsigned int N, typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
826 inline POLY_POLY_RESULT (N, Ca, Ca)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
827 zext (const poly_int_pod<N, Ca> &a, unsigned int precision)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
828 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
829 typedef POLY_POLY_COEFF (Ca, Ca) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
830 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
831 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
832 POLY_SET_COEFF (C, r, i, wi::zext (a.coeffs[i], precision));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
833 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
834 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
835 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
836
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
837 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
838 inline POLY_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
839 operator + (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
840 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
841 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
842 typedef POLY_POLY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
843 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
844 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
845 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) + b.coeffs[i]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
846 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
847 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
848
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
849 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
850 inline POLY_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
851 operator + (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
852 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
853 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
854 typedef POLY_CONST_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
855 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
856 POLY_SET_COEFF (C, r, 0, NCa (a.coeffs[0]) + b);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
857 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
858 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
859 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
860 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
861 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
862
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
863 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
864 inline CONST_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
865 operator + (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
866 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
867 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
868 typedef CONST_POLY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
869 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
870 POLY_SET_COEFF (C, r, 0, a + NCb (b.coeffs[0]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
871 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
872 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
873 POLY_SET_COEFF (C, r, i, NCb (b.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
874 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
875 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
876
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
877 namespace wi {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
878 /* Poly versions of wi::add, with the same interface. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
879
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
880 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
881 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
882 add (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
883 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
884 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
885 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
886 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
887 POLY_SET_COEFF (C, r, i, wi::add (a.coeffs[i], b.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
888 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
889 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
890
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
891 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
892 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
893 add (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
894 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
895 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
896 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
897 POLY_SET_COEFF (C, r, 0, wi::add (a.coeffs[0], b));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
898 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
899 POLY_SET_COEFF (C, r, i, wi::add (a.coeffs[i],
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
900 wi::ints_for<Cb>::zero (b)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
901 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
902 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
903
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
904 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
905 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
906 add (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
907 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
908 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
909 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
910 POLY_SET_COEFF (C, r, 0, wi::add (a, b.coeffs[0]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
911 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
912 POLY_SET_COEFF (C, r, i, wi::add (wi::ints_for<Ca>::zero (a),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
913 b.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
914 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
915 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
916
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
917 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
918 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
919 add (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
920 signop sgn, wi::overflow_type *overflow)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
921 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
922 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
923 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
924 POLY_SET_COEFF (C, r, 0, wi::add (a.coeffs[0], b.coeffs[0], sgn, overflow));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
925 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
926 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
927 wi::overflow_type suboverflow;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
928 POLY_SET_COEFF (C, r, i, wi::add (a.coeffs[i], b.coeffs[i], sgn,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
929 &suboverflow));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
930 wi::accumulate_overflow (*overflow, suboverflow);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
931 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
932 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
933 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
934 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
935
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
936 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
937 inline POLY_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
938 operator - (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
939 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
940 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
941 typedef POLY_POLY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
942 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
943 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
944 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) - b.coeffs[i]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
945 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
946 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
947
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
948 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
949 inline POLY_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
950 operator - (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
951 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
952 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
953 typedef POLY_CONST_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
954 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
955 POLY_SET_COEFF (C, r, 0, NCa (a.coeffs[0]) - b);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
956 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
957 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
958 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
959 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
960 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
961
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
962 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
963 inline CONST_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
964 operator - (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
965 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
966 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
967 typedef CONST_POLY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
968 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
969 POLY_SET_COEFF (C, r, 0, a - NCb (b.coeffs[0]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
970 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
971 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
972 POLY_SET_COEFF (C, r, i, -NCb (b.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
973 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
974 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
975
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
976 namespace wi {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
977 /* Poly versions of wi::sub, with the same interface. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
978
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
979 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
980 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
981 sub (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
982 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
983 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
984 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
985 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
986 POLY_SET_COEFF (C, r, i, wi::sub (a.coeffs[i], b.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
987 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
988 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
989
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
990 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
991 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
992 sub (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
993 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
994 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
995 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
996 POLY_SET_COEFF (C, r, 0, wi::sub (a.coeffs[0], b));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
997 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
998 POLY_SET_COEFF (C, r, i, wi::sub (a.coeffs[i],
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
999 wi::ints_for<Cb>::zero (b)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1000 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1001 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1002
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1003 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1004 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1005 sub (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1006 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1007 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1008 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1009 POLY_SET_COEFF (C, r, 0, wi::sub (a, b.coeffs[0]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1010 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1011 POLY_SET_COEFF (C, r, i, wi::sub (wi::ints_for<Ca>::zero (a),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1012 b.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1013 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1014 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1015
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1016 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1017 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1018 sub (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1019 signop sgn, wi::overflow_type *overflow)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1020 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1021 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1022 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1023 POLY_SET_COEFF (C, r, 0, wi::sub (a.coeffs[0], b.coeffs[0], sgn, overflow));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1024 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1025 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1026 wi::overflow_type suboverflow;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1027 POLY_SET_COEFF (C, r, i, wi::sub (a.coeffs[i], b.coeffs[i], sgn,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1028 &suboverflow));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1029 wi::accumulate_overflow (*overflow, suboverflow);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1030 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1031 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1032 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1033 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1034
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1035 template<unsigned int N, typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1036 inline POLY_POLY_RESULT (N, Ca, Ca)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1037 operator - (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1038 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1039 typedef POLY_CAST (Ca, Ca) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1040 typedef POLY_POLY_COEFF (Ca, Ca) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1041 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1042 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1043 POLY_SET_COEFF (C, r, i, -NCa (a.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1044 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1045 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1046
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1047 namespace wi {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1048 /* Poly version of wi::neg, with the same interface. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1049
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1050 template<unsigned int N, typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1051 inline poly_int<N, WI_UNARY_RESULT (Ca)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1052 neg (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1053 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1054 typedef WI_UNARY_RESULT (Ca) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1055 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1056 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1057 POLY_SET_COEFF (C, r, i, wi::neg (a.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1058 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1059 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1060
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1061 template<unsigned int N, typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1062 inline poly_int<N, WI_UNARY_RESULT (Ca)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1063 neg (const poly_int_pod<N, Ca> &a, wi::overflow_type *overflow)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1064 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1065 typedef WI_UNARY_RESULT (Ca) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1066 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1067 POLY_SET_COEFF (C, r, 0, wi::neg (a.coeffs[0], overflow));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1068 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1069 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1070 wi::overflow_type suboverflow;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1071 POLY_SET_COEFF (C, r, i, wi::neg (a.coeffs[i], &suboverflow));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1072 wi::accumulate_overflow (*overflow, suboverflow);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1073 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1074 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1075 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1076 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1077
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1078 template<unsigned int N, typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1079 inline POLY_POLY_RESULT (N, Ca, Ca)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1080 operator ~ (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1081 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1082 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1083 return -1 - a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1084 return ~a.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1085 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1086
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1087 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1088 inline POLY_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1089 operator * (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1090 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1091 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1092 typedef POLY_CONST_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1093 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1094 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1095 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) * b);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1096 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1097 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1098
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1099 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1100 inline CONST_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1101 operator * (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1102 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1103 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1104 typedef CONST_POLY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1105 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1106 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1107 POLY_SET_COEFF (C, r, i, NCa (a) * b.coeffs[i]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1108 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1109 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1110
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1111 namespace wi {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1112 /* Poly versions of wi::mul, with the same interface. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1113
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1114 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1115 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1116 mul (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1117 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1118 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1119 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1120 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1121 POLY_SET_COEFF (C, r, i, wi::mul (a.coeffs[i], b));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1122 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1123 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1124
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1125 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1126 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1127 mul (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1128 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1129 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1130 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1131 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1132 POLY_SET_COEFF (C, r, i, wi::mul (a, b.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1133 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1134 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1135
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1136 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1137 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1138 mul (const poly_int_pod<N, Ca> &a, const Cb &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1139 signop sgn, wi::overflow_type *overflow)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1140 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1141 typedef WI_BINARY_RESULT (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1142 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1143 POLY_SET_COEFF (C, r, 0, wi::mul (a.coeffs[0], b, sgn, overflow));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1144 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1145 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1146 wi::overflow_type suboverflow;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1147 POLY_SET_COEFF (C, r, i, wi::mul (a.coeffs[i], b, sgn, &suboverflow));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1148 wi::accumulate_overflow (*overflow, suboverflow);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1149 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1150 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1151 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1152 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1153
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1154 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1155 inline POLY_POLY_RESULT (N, Ca, Ca)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1156 operator << (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1157 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1158 typedef POLY_CAST (Ca, Ca) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1159 typedef POLY_POLY_COEFF (Ca, Ca) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1160 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1161 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1162 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) << b);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1163 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1164 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1165
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1166 namespace wi {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1167 /* Poly version of wi::lshift, with the same interface. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1168
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1169 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1170 inline poly_int<N, WI_BINARY_RESULT (Ca, Ca)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1171 lshift (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1172 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1173 typedef WI_BINARY_RESULT (Ca, Ca) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1174 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1175 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1176 POLY_SET_COEFF (C, r, i, wi::lshift (a.coeffs[i], b));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1177 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1178 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1179 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1180
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1181 /* Return true if a0 + a1 * x might equal b0 + b1 * x for some nonnegative
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1182 integer x. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1183
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1184 template<typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1185 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1186 maybe_eq_2 (const Ca &a0, const Ca &a1, const Cb &b0, const Cb &b1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1187 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1188 if (a1 != b1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1189 /* a0 + a1 * x == b0 + b1 * x
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1190 ==> (a1 - b1) * x == b0 - a0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1191 ==> x == (b0 - a0) / (a1 - b1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1192
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1193 We need to test whether that's a valid value of x.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1194 (b0 - a0) and (a1 - b1) must not have opposite signs
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1195 and the result must be integral. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1196 return (a1 < b1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1197 ? b0 <= a0 && (a0 - b0) % (b1 - a1) == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1198 : b0 >= a0 && (b0 - a0) % (a1 - b1) == 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1199 return a0 == b0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1200 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1201
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1202 /* Return true if a0 + a1 * x might equal b for some nonnegative
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1203 integer x. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1204
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1205 template<typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1206 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1207 maybe_eq_2 (const Ca &a0, const Ca &a1, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1208 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1209 if (a1 != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1210 /* a0 + a1 * x == b
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1211 ==> x == (b - a0) / a1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1212
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1213 We need to test whether that's a valid value of x.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1214 (b - a0) and a1 must not have opposite signs and the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1215 result must be integral. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1216 return (a1 < 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1217 ? b <= a0 && (a0 - b) % a1 == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1218 : b >= a0 && (b - a0) % a1 == 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1219 return a0 == b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1220 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1221
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1222 /* Return true if A might equal B for some indeterminate values. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1223
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1224 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1225 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1226 maybe_eq (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1227 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1228 STATIC_ASSERT (N <= 2);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1229 if (N == 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1230 return maybe_eq_2 (a.coeffs[0], a.coeffs[1], b.coeffs[0], b.coeffs[1]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1231 return a.coeffs[0] == b.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1232 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1233
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1234 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1235 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1236 maybe_eq (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1237 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1238 STATIC_ASSERT (N <= 2);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1239 if (N == 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1240 return maybe_eq_2 (a.coeffs[0], a.coeffs[1], b);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1241 return a.coeffs[0] == b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1242 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1243
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1244 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1245 inline typename if_nonpoly<Ca, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1246 maybe_eq (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1247 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1248 STATIC_ASSERT (N <= 2);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1249 if (N == 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1250 return maybe_eq_2 (b.coeffs[0], b.coeffs[1], a);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1251 return a == b.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1252 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1253
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1254 template<typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1255 inline typename if_nonpoly2<Ca, Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1256 maybe_eq (const Ca &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1257 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1258 return a == b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1259 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1260
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1261 /* Return true if A might not equal B for some indeterminate values. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1262
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1263 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1264 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1265 maybe_ne (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1266 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1267 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1268 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1269 if (a.coeffs[i] != b.coeffs[i])
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1270 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1271 return a.coeffs[0] != b.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1272 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1273
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1274 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1275 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1276 maybe_ne (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1277 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1278 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1279 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1280 if (a.coeffs[i] != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1281 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1282 return a.coeffs[0] != b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1283 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1284
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1285 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1286 inline typename if_nonpoly<Ca, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1287 maybe_ne (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1288 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1289 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1290 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1291 if (b.coeffs[i] != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1292 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1293 return a != b.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1294 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1295
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1296 template<typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1297 inline typename if_nonpoly2<Ca, Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1298 maybe_ne (const Ca &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1299 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1300 return a != b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1301 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1302
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1303 /* Return true if A is known to be equal to B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1304 #define known_eq(A, B) (!maybe_ne (A, B))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1305
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1306 /* Return true if A is known to be unequal to B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1307 #define known_ne(A, B) (!maybe_eq (A, B))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1308
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1309 /* Return true if A might be less than or equal to B for some
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1310 indeterminate values. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1311
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1312 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1313 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1314 maybe_le (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1315 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1316 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1317 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1318 if (a.coeffs[i] < b.coeffs[i])
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1319 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1320 return a.coeffs[0] <= b.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1321 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1322
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1323 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1324 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1325 maybe_le (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1326 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1327 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1328 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1329 if (a.coeffs[i] < 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1330 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1331 return a.coeffs[0] <= b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1332 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1333
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1334 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1335 inline typename if_nonpoly<Ca, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1336 maybe_le (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1337 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1338 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1339 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1340 if (b.coeffs[i] > 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1341 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1342 return a <= b.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1343 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1344
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1345 template<typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1346 inline typename if_nonpoly2<Ca, Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1347 maybe_le (const Ca &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1348 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1349 return a <= b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1350 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1351
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1352 /* Return true if A might be less than B for some indeterminate values. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1353
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1354 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1355 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1356 maybe_lt (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1357 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1358 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1359 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1360 if (a.coeffs[i] < b.coeffs[i])
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1361 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1362 return a.coeffs[0] < b.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1363 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1364
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1365 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1366 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1367 maybe_lt (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1368 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1369 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1370 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1371 if (a.coeffs[i] < 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1372 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1373 return a.coeffs[0] < b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1374 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1375
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1376 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1377 inline typename if_nonpoly<Ca, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1378 maybe_lt (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1379 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1380 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1381 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1382 if (b.coeffs[i] > 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1383 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1384 return a < b.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1385 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1386
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1387 template<typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1388 inline typename if_nonpoly2<Ca, Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1389 maybe_lt (const Ca &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1390 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1391 return a < b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1392 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1393
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1394 /* Return true if A may be greater than or equal to B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1395 #define maybe_ge(A, B) maybe_le (B, A)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1396
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1397 /* Return true if A may be greater than B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1398 #define maybe_gt(A, B) maybe_lt (B, A)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1399
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1400 /* Return true if A is known to be less than or equal to B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1401 #define known_le(A, B) (!maybe_gt (A, B))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1402
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1403 /* Return true if A is known to be less than B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1404 #define known_lt(A, B) (!maybe_ge (A, B))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1405
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1406 /* Return true if A is known to be greater than B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1407 #define known_gt(A, B) (!maybe_le (A, B))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1408
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1409 /* Return true if A is known to be greater than or equal to B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1410 #define known_ge(A, B) (!maybe_lt (A, B))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1411
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1412 /* Return true if A and B are ordered by the partial ordering known_le. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1413
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1414 template<typename T1, typename T2>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1415 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1416 ordered_p (const T1 &a, const T2 &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1417 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1418 return ((poly_int_traits<T1>::num_coeffs == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1419 && poly_int_traits<T2>::num_coeffs == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1420 || known_le (a, b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1421 || known_le (b, a));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1422 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1423
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1424 /* Assert that A and B are known to be ordered and return the minimum
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1425 of the two.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1426
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1427 NOTE: When using this function, please add a comment above the call
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1428 explaining why we know the values are ordered in that context. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1429
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1430 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1431 inline POLY_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1432 ordered_min (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1433 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1434 if (known_le (a, b))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1435 return a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1436 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1437 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1438 if (N > 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1439 gcc_checking_assert (known_le (b, a));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1440 return b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1441 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1442 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1443
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1444 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1445 inline CONST_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1446 ordered_min (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1447 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1448 if (known_le (a, b))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1449 return a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1450 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1451 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1452 if (N > 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1453 gcc_checking_assert (known_le (b, a));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1454 return b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1455 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1456 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1457
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1458 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1459 inline POLY_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1460 ordered_min (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1461 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1462 if (known_le (a, b))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1463 return a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1464 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1465 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1466 if (N > 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1467 gcc_checking_assert (known_le (b, a));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1468 return b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1469 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1470 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1471
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1472 /* Assert that A and B are known to be ordered and return the maximum
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1473 of the two.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1474
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1475 NOTE: When using this function, please add a comment above the call
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1476 explaining why we know the values are ordered in that context. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1477
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1478 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1479 inline POLY_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1480 ordered_max (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1481 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1482 if (known_le (a, b))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1483 return b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1484 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1485 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1486 if (N > 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1487 gcc_checking_assert (known_le (b, a));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1488 return a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1489 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1490 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1491
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1492 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1493 inline CONST_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1494 ordered_max (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1495 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1496 if (known_le (a, b))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1497 return b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1498 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1499 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1500 if (N > 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1501 gcc_checking_assert (known_le (b, a));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1502 return a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1503 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1504 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1505
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1506 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1507 inline POLY_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1508 ordered_max (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1509 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1510 if (known_le (a, b))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1511 return b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1512 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1513 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1514 if (N > 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1515 gcc_checking_assert (known_le (b, a));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1516 return a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1517 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1518 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1519
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1520 /* Return a constant lower bound on the value of A, which is known
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1521 to be nonnegative. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1522
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1523 template<unsigned int N, typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1524 inline Ca
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1525 constant_lower_bound (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1526 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1527 gcc_checking_assert (known_ge (a, POLY_INT_TYPE (Ca) (0)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1528 return a.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1529 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1530
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1531 /* Return the constant lower bound of A, given that it is no less than B. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1532
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1533 template<unsigned int N, typename Ca, typename Cb>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1534 inline POLY_CONST_COEFF (Ca, Cb)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1535 constant_lower_bound_with_limit (const poly_int_pod<N, Ca> &a, const Cb &b)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1536 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1537 if (known_ge (a, b))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1538 return a.coeffs[0];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1539 return b;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1540 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1541
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1542 /* Return the constant upper bound of A, given that it is no greater
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1543 than B. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1544
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1545 template<unsigned int N, typename Ca, typename Cb>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1546 inline POLY_CONST_COEFF (Ca, Cb)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1547 constant_upper_bound_with_limit (const poly_int_pod<N, Ca> &a, const Cb &b)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1548 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1549 if (known_le (a, b))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1550 return a.coeffs[0];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1551 return b;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1552 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1553
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1554 /* Return a value that is known to be no greater than A and B. This
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1555 will be the greatest lower bound for some indeterminate values but
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1556 not necessarily for all. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1557
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1558 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1559 inline POLY_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1560 lower_bound (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1561 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1562 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1563 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1564 typedef POLY_INT_TYPE (Cb) ICb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1565 typedef POLY_CONST_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1566
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1567 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1568 POLY_SET_COEFF (C, r, 0, MIN (NCa (a.coeffs[0]), NCb (b)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1569 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1570 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1571 POLY_SET_COEFF (C, r, i, MIN (NCa (a.coeffs[i]), ICb (0)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1572 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1573 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1574
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1575 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1576 inline CONST_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1577 lower_bound (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1578 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1579 return lower_bound (b, a);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1580 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1581
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1582 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1583 inline POLY_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1584 lower_bound (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1585 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1586 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1587 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1588 typedef POLY_POLY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1589
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1590 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1591 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1592 POLY_SET_COEFF (C, r, i, MIN (NCa (a.coeffs[i]), NCb (b.coeffs[i])));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1593 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1594 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1595
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1596 template<typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1597 inline CONST_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1598 lower_bound (const Ca &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1599 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1600 return a < b ? a : b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1601 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1602
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1603 /* Return a value that is known to be no less than A and B. This will
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1604 be the least upper bound for some indeterminate values but not
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1605 necessarily for all. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1606
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1607 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1608 inline POLY_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1609 upper_bound (const poly_int_pod<N, Ca> &a, const Cb &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1610 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1611 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1612 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1613 typedef POLY_INT_TYPE (Cb) ICb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1614 typedef POLY_CONST_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1615
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1616 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1617 POLY_SET_COEFF (C, r, 0, MAX (NCa (a.coeffs[0]), NCb (b)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1618 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1619 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1620 POLY_SET_COEFF (C, r, i, MAX (NCa (a.coeffs[i]), ICb (0)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1621 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1622 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1623
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1624 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1625 inline CONST_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1626 upper_bound (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1627 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1628 return upper_bound (b, a);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1629 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1630
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1631 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1632 inline POLY_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1633 upper_bound (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1634 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1635 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1636 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1637 typedef POLY_POLY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1638
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1639 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1640 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1641 POLY_SET_COEFF (C, r, i, MAX (NCa (a.coeffs[i]), NCb (b.coeffs[i])));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1642 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1643 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1644
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1645 /* Return the greatest common divisor of all nonzero coefficients, or zero
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1646 if all coefficients are zero. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1647
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1648 template<unsigned int N, typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1649 inline POLY_BINARY_COEFF (Ca, Ca)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1650 coeff_gcd (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1651 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1652 /* Find the first nonzero coefficient, stopping at 0 whatever happens. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1653 unsigned int i;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1654 for (i = N - 1; i > 0; --i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1655 if (a.coeffs[i] != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1656 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1657 typedef POLY_BINARY_COEFF (Ca, Ca) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1658 C r = a.coeffs[i];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1659 for (unsigned int j = 0; j < i; ++j)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1660 if (a.coeffs[j] != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1661 r = gcd (r, C (a.coeffs[j]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1662 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1663 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1664
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1665 /* Return a value that is a multiple of both A and B. This will be the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1666 least common multiple for some indeterminate values but necessarily
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1667 for all. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1668
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1669 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1670 POLY_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1671 common_multiple (const poly_int_pod<N, Ca> &a, Cb b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1672 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1673 POLY_BINARY_COEFF (Ca, Ca) xgcd = coeff_gcd (a);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1674 return a * (least_common_multiple (xgcd, b) / xgcd);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1675 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1676
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1677 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1678 inline CONST_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1679 common_multiple (const Ca &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1680 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1681 return common_multiple (b, a);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1682 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1683
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1684 /* Return a value that is a multiple of both A and B, asserting that
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1685 such a value exists. The result will be the least common multiple
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1686 for some indeterminate values but necessarily for all.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1687
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1688 NOTE: When using this function, please add a comment above the call
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1689 explaining why we know the values have a common multiple (which might
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1690 for example be because we know A / B is rational). */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1691
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1692 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1693 POLY_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1694 force_common_multiple (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1695 const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1696 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1697 if (b.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1698 return common_multiple (a, b.coeffs[0]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1699 if (a.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1700 return common_multiple (a.coeffs[0], b);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1701
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1702 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1703 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1704 typedef POLY_BINARY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1705 typedef POLY_INT_TYPE (Ca) ICa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1706
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1707 for (unsigned int i = 1; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1708 if (a.coeffs[i] != ICa (0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1709 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1710 C lcm = least_common_multiple (NCa (a.coeffs[i]), NCb (b.coeffs[i]));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1711 C amul = lcm / a.coeffs[i];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1712 C bmul = lcm / b.coeffs[i];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1713 for (unsigned int j = 0; j < N; ++j)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1714 gcc_checking_assert (a.coeffs[j] * amul == b.coeffs[j] * bmul);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1715 return a * amul;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1716 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1717 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1718 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1719
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1720 /* Compare A and B for sorting purposes, returning -1 if A should come
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1721 before B, 0 if A and B are identical, and 1 if A should come after B.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1722 This is a lexicographical compare of the coefficients in reverse order.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1723
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1724 A consequence of this is that all constant sizes come before all
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1725 non-constant ones, regardless of magnitude (since a size is never
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1726 negative). This is what most callers want. For example, when laying
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1727 data out on the stack, it's better to keep all the constant-sized
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1728 data together so that it can be accessed as a constant offset from a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1729 single base. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1730
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1731 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1732 inline int
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1733 compare_sizes_for_sort (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1734 const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1735 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1736 for (unsigned int i = N; i-- > 0; )
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1737 if (a.coeffs[i] != b.coeffs[i])
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1738 return a.coeffs[i] < b.coeffs[i] ? -1 : 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1739 return 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1740 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1741
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1742 /* Return true if we can calculate VALUE & (ALIGN - 1) at compile time. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1743
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1744 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1745 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1746 can_align_p (const poly_int_pod<N, Ca> &value, Cb align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1747 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1748 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1749 if ((value.coeffs[i] & (align - 1)) != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1750 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1751 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1752 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1753
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1754 /* Return true if we can align VALUE up to the smallest multiple of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1755 ALIGN that is >= VALUE. Store the aligned value in *ALIGNED if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1756
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1757 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1758 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1759 can_align_up (const poly_int_pod<N, Ca> &value, Cb align,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1760 poly_int_pod<N, Ca> *aligned)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1761 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1762 if (!can_align_p (value, align))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1763 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1764 *aligned = value + (-value.coeffs[0] & (align - 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1765 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1766 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1767
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1768 /* Return true if we can align VALUE down to the largest multiple of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1769 ALIGN that is <= VALUE. Store the aligned value in *ALIGNED if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1770
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1771 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1772 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1773 can_align_down (const poly_int_pod<N, Ca> &value, Cb align,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1774 poly_int_pod<N, Ca> *aligned)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1775 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1776 if (!can_align_p (value, align))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1777 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1778 *aligned = value - (value.coeffs[0] & (align - 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1779 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1780 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1781
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1782 /* Return true if we can align A and B up to the smallest multiples of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1783 ALIGN that are >= A and B respectively, and if doing so gives the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1784 same value. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1785
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1786 template<unsigned int N, typename Ca, typename Cb, typename Cc>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1787 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1788 known_equal_after_align_up (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1789 const poly_int_pod<N, Cb> &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1790 Cc align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1791 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1792 poly_int<N, Ca> aligned_a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1793 poly_int<N, Cb> aligned_b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1794 return (can_align_up (a, align, &aligned_a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1795 && can_align_up (b, align, &aligned_b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1796 && known_eq (aligned_a, aligned_b));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1797 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1798
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1799 /* Return true if we can align A and B down to the largest multiples of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1800 ALIGN that are <= A and B respectively, and if doing so gives the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1801 same value. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1802
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1803 template<unsigned int N, typename Ca, typename Cb, typename Cc>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1804 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1805 known_equal_after_align_down (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1806 const poly_int_pod<N, Cb> &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1807 Cc align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1808 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1809 poly_int<N, Ca> aligned_a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1810 poly_int<N, Cb> aligned_b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1811 return (can_align_down (a, align, &aligned_a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1812 && can_align_down (b, align, &aligned_b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1813 && known_eq (aligned_a, aligned_b));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1814 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1815
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1816 /* Assert that we can align VALUE to ALIGN at compile time and return
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1817 the smallest multiple of ALIGN that is >= VALUE.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1818
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1819 NOTE: When using this function, please add a comment above the call
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1820 explaining why we know the non-constant coefficients must already
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1821 be a multiple of ALIGN. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1822
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1823 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1824 inline poly_int<N, Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1825 force_align_up (const poly_int_pod<N, Ca> &value, Cb align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1826 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1827 gcc_checking_assert (can_align_p (value, align));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1828 return value + (-value.coeffs[0] & (align - 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1829 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1830
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1831 /* Assert that we can align VALUE to ALIGN at compile time and return
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1832 the largest multiple of ALIGN that is <= VALUE.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1833
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1834 NOTE: When using this function, please add a comment above the call
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1835 explaining why we know the non-constant coefficients must already
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1836 be a multiple of ALIGN. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1837
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1838 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1839 inline poly_int<N, Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1840 force_align_down (const poly_int_pod<N, Ca> &value, Cb align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1841 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1842 gcc_checking_assert (can_align_p (value, align));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1843 return value - (value.coeffs[0] & (align - 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1844 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1845
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1846 /* Return a value <= VALUE that is a multiple of ALIGN. It will be the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1847 greatest such value for some indeterminate values but not necessarily
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1848 for all. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1849
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1850 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1851 inline poly_int<N, Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1852 aligned_lower_bound (const poly_int_pod<N, Ca> &value, Cb align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1853 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1854 poly_int<N, Ca> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1855 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1856 /* This form copes correctly with more type combinations than
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1857 value.coeffs[i] & -align would. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1858 POLY_SET_COEFF (Ca, r, i, (value.coeffs[i]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1859 - (value.coeffs[i] & (align - 1))));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1860 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1861 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1862
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1863 /* Return a value >= VALUE that is a multiple of ALIGN. It will be the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1864 least such value for some indeterminate values but not necessarily
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1865 for all. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1866
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1867 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1868 inline poly_int<N, Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1869 aligned_upper_bound (const poly_int_pod<N, Ca> &value, Cb align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1870 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1871 poly_int<N, Ca> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1872 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1873 POLY_SET_COEFF (Ca, r, i, (value.coeffs[i]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1874 + (-value.coeffs[i] & (align - 1))));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1875 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1876 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1877
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1878 /* Assert that we can align VALUE to ALIGN at compile time. Align VALUE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1879 down to the largest multiple of ALIGN that is <= VALUE, then divide by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1880 ALIGN.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1881
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1882 NOTE: When using this function, please add a comment above the call
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1883 explaining why we know the non-constant coefficients must already
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1884 be a multiple of ALIGN. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1885
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1886 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1887 inline poly_int<N, Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1888 force_align_down_and_div (const poly_int_pod<N, Ca> &value, Cb align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1889 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1890 gcc_checking_assert (can_align_p (value, align));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1891
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1892 poly_int<N, Ca> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1893 POLY_SET_COEFF (Ca, r, 0, ((value.coeffs[0]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1894 - (value.coeffs[0] & (align - 1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1895 / align));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1896 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1897 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1898 POLY_SET_COEFF (Ca, r, i, value.coeffs[i] / align);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1899 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1900 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1901
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1902 /* Assert that we can align VALUE to ALIGN at compile time. Align VALUE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1903 up to the smallest multiple of ALIGN that is >= VALUE, then divide by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1904 ALIGN.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1905
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1906 NOTE: When using this function, please add a comment above the call
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1907 explaining why we know the non-constant coefficients must already
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1908 be a multiple of ALIGN. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1909
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1910 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1911 inline poly_int<N, Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1912 force_align_up_and_div (const poly_int_pod<N, Ca> &value, Cb align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1913 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1914 gcc_checking_assert (can_align_p (value, align));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1915
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1916 poly_int<N, Ca> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1917 POLY_SET_COEFF (Ca, r, 0, ((value.coeffs[0]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1918 + (-value.coeffs[0] & (align - 1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1919 / align));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1920 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1921 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1922 POLY_SET_COEFF (Ca, r, i, value.coeffs[i] / align);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1923 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1924 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1925
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1926 /* Return true if we know at compile time the difference between VALUE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1927 and the equal or preceding multiple of ALIGN. Store the value in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1928 *MISALIGN if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1929
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1930 template<unsigned int N, typename Ca, typename Cb, typename Cm>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1931 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1932 known_misalignment (const poly_int_pod<N, Ca> &value, Cb align, Cm *misalign)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1933 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1934 gcc_checking_assert (align != 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1935 if (!can_align_p (value, align))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1936 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1937 *misalign = value.coeffs[0] & (align - 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1938 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1939 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1940
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1941 /* Return X & (Y - 1), asserting that this value is known. Please add
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1942 an a comment above callers to this function to explain why the condition
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1943 is known to hold. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1944
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1945 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1946 inline POLY_BINARY_COEFF (Ca, Ca)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1947 force_get_misalignment (const poly_int_pod<N, Ca> &a, Cb align)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1948 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1949 gcc_checking_assert (can_align_p (a, align));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1950 return a.coeffs[0] & (align - 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1951 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1952
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1953 /* Return the maximum alignment that A is known to have. Return 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1954 if A is known to be zero. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1955
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1956 template<unsigned int N, typename Ca>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1957 inline POLY_BINARY_COEFF (Ca, Ca)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1958 known_alignment (const poly_int_pod<N, Ca> &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1959 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1960 typedef POLY_BINARY_COEFF (Ca, Ca) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1961 C r = a.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1962 for (unsigned int i = 1; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1963 r |= a.coeffs[i];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1964 return r & -r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1965 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1966
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1967 /* Return true if we can compute A | B at compile time, storing the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1968 result in RES if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1969
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1970 template<unsigned int N, typename Ca, typename Cb, typename Cr>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1971 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1972 can_ior_p (const poly_int_pod<N, Ca> &a, Cb b, Cr *result)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1973 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1974 /* Coefficients 1 and above must be a multiple of something greater
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1975 than B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1976 typedef POLY_INT_TYPE (Ca) int_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1977 if (N >= 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1978 for (unsigned int i = 1; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1979 if ((-(a.coeffs[i] & -a.coeffs[i]) & b) != int_type (0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1980 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1981 *result = a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1982 result->coeffs[0] |= b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1983 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1984 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1985
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1986 /* Return true if A is a constant multiple of B, storing the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1987 multiple in *MULTIPLE if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1988
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1989 template<unsigned int N, typename Ca, typename Cb, typename Cm>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1990 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1991 constant_multiple_p (const poly_int_pod<N, Ca> &a, Cb b, Cm *multiple)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1992 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1993 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1994 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1995
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1996 /* Do the modulus before the constant check, to catch divide by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1997 zero errors. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1998 if (NCa (a.coeffs[0]) % NCb (b) != 0 || !a.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1999 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2000 *multiple = NCa (a.coeffs[0]) / NCb (b);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2001 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2002 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2003
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2004 template<unsigned int N, typename Ca, typename Cb, typename Cm>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2005 inline typename if_nonpoly<Ca, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2006 constant_multiple_p (Ca a, const poly_int_pod<N, Cb> &b, Cm *multiple)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2007 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2008 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2009 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2010 typedef POLY_INT_TYPE (Ca) int_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2011
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2012 /* Do the modulus before the constant check, to catch divide by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2013 zero errors. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2014 if (NCa (a) % NCb (b.coeffs[0]) != 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2015 || (a != int_type (0) && !b.is_constant ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2016 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2017 *multiple = NCa (a) / NCb (b.coeffs[0]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2018 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2019 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2020
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2021 template<unsigned int N, typename Ca, typename Cb, typename Cm>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2022 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2023 constant_multiple_p (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2024 const poly_int_pod<N, Cb> &b, Cm *multiple)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2025 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2026 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2027 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2028 typedef POLY_INT_TYPE (Ca) ICa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2029 typedef POLY_INT_TYPE (Cb) ICb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2030 typedef POLY_BINARY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2031
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2032 if (NCa (a.coeffs[0]) % NCb (b.coeffs[0]) != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2033 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2034
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2035 C r = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2036 for (unsigned int i = 1; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2037 if (b.coeffs[i] == ICb (0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2038 ? a.coeffs[i] != ICa (0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2039 : (NCa (a.coeffs[i]) % NCb (b.coeffs[i]) != 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2040 || NCa (a.coeffs[i]) / NCb (b.coeffs[i]) != r))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2041 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2042
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2043 *multiple = r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2044 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2045 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2046
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2047 /* Return true if A is a multiple of B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2048
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2049 template<typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2050 inline typename if_nonpoly2<Ca, Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2051 multiple_p (Ca a, Cb b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2052 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2053 return a % b == 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2054 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2055
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2056 /* Return true if A is a (polynomial) multiple of B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2057
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2058 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2059 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2060 multiple_p (const poly_int_pod<N, Ca> &a, Cb b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2061 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2062 for (unsigned int i = 0; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2063 if (a.coeffs[i] % b != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2064 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2065 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2066 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2067
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2068 /* Return true if A is a (constant) multiple of B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2069
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2070 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2071 inline typename if_nonpoly<Ca, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2072 multiple_p (Ca a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2073 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2074 typedef POLY_INT_TYPE (Ca) int_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2075
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2076 /* Do the modulus before the constant check, to catch divide by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2077 potential zeros. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2078 return a % b.coeffs[0] == 0 && (a == int_type (0) || b.is_constant ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2079 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2080
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2081 /* Return true if A is a (polynomial) multiple of B. This handles cases
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2082 where either B is constant or the multiple is constant. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2083
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2084 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2085 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2086 multiple_p (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2087 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2088 if (b.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2089 return multiple_p (a, b.coeffs[0]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2090 POLY_BINARY_COEFF (Ca, Ca) tmp;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2091 return constant_multiple_p (a, b, &tmp);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2092 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2093
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2094 /* Return true if A is a (constant) multiple of B, storing the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2095 multiple in *MULTIPLE if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2096
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2097 template<typename Ca, typename Cb, typename Cm>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2098 inline typename if_nonpoly2<Ca, Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2099 multiple_p (Ca a, Cb b, Cm *multiple)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2100 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2101 if (a % b != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2102 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2103 *multiple = a / b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2104 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2105 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2106
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2107 /* Return true if A is a (polynomial) multiple of B, storing the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2108 multiple in *MULTIPLE if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2109
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2110 template<unsigned int N, typename Ca, typename Cb, typename Cm>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2111 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2112 multiple_p (const poly_int_pod<N, Ca> &a, Cb b, poly_int_pod<N, Cm> *multiple)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2113 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2114 if (!multiple_p (a, b))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2115 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2116 for (unsigned int i = 0; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2117 multiple->coeffs[i] = a.coeffs[i] / b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2118 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2119 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2120
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2121 /* Return true if B is a constant and A is a (constant) multiple of B,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2122 storing the multiple in *MULTIPLE if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2123
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2124 template<unsigned int N, typename Ca, typename Cb, typename Cm>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2125 inline typename if_nonpoly<Ca, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2126 multiple_p (Ca a, const poly_int_pod<N, Cb> &b, Cm *multiple)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2127 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2128 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2129
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2130 /* Do the modulus before the constant check, to catch divide by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2131 potential zeros. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2132 if (a % b.coeffs[0] != 0 || (NCa (a) != 0 && !b.is_constant ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2133 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2134 *multiple = a / b.coeffs[0];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2135 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2136 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2137
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2138 /* Return true if A is a (polynomial) multiple of B, storing the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2139 multiple in *MULTIPLE if so. This handles cases where either
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2140 B is constant or the multiple is constant. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2141
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2142 template<unsigned int N, typename Ca, typename Cb, typename Cm>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2143 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2144 multiple_p (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2145 poly_int_pod<N, Cm> *multiple)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2146 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2147 if (b.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2148 return multiple_p (a, b.coeffs[0], multiple);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2149 return constant_multiple_p (a, b, multiple);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2150 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2151
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2152 /* Return A / B, given that A is known to be a multiple of B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2153
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2154 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2155 inline POLY_CONST_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2156 exact_div (const poly_int_pod<N, Ca> &a, Cb b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2157 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2158 typedef POLY_CONST_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2159 poly_int<N, C> r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2160 for (unsigned int i = 0; i < N; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2161 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2162 gcc_checking_assert (a.coeffs[i] % b == 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2163 POLY_SET_COEFF (C, r, i, a.coeffs[i] / b);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2164 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2165 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2166 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2167
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2168 /* Return A / B, given that A is known to be a multiple of B. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2169
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2170 template<unsigned int N, typename Ca, typename Cb>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2171 inline POLY_POLY_RESULT (N, Ca, Cb)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2172 exact_div (const poly_int_pod<N, Ca> &a, const poly_int_pod<N, Cb> &b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2173 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2174 if (b.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2175 return exact_div (a, b.coeffs[0]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2176
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2177 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2178 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2179 typedef POLY_BINARY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2180 typedef POLY_INT_TYPE (Cb) int_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2181
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2182 gcc_checking_assert (a.coeffs[0] % b.coeffs[0] == 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2183 C r = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2184 for (unsigned int i = 1; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2185 gcc_checking_assert (b.coeffs[i] == int_type (0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2186 ? a.coeffs[i] == int_type (0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2187 : (a.coeffs[i] % b.coeffs[i] == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2188 && NCa (a.coeffs[i]) / NCb (b.coeffs[i]) == r));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2189
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2190 return r;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2191 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2192
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2193 /* Return true if there is some constant Q and polynomial r such that:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2194
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2195 (1) a = b * Q + r
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2196 (2) |b * Q| <= |a|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2197 (3) |r| < |b|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2198
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2199 Store the value Q in *QUOTIENT if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2200
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2201 template<unsigned int N, typename Ca, typename Cb, typename Cq>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2202 inline typename if_nonpoly2<Cb, Cq, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2203 can_div_trunc_p (const poly_int_pod<N, Ca> &a, Cb b, Cq *quotient)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2204 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2205 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2206 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2207
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2208 /* Do the division before the constant check, to catch divide by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2209 zero errors. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2210 Cq q = NCa (a.coeffs[0]) / NCb (b);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2211 if (!a.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2212 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2213 *quotient = q;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2214 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2215 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2216
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2217 template<unsigned int N, typename Ca, typename Cb, typename Cq>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2218 inline typename if_nonpoly<Cq, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2219 can_div_trunc_p (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2220 const poly_int_pod<N, Cb> &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2221 Cq *quotient)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2222 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2223 /* We can calculate Q from the case in which the indeterminates
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2224 are zero. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2225 typedef POLY_CAST (Ca, Cb) NCa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2226 typedef POLY_CAST (Cb, Ca) NCb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2227 typedef POLY_INT_TYPE (Ca) ICa;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2228 typedef POLY_INT_TYPE (Cb) ICb;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2229 typedef POLY_BINARY_COEFF (Ca, Cb) C;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2230 C q = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2231
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2232 /* Check the other coefficients and record whether the division is exact.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2233 The only difficult case is when it isn't. If we require a and b to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2234 ordered wrt zero, there can be no two coefficients of the same value
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2235 that have opposite signs. This means that:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2236
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2237 |a| = |a0| + |a1 * x1| + |a2 * x2| + ...
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2238 |b| = |b0| + |b1 * x1| + |b2 * x2| + ...
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2239
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2240 The Q we've just calculated guarantees:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2241
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2242 |b0 * Q| <= |a0|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2243 |a0 - b0 * Q| < |b0|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2244
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2245 and so:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2246
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2247 (2) |b * Q| <= |a|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2248
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2249 is satisfied if:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2250
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2251 |bi * xi * Q| <= |ai * xi|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2252
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2253 for each i in [1, N]. This is trivially true when xi is zero.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2254 When it isn't we need:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2255
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2256 (2') |bi * Q| <= |ai|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2257
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2258 r is calculated as:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2259
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2260 r = r0 + r1 * x1 + r2 * x2 + ...
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2261 where ri = ai - bi * Q
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2262
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2263 Restricting to ordered a and b also guarantees that no two ris
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2264 have opposite signs, so we have:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2265
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2266 |r| = |r0| + |r1 * x1| + |r2 * x2| + ...
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2267
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2268 We know from the calculation of Q that |r0| < |b0|, so:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2269
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2270 (3) |r| < |b|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2271
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2272 is satisfied if:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2273
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2274 (3') |ai - bi * Q| <= |bi|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2275
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2276 for each i in [1, N]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2277 bool rem_p = NCa (a.coeffs[0]) % NCb (b.coeffs[0]) != 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2278 for (unsigned int i = 1; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2279 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2280 if (b.coeffs[i] == ICb (0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2281 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2282 /* For bi == 0 we simply need: (3') |ai| == 0. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2283 if (a.coeffs[i] != ICa (0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2284 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2285 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2286 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2287 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2288 if (q == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2289 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2290 /* For Q == 0 we simply need: (3') |ai| <= |bi|. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2291 if (a.coeffs[i] != ICa (0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2292 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2293 /* Use negative absolute to avoid overflow, i.e.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2294 -|ai| >= -|bi|. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2295 C neg_abs_a = (a.coeffs[i] < 0 ? a.coeffs[i] : -a.coeffs[i]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2296 C neg_abs_b = (b.coeffs[i] < 0 ? b.coeffs[i] : -b.coeffs[i]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2297 if (neg_abs_a < neg_abs_b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2298 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2299 rem_p = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2300 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2301 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2302 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2303 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2304 /* Otherwise just check for the case in which ai / bi == Q. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2305 if (NCa (a.coeffs[i]) / NCb (b.coeffs[i]) != q)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2306 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2307 if (NCa (a.coeffs[i]) % NCb (b.coeffs[i]) != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2308 rem_p = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2309 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2310 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2311 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2312
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2313 /* If the division isn't exact, require both values to be ordered wrt 0,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2314 so that we can guarantee conditions (2) and (3) for all indeterminate
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2315 values. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2316 if (rem_p && (!ordered_p (a, ICa (0)) || !ordered_p (b, ICb (0))))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2317 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2318
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2319 *quotient = q;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2320 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2321 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2322
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2323 /* Likewise, but also store r in *REMAINDER. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2324
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2325 template<unsigned int N, typename Ca, typename Cb, typename Cq, typename Cr>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2326 inline typename if_nonpoly<Cq, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2327 can_div_trunc_p (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2328 const poly_int_pod<N, Cb> &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2329 Cq *quotient, Cr *remainder)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2330 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2331 if (!can_div_trunc_p (a, b, quotient))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2332 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2333 *remainder = a - *quotient * b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2334 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2335 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2336
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2337 /* Return true if there is some polynomial q and constant R such that:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2338
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2339 (1) a = B * q + R
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2340 (2) |B * q| <= |a|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2341 (3) |R| < |B|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2342
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2343 Store the value q in *QUOTIENT if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2344
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2345 template<unsigned int N, typename Ca, typename Cb, typename Cq>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2346 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2347 can_div_trunc_p (const poly_int_pod<N, Ca> &a, Cb b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2348 poly_int_pod<N, Cq> *quotient)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2349 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2350 /* The remainder must be constant. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2351 for (unsigned int i = 1; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2352 if (a.coeffs[i] % b != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2353 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2354 for (unsigned int i = 0; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2355 quotient->coeffs[i] = a.coeffs[i] / b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2356 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2357 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2358
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2359 /* Likewise, but also store R in *REMAINDER. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2360
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2361 template<unsigned int N, typename Ca, typename Cb, typename Cq, typename Cr>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2362 inline typename if_nonpoly<Cb, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2363 can_div_trunc_p (const poly_int_pod<N, Ca> &a, Cb b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2364 poly_int_pod<N, Cq> *quotient, Cr *remainder)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2365 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2366 if (!can_div_trunc_p (a, b, quotient))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2367 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2368 *remainder = a.coeffs[0] % b;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2369 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2370 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2371
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2372 /* Return true if we can compute A / B at compile time, rounding towards zero.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2373 Store the result in QUOTIENT if so.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2374
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2375 This handles cases in which either B is constant or the result is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2376 constant. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2377
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2378 template<unsigned int N, typename Ca, typename Cb, typename Cq>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2379 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2380 can_div_trunc_p (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2381 const poly_int_pod<N, Cb> &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2382 poly_int_pod<N, Cq> *quotient)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2383 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2384 if (b.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2385 return can_div_trunc_p (a, b.coeffs[0], quotient);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2386 if (!can_div_trunc_p (a, b, &quotient->coeffs[0]))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2387 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2388 for (unsigned int i = 1; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2389 quotient->coeffs[i] = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2390 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2391 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2392
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2393 /* Return true if there is some constant Q and polynomial r such that:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2394
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2395 (1) a = b * Q + r
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2396 (2) |a| <= |b * Q|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2397 (3) |r| < |b|
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2398
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2399 Store the value Q in *QUOTIENT if so. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2400
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2401 template<unsigned int N, typename Ca, typename Cb, typename Cq>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2402 inline typename if_nonpoly<Cq, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2403 can_div_away_from_zero_p (const poly_int_pod<N, Ca> &a,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2404 const poly_int_pod<N, Cb> &b,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2405 Cq *quotient)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2406 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2407 if (!can_div_trunc_p (a, b, quotient))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2408 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2409 if (maybe_ne (*quotient * b, a))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2410 *quotient += (*quotient < 0 ? -1 : 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2411 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2412 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2413
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2414 /* Use print_dec to print VALUE to FILE, where SGN is the sign
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2415 of the values. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2416
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2417 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2418 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2419 print_dec (const poly_int_pod<N, C> &value, FILE *file, signop sgn)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2420 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2421 if (value.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2422 print_dec (value.coeffs[0], file, sgn);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2423 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2424 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2425 fprintf (file, "[");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2426 for (unsigned int i = 0; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2427 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2428 print_dec (value.coeffs[i], file, sgn);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2429 fputc (i == N - 1 ? ']' : ',', file);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2430 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2431 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2432 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2433
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2434 /* Likewise without the signop argument, for coefficients that have an
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2435 inherent signedness. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2436
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2437 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2438 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2439 print_dec (const poly_int_pod<N, C> &value, FILE *file)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2440 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2441 STATIC_ASSERT (poly_coeff_traits<C>::signedness >= 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2442 print_dec (value, file,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2443 poly_coeff_traits<C>::signedness ? SIGNED : UNSIGNED);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2444 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2445
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2446 /* Use print_hex to print VALUE to FILE. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2447
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2448 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2449 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2450 print_hex (const poly_int_pod<N, C> &value, FILE *file)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2451 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2452 if (value.is_constant ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2453 print_hex (value.coeffs[0], file);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2454 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2455 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2456 fprintf (file, "[");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2457 for (unsigned int i = 0; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2458 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2459 print_hex (value.coeffs[i], file);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2460 fputc (i == N - 1 ? ']' : ',', file);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2461 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2462 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2463 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2464
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2465 /* Helper for calculating the distance between two points P1 and P2,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2466 in cases where known_le (P1, P2). T1 and T2 are the types of the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2467 two positions, in either order. The coefficients of P2 - P1 have
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2468 type unsigned HOST_WIDE_INT if the coefficients of both T1 and T2
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2469 have C++ primitive type, otherwise P2 - P1 has its usual
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2470 wide-int-based type.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2471
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2472 The actual subtraction should look something like this:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2473
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2474 typedef poly_span_traits<T1, T2> span_traits;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2475 span_traits::cast (P2) - span_traits::cast (P1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2476
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2477 Applying the cast before the subtraction avoids undefined overflow
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2478 for signed T1 and T2.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2479
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2480 The implementation of the cast tries to avoid unnecessary arithmetic
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2481 or copying. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2482 template<typename T1, typename T2,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2483 typename Res = POLY_BINARY_COEFF (POLY_BINARY_COEFF (T1, T2),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2484 unsigned HOST_WIDE_INT)>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2485 struct poly_span_traits
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2486 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2487 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2488 static const T &cast (const T &x) { return x; }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2489 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2490
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2491 template<typename T1, typename T2>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2492 struct poly_span_traits<T1, T2, unsigned HOST_WIDE_INT>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2493 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2494 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2495 static typename if_nonpoly<T, unsigned HOST_WIDE_INT>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2496 cast (const T &x) { return x; }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2497
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2498 template<unsigned int N, typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2499 static poly_int<N, unsigned HOST_WIDE_INT>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2500 cast (const poly_int_pod<N, T> &x) { return x; }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2501 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2502
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2503 /* Return true if SIZE represents a known size, assuming that all-ones
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2504 indicates an unknown size. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2505
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2506 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2507 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2508 known_size_p (const T &a)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2509 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2510 return maybe_ne (a, POLY_INT_TYPE (T) (-1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2511 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2512
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2513 /* Return true if range [POS, POS + SIZE) might include VAL.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2514 SIZE can be the special value -1, in which case the range is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2515 open-ended. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2516
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2517 template<typename T1, typename T2, typename T3>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2518 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2519 maybe_in_range_p (const T1 &val, const T2 &pos, const T3 &size)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2520 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2521 typedef poly_span_traits<T1, T2> start_span;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2522 typedef poly_span_traits<T3, T3> size_span;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2523 if (known_lt (val, pos))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2524 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2525 if (!known_size_p (size))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2526 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2527 if ((poly_int_traits<T1>::num_coeffs > 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2528 || poly_int_traits<T2>::num_coeffs > 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2529 && maybe_lt (val, pos))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2530 /* In this case we don't know whether VAL >= POS is true at compile
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2531 time, so we can't prove that VAL >= POS + SIZE. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2532 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2533 return maybe_lt (start_span::cast (val) - start_span::cast (pos),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2534 size_span::cast (size));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2535 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2536
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2537 /* Return true if range [POS, POS + SIZE) is known to include VAL.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2538 SIZE can be the special value -1, in which case the range is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2539 open-ended. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2540
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2541 template<typename T1, typename T2, typename T3>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2542 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2543 known_in_range_p (const T1 &val, const T2 &pos, const T3 &size)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2544 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2545 typedef poly_span_traits<T1, T2> start_span;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2546 typedef poly_span_traits<T3, T3> size_span;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2547 return (known_size_p (size)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2548 && known_ge (val, pos)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2549 && known_lt (start_span::cast (val) - start_span::cast (pos),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2550 size_span::cast (size)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2551 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2552
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2553 /* Return true if the two ranges [POS1, POS1 + SIZE1) and [POS2, POS2 + SIZE2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2554 might overlap. SIZE1 and/or SIZE2 can be the special value -1, in which
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2555 case the range is open-ended. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2556
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2557 template<typename T1, typename T2, typename T3, typename T4>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2558 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2559 ranges_maybe_overlap_p (const T1 &pos1, const T2 &size1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2560 const T3 &pos2, const T4 &size2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2561 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2562 if (maybe_in_range_p (pos2, pos1, size1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2563 return maybe_ne (size2, POLY_INT_TYPE (T4) (0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2564 if (maybe_in_range_p (pos1, pos2, size2))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2565 return maybe_ne (size1, POLY_INT_TYPE (T2) (0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2566 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2567 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2568
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2569 /* Return true if the two ranges [POS1, POS1 + SIZE1) and [POS2, POS2 + SIZE2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2570 are known to overlap. SIZE1 and/or SIZE2 can be the special value -1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2571 in which case the range is open-ended. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2572
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2573 template<typename T1, typename T2, typename T3, typename T4>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2574 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2575 ranges_known_overlap_p (const T1 &pos1, const T2 &size1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2576 const T3 &pos2, const T4 &size2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2577 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2578 typedef poly_span_traits<T1, T3> start_span;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2579 typedef poly_span_traits<T2, T2> size1_span;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2580 typedef poly_span_traits<T4, T4> size2_span;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2581 /* known_gt (POS1 + SIZE1, POS2) [infinite precision]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2582 --> known_gt (SIZE1, POS2 - POS1) [infinite precision]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2583 --> known_gt (SIZE1, POS2 - lower_bound (POS1, POS2)) [infinite precision]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2584 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ always nonnegative
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2585 --> known_gt (SIZE1, span1::cast (POS2 - lower_bound (POS1, POS2))).
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2586
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2587 Using the saturating subtraction enforces that SIZE1 must be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2588 nonzero, since known_gt (0, x) is false for all nonnegative x.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2589 If POS2.coeff[I] < POS1.coeff[I] for some I > 0, increasing
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2590 indeterminate number I makes the unsaturated condition easier to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2591 satisfy, so using a saturated coefficient of zero tests the case in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2592 which the indeterminate is zero (the minimum value). */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2593 return (known_size_p (size1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2594 && known_size_p (size2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2595 && known_lt (start_span::cast (pos2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2596 - start_span::cast (lower_bound (pos1, pos2)),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2597 size1_span::cast (size1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2598 && known_lt (start_span::cast (pos1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2599 - start_span::cast (lower_bound (pos1, pos2)),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2600 size2_span::cast (size2)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2601 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2602
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2603 /* Return true if range [POS1, POS1 + SIZE1) is known to be a subrange of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2604 [POS2, POS2 + SIZE2). SIZE1 and/or SIZE2 can be the special value -1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2605 in which case the range is open-ended. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2606
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2607 template<typename T1, typename T2, typename T3, typename T4>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2608 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2609 known_subrange_p (const T1 &pos1, const T2 &size1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2610 const T3 &pos2, const T4 &size2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2611 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2612 typedef typename poly_int_traits<T2>::coeff_type C2;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2613 typedef poly_span_traits<T1, T3> start_span;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2614 typedef poly_span_traits<T2, T4> size_span;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2615 return (known_gt (size1, POLY_INT_TYPE (T2) (0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2616 && (poly_coeff_traits<C2>::signedness > 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2617 || known_size_p (size1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2618 && known_size_p (size2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2619 && known_ge (pos1, pos2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2620 && known_le (size1, size2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2621 && known_le (start_span::cast (pos1) - start_span::cast (pos2),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2622 size_span::cast (size2) - size_span::cast (size1)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2623 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2624
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2625 /* Return true if the endpoint of the range [POS, POS + SIZE) can be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2626 stored in a T, or if SIZE is the special value -1, which makes the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2627 range open-ended. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2628
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2629 template<typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2630 inline typename if_nonpoly<T, bool>::type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2631 endpoint_representable_p (const T &pos, const T &size)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2632 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2633 return (!known_size_p (size)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2634 || pos <= poly_coeff_traits<T>::max_value - size);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2635 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2636
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2637 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2638 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2639 endpoint_representable_p (const poly_int_pod<N, C> &pos,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2640 const poly_int_pod<N, C> &size)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2641 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2642 if (known_size_p (size))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2643 for (unsigned int i = 0; i < N; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2644 if (pos.coeffs[i] > poly_coeff_traits<C>::max_value - size.coeffs[i])
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2645 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2646 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2647 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2648
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2649 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2650 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2651 gt_ggc_mx (poly_int_pod<N, C> *)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2652 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2653 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2654
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2655 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2656 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2657 gt_pch_nx (poly_int_pod<N, C> *)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2658 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2659 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2660
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2661 template<unsigned int N, typename C>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2662 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2663 gt_pch_nx (poly_int_pod<N, C> *, void (*) (void *, void *), void *)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2664 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2665 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2666
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2667 #undef POLY_SET_COEFF
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2668 #undef POLY_INT_TYPE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2669 #undef POLY_BINARY_COEFF
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2670 #undef CONST_CONST_RESULT
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2671 #undef POLY_CONST_RESULT
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2672 #undef CONST_POLY_RESULT
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2673 #undef POLY_POLY_RESULT
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2674 #undef POLY_CONST_COEFF
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2675 #undef CONST_POLY_COEFF
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2676 #undef POLY_POLY_COEFF
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2677
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2678 #endif