CBMC
dstring.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Container for C-Strings
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #ifndef CPROVER_UTIL_DSTRING_H
13 #define CPROVER_UTIL_DSTRING_H
14 
15 #include <iosfwd>
16 #include <string>
17 
18 #include "invariant.h"
19 #include "magic.h"
20 #include "string_container.h"
21 
36 class dstringt final
37 {
38 public:
39  // this is safe for static objects
40  #ifdef __GNUC__
41  constexpr
42  #endif
43  dstringt():no(0)
44  {
45  }
46 
47  // this is safe for static objects
48  #ifdef __GNUC__
49  constexpr
50  #endif
52  {
53  return dstringt(no);
54  }
55 
56  #if 0
57  // This conversion allows the use of dstrings
58  // in switch ... case statements.
59  constexpr operator int() const { return no; }
60  #endif
61 
62  // this one is not safe for static objects
63  // NOLINTNEXTLINE(runtime/explicit)
64  dstringt(const char *s):no(get_string_container()[s])
65  {
66  }
67 
68  // this one is not safe for static objects
69  // NOLINTNEXTLINE(runtime/explicit)
70  dstringt(const std::string &s):no(get_string_container()[s])
71  {
72  }
73 
74  dstringt(const dstringt &) = default;
75 
78 #ifdef __GNUC__
79  constexpr
80 #endif
81  dstringt(dstringt &&other)
82  : no(other.no)
83  {
84  }
85 
86  // access
87 
88  bool empty() const
89  {
90  return no==0; // string 0 is exactly the empty string
91  }
92 
94  bool starts_with(const char *s)
95  {
96  for(const char *t = c_str(); *s != 0; s++, t++)
97  if(*t != *s)
98  return false;
99 
100  return true;
101  }
102 
104  bool starts_with(const std::string &prefix)
105  {
106  return as_string().compare(0, prefix.size(), prefix) == 0;
107  }
108 
109  char operator[](size_t i) const
110  {
111  return as_string()[i];
112  }
113 
114  // the pointer is guaranteed to be stable
115  const char *c_str() const
116  {
117  return as_string().c_str();
118  }
119 
120  size_t size() const
121  {
122  return as_string().size();
123  }
124 
125  // ordering -- not the same as lexicographical ordering
126 
127  bool operator< (const dstringt &b) const { return no<b.no; }
128 
129  // comparison with same type
130 
131  bool operator==(const dstringt &b) const
132  { return no==b.no; } // really fast equality testing
133 
134  bool operator!=(const dstringt &b) const
135  { return no!=b.no; } // really fast equality testing
136 
137  // comparison with other types
138 
139  bool operator==(const char *b) const { return as_string()==b; }
140  bool operator!=(const char *b) const { return as_string()!=b; }
141 
142  bool operator==(const std::string &b) const { return as_string()==b; }
143  bool operator!=(const std::string &b) const { return as_string()!=b; }
144  bool operator<(const std::string &b) const { return as_string()<b; }
145  bool operator>(const std::string &b) const { return as_string()>b; }
146  bool operator<=(const std::string &b) const { return as_string()<=b; }
147  bool operator>=(const std::string &b) const { return as_string()>=b; }
148 
149  int compare(const dstringt &b) const
150  {
151  if(no==b.no)
152  return 0; // equal
153  return as_string().compare(b.as_string());
154  }
155 
156  // modifying
157 
158  void clear()
159  { no=0; }
160 
161  void swap(dstringt &b)
162  { unsigned t=no; no=b.no; b.no=t; }
163 
165  { no=b.no; return *this; }
166 
170  {
171  no = other.no;
172  return *this;
173  }
174 
175  // output
176 
177  std::ostream &operator<<(std::ostream &out) const;
178 
179  // non-standard
180 
181  unsigned get_no() const
182  {
183  return no;
184  }
185 
186  size_t hash() const
187  {
188  return no;
189  }
190 
191  // iterators for the underlying string
192  std::string::const_iterator begin() const
193  {
194  return as_string().begin();
195  }
196 
197  std::string::const_iterator end() const
198  {
199  return as_string().end();
200  }
201 
202 private:
203  #ifdef __GNUC__
204  constexpr
205  #endif
206  explicit dstringt(unsigned _no):no(_no)
207  {
208  }
209 
210  unsigned no;
211 
212  // the reference returned is guaranteed to be stable
213  const std::string &as_string() const
214  { return get_string_container().get_string(no); }
215 };
216 
217 // the reference returned is guaranteed to be stable
218 inline const std::string &as_string(const dstringt &s)
219 { return get_string_container().get_string(s.get_no()); }
220 
221 // NOLINTNEXTLINE(readability/identifiers)
223 {
224  size_t operator()(const dstringt &s) const { return s.hash(); }
225 };
226 
227 inline size_t hash_string(const dstringt &s)
228 {
229  return s.hash();
230 }
231 
232 inline std::ostream &operator<<(std::ostream &out, const dstringt &a)
233 {
234  return a.operator<<(out);
235 }
236 
237 // NOLINTNEXTLINE [allow specialisation within 'std']
238 namespace std
239 {
241 template <>
242 struct hash<dstringt> // NOLINT(readability/identifiers)
243 {
244  size_t operator()(const dstringt &dstring) const
245  {
246  return dstring.hash();
247  }
248 };
249 }
250 
251 template <>
253 {
254  static std::string diagnostics_as_string(const dstringt &dstring)
255  {
256  return as_string(dstring);
257  }
258 };
259 
260 dstringt get_dstring_number(std::size_t);
261 
264 template <typename T>
265 static inline
266  typename std::enable_if<std::is_integral<T>::value, dstringt>::type
267  to_dstring(T value)
268 {
269  if(value >= 0 && value <= static_cast<T>(DSTRING_NUMBERS_MAX))
270  return get_dstring_number(value);
271  else
272  return std::to_string(value);
273 }
274 
275 #endif // CPROVER_UTIL_DSTRING_H
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
dstringt::dstringt
dstringt(unsigned _no)
Definition: dstring.h:206
dstringt::c_str
const char * c_str() const
Definition: dstring.h:115
dstring_hash::operator()
size_t operator()(const dstringt &s) const
Definition: dstring.h:224
dstringt::operator>=
bool operator>=(const std::string &b) const
Definition: dstring.h:147
dstringt::operator!=
bool operator!=(const char *b) const
Definition: dstring.h:140
operator<<
std::ostream & operator<<(std::ostream &out, const dstringt &a)
Definition: dstring.h:232
get_dstring_number
dstringt get_dstring_number(std::size_t)
Definition: dstring.cpp:19
string_containert::get_string
const std::string & get_string(size_t no) const
Definition: string_container.h:87
dstringt::operator==
bool operator==(const dstringt &b) const
Definition: dstring.h:131
dstringt::operator<<
std::ostream & operator<<(std::ostream &out) const
Definition: dstring.cpp:14
std::hash< dstringt >::operator()
size_t operator()(const dstringt &dstring) const
Definition: dstring.h:244
invariant.h
string_container.h
dstringt::operator<
bool operator<(const dstringt &b) const
Definition: dstring.h:127
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
as_string
const std::string & as_string(const dstringt &s)
Definition: dstring.h:218
magic.h
Magic numbers used throughout the codebase.
dstringt::starts_with
bool starts_with(const std::string &prefix)
equivalent of as_string().starts_with(s)
Definition: dstring.h:104
dstringt::operator==
bool operator==(const char *b) const
Definition: dstring.h:139
dstringt::dstringt
dstringt(dstringt &&other)
Move constructor.
Definition: dstring.h:81
dstringt::swap
void swap(dstringt &b)
Definition: dstring.h:161
to_dstring
static std::enable_if< std::is_integral< T >::value, dstringt >::type to_dstring(T value)
equivalent to dstringt(std::to_string(value)), i.e., produces a string from a number
Definition: dstring.h:267
dstringt::no
unsigned no
Definition: dstring.h:210
dstring_hash
Definition: dstring.h:222
dstringt::operator=
dstringt & operator=(dstringt &&other)
Move assignment.
Definition: dstring.h:169
dstringt::dstringt
dstringt(const char *s)
Definition: dstring.h:64
DSTRING_NUMBERS_MAX
constexpr std::size_t DSTRING_NUMBERS_MAX
Definition: magic.h:17
dstringt::empty
bool empty() const
Definition: dstring.h:88
dstringt::compare
int compare(const dstringt &b) const
Definition: dstring.h:149
dstringt::operator!=
bool operator!=(const dstringt &b) const
Definition: dstring.h:134
diagnostics_helpert
Helper to give us some diagnostic in a usable form on assertion failure.
Definition: invariant.h:298
hash_string
size_t hash_string(const dstringt &s)
Definition: dstring.h:227
dstringt::clear
void clear()
Definition: dstring.h:158
dstringt::as_string
const std::string & as_string() const
Definition: dstring.h:213
dstringt::make_from_table_index
static dstringt make_from_table_index(unsigned no)
Definition: dstring.h:51
diagnostics_helpert< dstringt >::diagnostics_as_string
static std::string diagnostics_as_string(const dstringt &dstring)
Definition: dstring.h:254
dstringt::get_no
unsigned get_no() const
Definition: dstring.h:181
dstringt::end
std::string::const_iterator end() const
Definition: dstring.h:197
dstringt::operator!=
bool operator!=(const std::string &b) const
Definition: dstring.h:143
dstringt::operator<
bool operator<(const std::string &b) const
Definition: dstring.h:144
dstringt::operator==
bool operator==(const std::string &b) const
Definition: dstring.h:142
dstringt::dstringt
dstringt(const std::string &s)
Definition: dstring.h:70
dstringt::operator=
dstringt & operator=(const dstringt &b)
Definition: dstring.h:164
dstringt::begin
std::string::const_iterator begin() const
Definition: dstring.h:192
dstringt::starts_with
bool starts_with(const char *s)
equivalent of as_string().starts_with(s)
Definition: dstring.h:94
dstringt::hash
size_t hash() const
Definition: dstring.h:186
dstringt::operator>
bool operator>(const std::string &b) const
Definition: dstring.h:145
dstringt::dstringt
dstringt()
Definition: dstring.h:43
dstringt::size
size_t size() const
Definition: dstring.h:120
get_string_container
string_containert & get_string_container()
Get a reference to the global string container.
Definition: string_container.h:111
dstringt::operator[]
char operator[](size_t i) const
Definition: dstring.h:109
dstringt::operator<=
bool operator<=(const std::string &b) const
Definition: dstring.h:146