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 SIMGRIC_XBT_STRING_HPP
8 #define SIMGRIC_XBT_STRING_HPP
19 #include <xbt/sysdep.h>
24 /** POD structure representation of a string
31 /** A std::string with well-known representation
33 * This is a (incomplete) drop-in replacement for `std::string`.
34 * It has a fixed POD representation (`simgrid::xbt::string_data`)
35 * which can be used to easily read the string content from another
38 * The internal representation of a `std::string` is private.
39 * We could add some code to read this for a given implementation.
40 * However, even if we focus on GNU libstdc++ with Itanium ABI
41 * GNU libstdc++ currently has two different ABIs
43 * * the pre-C++11 is a pointer to a ref-counted
44 * string-representation (with support for COW);
46 * * the [C++11-conforming implementation](https://gcc.gnu.org/gcc-5/changes.html)
47 * does not use refcouting/COW but has a small string optimization.
49 XBT_PUBLIC_CLASS string : private string_data {
50 static const char NUL;
54 typedef std::size_t size_type;
55 typedef std::ptrdiff_t difference_type;
56 typedef char& reference;
57 typedef const char& const_reference;
58 typedef char* pointer;
59 typedef const char* const_pointer;
60 typedef char* iterator;
61 typedef const char* const_iterator;
66 if (string_data::data != &NUL)
67 std::free(string_data::data);
71 string(const char* s, size_t size)
75 string_data::data = const_cast<char*>(&NUL);
77 string_data::len = size;
78 string_data::data = static_cast<char*>(std::malloc(string_data::len + 1));
79 memcpy(string_data::data, s, string_data::len);
80 string_data::data[string_data::len] = '\0';
83 string() : string (nullptr, 0) {}
85 : string(s, s == nullptr ? 0 : strlen(s))
87 string(string const& s) : string(s.c_str(), s.size()) {}
90 string_data::len = s.string_data::len;
91 string_data::data = s.string_data::data;
92 s.string_data::len = 0;
93 s.string_data::data = const_cast<char*>(&NUL);
95 string(std::string const& s) : string(s.c_str(), s.size()) {}
98 void assign(const char* s, size_t size)
100 if (string_data::data != &NUL)
101 std::free(string_data::data);
103 string_data::len = 0;
104 string_data::data = nullptr;
106 string_data::len = size;
107 string_data::data = (char*) std::malloc(string_data::len + 1);
108 memcpy(string_data::data, s, string_data::len);
109 string_data::data[string_data::len] = '\0';
114 string& operator=(const char* s)
116 assign(s, s == nullptr ? 0 : std::strlen(s));
119 string& operator=(string& s)
121 assign(s.c_str(), s.size());
124 string& operator=(std::string& s)
126 assign(s.c_str(), s.size());
131 size_t size() const { return len; }
132 size_t length() const { return len; }
133 bool empty() const { return len != 0; }
134 void shrink_to_fit() {}
137 char* data() { return string_data::data; }
138 const char* data() const { return string_data::data; }
139 char* c_str() { return string_data::data; }
140 const char* c_str() const { return string_data::data; };
141 reference at(size_type i)
144 throw std::out_of_range("Out of range");
147 const_reference at(size_type i) const
150 throw std::out_of_range("Out of range");
153 reference operator[](size_type i)
157 const_reference operator[](size_type i) const
162 operator std::string() const
164 return std::string(this->c_str(), this->size());
168 iterator begin() { return data(); }
169 iterator end() { return data() + size(); }
170 const_iterator begin() const { return data(); }
171 const_iterator end() const { return data() + size(); }
172 const_iterator cbegin() const { return data(); }
173 const_iterator cend() const { return data() + size(); }
174 // (Missing, reverse iterators)
179 string_data::len = 0;
180 string_data::data = (char*) &NUL;
184 int compare(string const& that) const
186 size_t n = std::min(this->size(), that.size());
187 int res = memcmp(this->c_str(), that.c_str(), n);
190 else if (this->size() == that.size())
192 else if (this->size() < that.size())
197 bool operator==(string const& that) const
199 return this->size() == that.size()
200 && std::memcmp(this->c_str(), that.c_str(), this->size()) == 0;
202 bool operator!=(string const& that) const
204 return !(*this == that);
206 bool operator<(string const& that) const
208 return compare(that) < 0;
210 bool operator<=(string const& that) const
212 return compare(that) <= 0;
214 bool operator>(string const& that) const
216 return compare(that) > 0;
218 bool operator>=(string const& that) const
220 return compare(that) >= 0;
223 // Compare with std::string
224 bool operator==(std::string const& that) const
226 return this->size() == that.size()
227 && std::memcmp(this->c_str(), that.c_str(), this->size()) == 0;
229 bool operator!=(std::string const& that) const
231 return !(*this == that);
233 bool operator<(std::string const& that) const
235 return compare(that) < 0;
237 bool operator<=(std::string const& that) const
239 return compare(that) <= 0;
241 bool operator>(std::string const& that) const
243 return compare(that) > 0;
245 bool operator>=(std::string const& that) const
247 return compare(that) >= 0;
252 bool operator==(std::string const& a, string const& b)
257 bool operator!=(std::string const& a, string const& b)
262 bool operator<(std::string const& a, string const& b)
267 bool operator<=(std::string const& a, string const& b)
272 bool operator>(std::string const& a, string const& b)
277 bool operator>=(std::string const& a, string const& b)
292 typedef std::string string;