1 /* BD_Shape<T>::Status 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_BDS_Status_inlines_hh
25 #define PPL_BDS_Status_inlines_hh 1
26
27 namespace Parma_Polyhedra_Library {
28
29 template <typename T>
30 inline
Status(flags_t mask)31 BD_Shape<T>::Status::Status(flags_t mask)
32 : flags(mask) {
33 }
34
35 template <typename T>
36 inline
Status()37 BD_Shape<T>::Status::Status()
38 : flags(ZERO_DIM_UNIV) {
39 }
40
41 template <typename T>
42 inline bool
test_all(flags_t mask) const43 BD_Shape<T>::Status::test_all(flags_t mask) const {
44 return (flags & mask) == mask;
45 }
46
47 template <typename T>
48 inline bool
test_any(flags_t mask) const49 BD_Shape<T>::Status::test_any(flags_t mask) const {
50 return (flags & mask) != 0;
51 }
52
53 template <typename T>
54 inline void
set(flags_t mask)55 BD_Shape<T>::Status::set(flags_t mask) {
56 flags |= mask;
57 }
58
59 template <typename T>
60 inline void
reset(flags_t mask)61 BD_Shape<T>::Status::reset(flags_t mask) {
62 flags &= ~mask;
63 }
64
65 template <typename T>
66 inline bool
test_zero_dim_univ() const67 BD_Shape<T>::Status::test_zero_dim_univ() const {
68 return flags == ZERO_DIM_UNIV;
69 }
70
71 template <typename T>
72 inline void
reset_zero_dim_univ()73 BD_Shape<T>::Status::reset_zero_dim_univ() {
74 // This is a no-op if the current status is not zero-dim.
75 if (flags == ZERO_DIM_UNIV) {
76 // In the zero-dim space, if it is not the universe it is empty.
77 flags = EMPTY;
78 }
79 }
80
81 template <typename T>
82 inline void
set_zero_dim_univ()83 BD_Shape<T>::Status::set_zero_dim_univ() {
84 // Zero-dim universe is incompatible with anything else.
85 flags = ZERO_DIM_UNIV;
86 }
87
88 template <typename T>
89 inline bool
test_empty() const90 BD_Shape<T>::Status::test_empty() const {
91 return test_any(EMPTY);
92 }
93
94 template <typename T>
95 inline void
reset_empty()96 BD_Shape<T>::Status::reset_empty() {
97 reset(EMPTY);
98 }
99
100 template <typename T>
101 inline void
set_empty()102 BD_Shape<T>::Status::set_empty() {
103 flags = EMPTY;
104 }
105
106 template <typename T>
107 inline bool
test_shortest_path_closed() const108 BD_Shape<T>::Status::test_shortest_path_closed() const {
109 return test_any(SHORTEST_PATH_CLOSED);
110 }
111
112 template <typename T>
113 inline void
reset_shortest_path_closed()114 BD_Shape<T>::Status::reset_shortest_path_closed() {
115 // A system is reduced only if it is also closed.
116 reset(SHORTEST_PATH_CLOSED | SHORTEST_PATH_REDUCED);
117 }
118
119 template <typename T>
120 inline void
set_shortest_path_closed()121 BD_Shape<T>::Status::set_shortest_path_closed() {
122 set(SHORTEST_PATH_CLOSED);
123 }
124
125 template <typename T>
126 inline bool
test_shortest_path_reduced() const127 BD_Shape<T>::Status::test_shortest_path_reduced() const {
128 return test_any(SHORTEST_PATH_REDUCED);
129 }
130
131 template <typename T>
132 inline void
reset_shortest_path_reduced()133 BD_Shape<T>::Status::reset_shortest_path_reduced() {
134 reset(SHORTEST_PATH_REDUCED);
135 }
136
137 template <typename T>
138 inline void
set_shortest_path_reduced()139 BD_Shape<T>::Status::set_shortest_path_reduced() {
140 PPL_ASSERT(test_shortest_path_closed());
141 set(SHORTEST_PATH_REDUCED);
142 }
143
144 template <typename T>
145 bool
OK() const146 BD_Shape<T>::Status::OK() const {
147 if (test_zero_dim_univ()) {
148 // Zero-dim universe is OK.
149 return true;
150 }
151
152 if (test_empty()) {
153 Status copy = *this;
154 copy.reset_empty();
155 if (copy.test_zero_dim_univ()) {
156 return true;
157 }
158 else {
159 #ifndef NDEBUG
160 std::cerr << "The empty flag is incompatible with any other one."
161 << std::endl;
162 #endif
163 return false;
164 }
165 }
166
167 // Shortest-path reduction implies shortest-path closure.
168 if (test_shortest_path_reduced()) {
169 if (test_shortest_path_closed()) {
170 return true;
171 }
172 else {
173 #ifndef NDEBUG
174 std::cerr << "The shortest-path reduction flag should also imply "
175 << "the closure flag."
176 << std::endl;
177 #endif
178 return false;
179 }
180 }
181
182 // Any other case is OK.
183 return true;
184 }
185
186
187 namespace Implementation {
188
189 namespace BD_Shapes {
190
191 // These are the keywords that indicate the individual assertions.
192 extern const char* zero_dim_univ;
193 extern const char* empty;
194 extern const char* sp_closed;
195 extern const char* sp_reduced;
196 const char yes = '+';
197 const char no = '-';
198 const char separator = ' ';
199
200 /*! \relates Parma_Polyhedra_Library::BD_Shape::Status
201 Reads a keyword and its associated on/off flag from \p s.
202 Returns <CODE>true</CODE> if the operation is successful,
203 returns <CODE>false</CODE> otherwise.
204 When successful, \p positive is set to <CODE>true</CODE> if the flag
205 is on; it is set to <CODE>false</CODE> otherwise.
206 */
207 inline bool
get_field(std::istream & s,const char * keyword,bool & positive)208 get_field(std::istream& s, const char* keyword, bool& positive) {
209 std::string str;
210 if (!(s >> str)
211 || (str[0] != yes && str[0] != no)
212 || str.substr(1) != keyword) {
213 return false;
214 }
215 positive = (str[0] == yes);
216 return true;
217 }
218
219 } // namespace BD_Shapes
220
221 } // namespace Implementation
222
223 template <typename T>
224 void
ascii_dump(std::ostream & s) const225 BD_Shape<T>::Status::ascii_dump(std::ostream& s) const {
226 using namespace Implementation::BD_Shapes;
227 s << (test_zero_dim_univ() ? yes : no) << zero_dim_univ << separator
228 << (test_empty() ? yes : no) << empty << separator
229 << separator
230 << (test_shortest_path_closed() ? yes : no) << sp_closed << separator
231 << (test_shortest_path_reduced() ? yes : no) << sp_reduced << separator;
232 }
233
PPL_OUTPUT_TEMPLATE_DEFINITIONS_ASCII_ONLY(T,BD_Shape<T>::Status)234 PPL_OUTPUT_TEMPLATE_DEFINITIONS_ASCII_ONLY(T, BD_Shape<T>::Status)
235
236 template <typename T>
237 bool
238 BD_Shape<T>::Status::ascii_load(std::istream& s) {
239 using namespace Implementation::BD_Shapes;
240 PPL_UNINITIALIZED(bool, positive);
241
242 if (!get_field(s, zero_dim_univ, positive)) {
243 return false;
244 }
245 if (positive) {
246 set_zero_dim_univ();
247 }
248
249 if (!get_field(s, empty, positive)) {
250 return false;
251 }
252 if (positive) {
253 set_empty();
254 }
255
256 if (!get_field(s, sp_closed, positive)) {
257 return false;
258 }
259 if (positive) {
260 set_shortest_path_closed();
261 }
262 else {
263 reset_shortest_path_closed();
264 }
265
266 if (!get_field(s, sp_reduced, positive)) {
267 return false;
268 }
269 if (positive) {
270 set_shortest_path_reduced();
271 }
272 else {
273 reset_shortest_path_reduced();
274 }
275
276 // Check invariants.
277 PPL_ASSERT(OK());
278 return true;
279 }
280
281 } // namespace Parma_Polyhedra_Library
282
283 #endif // !defined(PPL_BDS_Status_inlines_hh)
284