1 /* Determinate class implementation: inline functions.
2    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3    Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #ifndef PPL_Determinate_inlines_hh
25 #define PPL_Determinate_inlines_hh 1
26 
27 #include "assertions.hh"
28 
29 namespace Parma_Polyhedra_Library {
30 
31 template <typename PSET>
32 inline
Rep(dimension_type num_dimensions,Degenerate_Element kind)33 Determinate<PSET>::Rep::Rep(dimension_type num_dimensions,
34                           Degenerate_Element kind)
35   : references(0), pset(num_dimensions, kind) {
36 }
37 
38 template <typename PSET>
39 inline
Rep(const PSET & p)40 Determinate<PSET>::Rep::Rep(const PSET& p)
41   : references(0), pset(p) {
42 }
43 
44 template <typename PSET>
45 inline
Rep(const Constraint_System & cs)46 Determinate<PSET>::Rep::Rep(const Constraint_System& cs)
47   : references(0), pset(cs) {
48 }
49 
50 template <typename PSET>
51 inline
Rep(const Congruence_System & cgs)52 Determinate<PSET>::Rep::Rep(const Congruence_System& cgs)
53   : references(0), pset(cgs) {
54 }
55 
56 template <typename PSET>
57 inline
~Rep()58 Determinate<PSET>::Rep::~Rep() {
59   PPL_ASSERT(references == 0);
60 }
61 
62 template <typename PSET>
63 inline void
new_reference() const64 Determinate<PSET>::Rep::new_reference() const {
65   ++references;
66 }
67 
68 template <typename PSET>
69 inline bool
del_reference() const70 Determinate<PSET>::Rep::del_reference() const {
71   return --references == 0;
72 }
73 
74 template <typename PSET>
75 inline bool
is_shared() const76 Determinate<PSET>::Rep::is_shared() const {
77   return references > 1;
78 }
79 
80 template <typename PSET>
81 inline memory_size_type
external_memory_in_bytes() const82 Determinate<PSET>::Rep::external_memory_in_bytes() const {
83   return pset.external_memory_in_bytes();
84 }
85 
86 template <typename PSET>
87 inline memory_size_type
total_memory_in_bytes() const88 Determinate<PSET>::Rep::total_memory_in_bytes() const {
89   return sizeof(*this) + external_memory_in_bytes();
90 }
91 
92 template <typename PSET>
93 inline
Determinate(const PSET & pset)94 Determinate<PSET>::Determinate(const PSET& pset)
95   : prep(new Rep(pset)) {
96   prep->new_reference();
97 }
98 
99 template <typename PSET>
100 inline
Determinate(const Constraint_System & cs)101 Determinate<PSET>::Determinate(const Constraint_System& cs)
102   : prep(new Rep(cs)) {
103   prep->new_reference();
104 }
105 
106 template <typename PSET>
107 inline
Determinate(const Congruence_System & cgs)108 Determinate<PSET>::Determinate(const Congruence_System& cgs)
109   : prep(new Rep(cgs)) {
110   prep->new_reference();
111 }
112 
113 template <typename PSET>
114 inline
Determinate(const Determinate & y)115 Determinate<PSET>::Determinate(const Determinate& y)
116   : prep(y.prep) {
117   prep->new_reference();
118 }
119 
120 template <typename PSET>
121 inline
~Determinate()122 Determinate<PSET>::~Determinate() {
123   if (prep->del_reference()) {
124     delete prep;
125   }
126 }
127 
128 template <typename PSET>
129 inline Determinate<PSET>&
operator =(const Determinate & y)130 Determinate<PSET>::operator=(const Determinate& y) {
131   y.prep->new_reference();
132   if (prep->del_reference()) {
133     delete prep;
134   }
135   prep = y.prep;
136   return *this;
137 }
138 
139 template <typename PSET>
140 inline void
m_swap(Determinate & y)141 Determinate<PSET>::m_swap(Determinate& y) {
142   using std::swap;
143   swap(prep, y.prep);
144 }
145 
146 template <typename PSET>
147 inline void
mutate()148 Determinate<PSET>::mutate() {
149   if (prep->is_shared()) {
150     Rep* const new_prep = new Rep(prep->pset);
151     (void) prep->del_reference();
152     new_prep->new_reference();
153     prep = new_prep;
154   }
155 }
156 
157 template <typename PSET>
158 inline const PSET&
pointset() const159 Determinate<PSET>::pointset() const {
160   return prep->pset;
161 }
162 
163 template <typename PSET>
164 inline PSET&
pointset()165 Determinate<PSET>::pointset() {
166   mutate();
167   return prep->pset;
168 }
169 
170 template <typename PSET>
171 inline void
upper_bound_assign(const Determinate & y)172 Determinate<PSET>::upper_bound_assign(const Determinate& y) {
173   pointset().upper_bound_assign(y.pointset());
174 }
175 
176 template <typename PSET>
177 inline void
meet_assign(const Determinate & y)178 Determinate<PSET>::meet_assign(const Determinate& y) {
179   pointset().intersection_assign(y.pointset());
180 }
181 
182 template <typename PSET>
183 inline bool
has_nontrivial_weakening()184 Determinate<PSET>::has_nontrivial_weakening() {
185   // FIXME: the following should be turned into a query to PSET.  This
186   // can be postponed until the time the ask-and-tell construction is
187   // revived.
188   return false;
189 }
190 
191 template <typename PSET>
192 inline void
weakening_assign(const Determinate & y)193 Determinate<PSET>::weakening_assign(const Determinate& y) {
194   // FIXME: the following should be turned into a proper
195   // implementation.  This can be postponed until the time the
196   // ask-and-tell construction is revived.
197   pointset().difference_assign(y.pointset());
198 }
199 
200 template <typename PSET>
201 inline void
concatenate_assign(const Determinate & y)202 Determinate<PSET>::concatenate_assign(const Determinate& y) {
203   pointset().concatenate_assign(y.pointset());
204 }
205 
206 template <typename PSET>
207 inline bool
definitely_entails(const Determinate & y) const208 Determinate<PSET>::definitely_entails(const Determinate& y) const {
209   return prep == y.prep || y.prep->pset.contains(prep->pset);
210 }
211 
212 template <typename PSET>
213 inline bool
is_definitely_equivalent_to(const Determinate & y) const214 Determinate<PSET>::is_definitely_equivalent_to(const Determinate& y) const {
215   return prep == y.prep || prep->pset == y.prep->pset;
216 }
217 
218 template <typename PSET>
219 inline bool
is_top() const220 Determinate<PSET>::is_top() const {
221   return prep->pset.is_universe();
222 }
223 
224 template <typename PSET>
225 inline bool
is_bottom() const226 Determinate<PSET>::is_bottom() const {
227   return prep->pset.is_empty();
228 }
229 
230 template <typename PSET>
231 inline memory_size_type
external_memory_in_bytes() const232 Determinate<PSET>::external_memory_in_bytes() const {
233   return prep->total_memory_in_bytes();
234 }
235 
236 template <typename PSET>
237 inline memory_size_type
total_memory_in_bytes() const238 Determinate<PSET>::total_memory_in_bytes() const {
239   return sizeof(*this) + external_memory_in_bytes();
240 }
241 
242 template <typename PSET>
243 inline bool
OK() const244 Determinate<PSET>::OK() const {
245   return prep->pset.OK();
246 }
247 
248 namespace IO_Operators {
249 
250 /*! \relates Parma_Polyhedra_Library::Determinate */
251 template <typename PSET>
252 inline std::ostream&
operator <<(std::ostream & s,const Determinate<PSET> & x)253 operator<<(std::ostream& s, const Determinate<PSET>& x) {
254   s << x.pointset();
255   return s;
256 }
257 
258 } // namespace IO_Operators
259 
260 /*! \relates Determinate */
261 template <typename PSET>
262 inline bool
operator ==(const Determinate<PSET> & x,const Determinate<PSET> & y)263 operator==(const Determinate<PSET>& x, const Determinate<PSET>& y) {
264   return x.prep == y.prep || x.prep->pset == y.prep->pset;
265 }
266 
267 /*! \relates Determinate */
268 template <typename PSET>
269 inline bool
operator !=(const Determinate<PSET> & x,const Determinate<PSET> & y)270 operator!=(const Determinate<PSET>& x, const Determinate<PSET>& y) {
271   return x.prep != y.prep && x.prep->pset != y.prep->pset;
272 }
273 
274 template <typename PSET>
275 template <typename Binary_Operator_Assign>
276 inline
277 Determinate<PSET>::Binary_Operator_Assign_Lifter<Binary_Operator_Assign>::
Binary_Operator_Assign_Lifter(Binary_Operator_Assign op_assign)278 Binary_Operator_Assign_Lifter(Binary_Operator_Assign op_assign)
279   : op_assign_(op_assign) {
280 }
281 
282 template <typename PSET>
283 template <typename Binary_Operator_Assign>
284 inline void
285 Determinate<PSET>::Binary_Operator_Assign_Lifter<Binary_Operator_Assign>::
operator ()(Determinate & x,const Determinate & y) const286 operator()(Determinate& x, const Determinate& y) const {
287   op_assign_(x.pointset(), y.pointset());
288 }
289 
290 template <typename PSET>
291 template <typename Binary_Operator_Assign>
292 inline typename
293 Determinate<PSET>::template Binary_Operator_Assign_Lifter<Binary_Operator_Assign>
lift_op_assign(Binary_Operator_Assign op_assign)294 Determinate<PSET>::lift_op_assign(Binary_Operator_Assign op_assign) {
295   return Binary_Operator_Assign_Lifter<Binary_Operator_Assign>(op_assign);
296 }
297 
298 /*! \relates Determinate */
299 template <typename PSET>
300 inline void
swap(Determinate<PSET> & x,Determinate<PSET> & y)301 swap(Determinate<PSET>& x, Determinate<PSET>& y) {
302   x.m_swap(y);
303 }
304 
305 } // namespace Parma_Polyhedra_Library
306 
307 #endif // !defined(PPL_Determinate_inlines_hh)
308