PPL  1.2
Checked_Number_templates.hh
Go to the documentation of this file.
1 /* Checked_Number class implementation: non-inline template 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_Checked_Number_templates_hh
25 #define PPL_Checked_Number_templates_hh 1
26 
27 #include "assertions.hh"
28 #include <iomanip>
29 #include <limits>
30 
31 namespace Parma_Polyhedra_Library {
32 
33 template <typename T>
34 typename Enable_If<Is_Native_Or_Checked<T>::value, void>::type
35 ascii_dump(std::ostream& s, const T& t) {
36  if (std::numeric_limits<T>::is_exact) {
37  // An exact data type: pretty printer is accurate.
38  s << t;
39  }
40  else {
41  // An inexact data type (probably floating point):
42  // first dump its hexadecimal representation ...
43  const std::ios::fmtflags old_flags = s.setf(std::ios::hex,
44  std::ios::basefield);
45  const unsigned char* p = reinterpret_cast<const unsigned char*>(&t);
46  for (unsigned i = 0; i < sizeof(T); ++i) {
47  s << std::setw(2) << std::setfill('0') << static_cast<unsigned>(p[i]);
48  }
49  s.flags(old_flags);
50  // ... and then pretty print it for readability.
51  s << " (" << t << ")";
52  }
53 }
54 
55 template <typename T>
56 typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type
57 ascii_load(std::istream& s, T& t) {
58  if (std::numeric_limits<T>::is_exact) {
59  // An exact data type: input from pretty printed version is accurate.
60  s >> t;
61  return !s.fail();
62  }
63  else {
64  // An inexact data type (probably floating point):
65  // first load its hexadecimal representation ...
66  std::string str;
67  if (!(s >> str) || str.size() != 2*sizeof(T)) {
68  return false;
69  }
70  unsigned char* p = reinterpret_cast<unsigned char*>(&t);
71  // CHECKME: any (portable) simpler way?
72  for (unsigned i = 0; i < sizeof(T); ++i) {
73  unsigned byte_value = 0;
74  for (unsigned j = 0; j < 2; ++j) {
75  byte_value <<= 4;
76  unsigned half_byte_value;
77  // Interpret single hex character.
78  switch (str[2*i + j]) {
79  case '0':
80  half_byte_value = 0;
81  break;
82  case '1':
83  half_byte_value = 1;
84  break;
85  case '2':
86  half_byte_value = 2;
87  break;
88  case '3':
89  half_byte_value = 3;
90  break;
91  case '4':
92  half_byte_value = 4;
93  break;
94  case '5':
95  half_byte_value = 5;
96  break;
97  case '6':
98  half_byte_value = 6;
99  break;
100  case '7':
101  half_byte_value = 7;
102  break;
103  case '8':
104  half_byte_value = 8;
105  break;
106  case '9':
107  half_byte_value = 9;
108  break;
109  case 'A':
110  case 'a':
111  half_byte_value = 10;
112  break;
113  case 'B':
114  case 'b':
115  half_byte_value = 11;
116  break;
117  case 'C':
118  case 'c':
119  half_byte_value = 12;
120  break;
121  case 'D':
122  case 'd':
123  half_byte_value = 13;
124  break;
125  case 'E':
126  case 'e':
127  half_byte_value = 14;
128  break;
129  case 'F':
130  case 'f':
131  half_byte_value = 15;
132  break;
133  default:
134  return false;
135  }
136  byte_value += half_byte_value;
137  }
138  PPL_ASSERT(byte_value <= 255);
139  p[i] = static_cast<unsigned char>(byte_value);
140  }
141  // ... then read and discard pretty printed value.
142  if (!(s >> str)) {
143  return false;
144  }
145  const std::string::size_type sz = str.size();
146  return sz > 2 && str[0] == '(' && str[sz-1] == ')';
147  }
148 }
149 
150 } // namespace Parma_Polyhedra_Library
151 
152 #endif // !defined(PPL_Checked_Number_templates_hh)
Enable_If< Is_Native_Or_Checked< T >::value, void >::type ascii_dump(std::ostream &s, const T &t)
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type ascii_load(std::istream &s, T &t)
Coefficient value
Definition: PIP_Tree.cc:618
The entire library is confined to this namespace.
Definition: version.hh:61