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
10 #include "src/internal_config.h"
20 #include <xbt/sysdep.h>
25 /** POD structure representation of a string
32 /** A std::string with well-known representation
34 * This is a (incomplete) drop-in replacement for `std::string`.
35 * It has a fixed POD representation (`simgrid::xbt::string_data`)
36 * which can be used to easily read the string content from another
39 * The internal representation of a `std::string` is private.
40 * We could add some code to read this for a given implementation.
41 * However, even if we focus on GNU libstdc++ with Itanium ABI
42 * GNU libstdc++ currently has two different ABIs
44 * * the pre-C++11 is a pointer to a ref-counted
45 * string-representation (with support for COW);
47 * * the [C++11-conforming implementation](https://gcc.gnu.org/gcc-5/changes.html)
48 * does not use refcouting/COW but has a small string optimization.
50 XBT_PUBLIC_CLASS string : private string_data {
51 static const char NUL;
55 typedef std::size_t size_type;
56 typedef std::ptrdiff_t difference_type;
57 typedef char& reference;
58 typedef const char& const_reference;
59 typedef char* pointer;
60 typedef const char* const_pointer;
61 typedef char* iterator;
62 typedef const char* const_iterator;
67 if (string_data::data != &NUL)
68 std::free(string_data::data);
72 string(const char* s, size_t size)
76 string_data::data = const_cast<char*>(&NUL);
78 string_data::len = size;
79 string_data::data = static_cast<char*>(std::malloc(string_data::len + 1));
80 memcpy(string_data::data, s, string_data::len);
81 string_data::data[string_data::len] = '\0';
84 string() : string (nullptr, 0) {}
86 : string(s, s == nullptr ? 0 : strlen(s))
88 string(string const& s) : string(s.c_str(), s.size()) {}
91 string_data::len = s.string_data::len;
92 string_data::data = s.string_data::data;
93 s.string_data::len = 0;
94 s.string_data::data = const_cast<char*>(&NUL);
96 string(std::string const& s) : string(s.c_str(), s.size()) {}
99 void assign(const char* s, size_t size)
101 if (string_data::data != &NUL)
102 std::free(string_data::data);
104 string_data::len = 0;
105 string_data::data = nullptr;
107 string_data::len = size;
108 string_data::data = (char*) std::malloc(string_data::len + 1);
109 memcpy(string_data::data, s, string_data::len);
110 string_data::data[string_data::len] = '\0';
115 string& operator=(const char* s)
117 assign(s, s == nullptr ? 0 : std::strlen(s));
120 string& operator=(string& s)
122 assign(s.c_str(), s.size());
125 string& operator=(std::string& s)
127 assign(s.c_str(), s.size());
132 size_t size() const { return len; }
133 size_t length() const { return len; }
134 bool empty() const { return len != 0; }
135 void shrink_to_fit() {}
138 char* data() { return string_data::data; }
139 const char* data() const { return string_data::data; }
140 char* c_str() { return string_data::data; }
141 const char* c_str() const { return string_data::data; };
142 reference at(size_type i)
145 throw std::out_of_range("Out of range");
148 const_reference at(size_type i) const
151 throw std::out_of_range("Out of range");
154 reference operator[](size_type i)
158 const_reference operator[](size_type i) const
163 operator std::string() const
165 return std::string(this->c_str(), this->size());
169 iterator begin() { return data(); }
170 iterator end() { return data() + size(); }
171 const_iterator begin() const { return data(); }
172 const_iterator end() const { return data() + size(); }
173 const_iterator cbegin() const { return data(); }
174 const_iterator cend() const { return data() + size(); }
175 // (Missing, reverse iterators)
180 string_data::len = 0;
181 string_data::data = (char*) &NUL;
185 int compare(string const& that) const
187 size_t n = std::min(this->size(), that.size());
188 int res = memcmp(this->c_str(), that.c_str(), n);
191 else if (this->size() == that.size())
193 else if (this->size() < that.size())
198 bool operator==(string const& that) const
200 return this->size() == that.size()
201 && std::memcmp(this->c_str(), that.c_str(), this->size()) == 0;
203 bool operator!=(string const& that) const
205 return !(*this == that);
207 bool operator<(string const& that) const
209 return compare(that) < 0;
211 bool operator<=(string const& that) const
213 return compare(that) <= 0;
215 bool operator>(string const& that) const
217 return compare(that) > 0;
219 bool operator>=(string const& that) const
221 return compare(that) >= 0;
224 // Compare with std::string
225 bool operator==(std::string const& that) const
227 return this->size() == that.size()
228 && std::memcmp(this->c_str(), that.c_str(), this->size()) == 0;
230 bool operator!=(std::string const& that) const
232 return !(*this == that);
234 bool operator<(std::string const& that) const
236 return compare(that) < 0;
238 bool operator<=(std::string const& that) const
240 return compare(that) <= 0;
242 bool operator>(std::string const& that) const
244 return compare(that) > 0;
246 bool operator>=(std::string const& that) const
248 return compare(that) >= 0;
253 bool operator==(std::string const& a, string const& b)
258 bool operator!=(std::string const& a, string const& b)
263 bool operator<(std::string const& a, string const& b)
268 bool operator<=(std::string const& a, string const& b)
273 bool operator>(std::string const& a, string const& b)
278 bool operator>=(std::string const& a, string const& b)
293 typedef std::string string;