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