1 /* Copyright (c) 2015. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
7 #ifndef SIMGRID_XBT_STRING_HPP
8 #define SIMGRID_XBT_STRING_HPP
10 #include <simgrid_config.h>
21 #include <xbt/sysdep.h>
26 /** POD structure representation of a string
33 /** A std::string with well-known representation
35 * This is a (incomplete) drop-in replacement for `std::string`.
36 * It has a fixed POD representation (`simgrid::xbt::string_data`)
37 * which can be used to easily read the string content from another
40 * The internal representation of a `std::string` is private.
41 * We could add some code to read this for a given implementation.
42 * However, even if we focus on GNU libstdc++ with Itanium ABI
43 * GNU libstdc++ currently has two different ABIs
45 * * the pre-C++11 is a pointer to a ref-counted
46 * string-representation (with support for COW);
48 * * the [C++11-conforming implementation](https://gcc.gnu.org/gcc-5/changes.html)
49 * does not use refcouting/COW but has a small string optimization.
51 XBT_PUBLIC_CLASS string : private string_data {
52 static const char NUL;
56 typedef std::size_t size_type;
57 typedef std::ptrdiff_t difference_type;
58 typedef char& reference;
59 typedef const char& const_reference;
60 typedef char* pointer;
61 typedef const char* const_pointer;
62 typedef char* iterator;
63 typedef const char* const_iterator;
68 if (string_data::data != &NUL)
69 std::free(string_data::data);
73 string(const char* s, size_t size)
77 string_data::data = const_cast<char*>(&NUL);
79 string_data::len = size;
80 string_data::data = static_cast<char*>(std::malloc(string_data::len + 1));
81 memcpy(string_data::data, s, string_data::len);
82 string_data::data[string_data::len] = '\0';
85 string() : string (nullptr, 0) {}
87 : string(s, s == nullptr ? 0 : strlen(s))
89 string(string const& s) : string(s.c_str(), s.size()) {}
92 string_data::len = s.string_data::len;
93 string_data::data = s.string_data::data;
94 s.string_data::len = 0;
95 s.string_data::data = const_cast<char*>(&NUL);
97 string(std::string const& s) : string(s.c_str(), s.size()) {}
100 void assign(const char* s, size_t size)
102 if (string_data::data != &NUL)
103 std::free(string_data::data);
105 string_data::len = 0;
106 string_data::data = nullptr;
108 string_data::len = size;
109 string_data::data = (char*) std::malloc(string_data::len + 1);
110 memcpy(string_data::data, s, string_data::len);
111 string_data::data[string_data::len] = '\0';
116 string& operator=(const char* s)
118 assign(s, s == nullptr ? 0 : std::strlen(s));
121 string& operator=(string& s)
123 assign(s.c_str(), s.size());
126 string& operator=(std::string& s)
128 assign(s.c_str(), s.size());
133 size_t size() const { return len; }
134 size_t length() const { return len; }
135 bool empty() const { return len != 0; }
136 void shrink_to_fit() {}
139 char* data() { return string_data::data; }
140 const char* data() const { return string_data::data; }
141 char* c_str() { return string_data::data; }
142 const char* c_str() const { return string_data::data; };
143 reference at(size_type i)
146 throw std::out_of_range("Out of range");
149 const_reference at(size_type i) const
152 throw std::out_of_range("Out of range");
155 reference operator[](size_type i)
159 const_reference operator[](size_type i) const
164 operator std::string() const
166 return std::string(this->c_str(), this->size());
170 iterator begin() { return data(); }
171 iterator end() { return data() + size(); }
172 const_iterator begin() const { return data(); }
173 const_iterator end() const { return data() + size(); }
174 const_iterator cbegin() const { return data(); }
175 const_iterator cend() const { return data() + size(); }
176 // (Missing, reverse iterators)
181 string_data::len = 0;
182 string_data::data = (char*) &NUL;
186 int compare(string const& that) const
188 size_t n = std::min(this->size(), that.size());
189 int res = memcmp(this->c_str(), that.c_str(), n);
192 else if (this->size() == that.size())
194 else if (this->size() < that.size())
199 bool operator==(string const& that) const
201 return this->size() == that.size()
202 && std::memcmp(this->c_str(), that.c_str(), this->size()) == 0;
204 bool operator!=(string const& that) const
206 return !(*this == that);
208 bool operator<(string const& that) const
210 return compare(that) < 0;
212 bool operator<=(string const& that) const
214 return compare(that) <= 0;
216 bool operator>(string const& that) const
218 return compare(that) > 0;
220 bool operator>=(string const& that) const
222 return compare(that) >= 0;
225 // Compare with std::string
226 bool operator==(std::string const& that) const
228 return this->size() == that.size()
229 && std::memcmp(this->c_str(), that.c_str(), this->size()) == 0;
231 bool operator!=(std::string const& that) const
233 return !(*this == that);
235 bool operator<(std::string const& that) const
237 return compare(that) < 0;
239 bool operator<=(std::string const& that) const
241 return compare(that) <= 0;
243 bool operator>(std::string const& that) const
245 return compare(that) > 0;
247 bool operator>=(std::string const& that) const
249 return compare(that) >= 0;
254 bool operator==(std::string const& a, string const& b)
259 bool operator!=(std::string const& a, string const& b)
264 bool operator<(std::string const& a, string const& b)
269 bool operator<=(std::string const& a, string const& b)
274 bool operator>(std::string const& a, string const& b)
279 bool operator>=(std::string const& a, string const& b)
294 typedef std::string string;