-/* Copyright (c) 2015-2017. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#ifndef SIMGRID_XBT_STRING_HPP
#define SIMGRID_XBT_STRING_HPP
-#include <simgrid_config.h>
+#include <simgrid/config.h>
#include <cstdarg>
#include <cstdlib>
namespace simgrid {
namespace xbt {
+/** Create a C++ string from a C-style format
+ *
+ * @ingroup XBT_str
+ */
+XBT_PUBLIC std::string string_printf(const char* fmt, ...) XBT_ATTRIB_PRINTF(1, 2);
+
+/** Create a C++ string from a C-style format
+ *
+ * @ingroup XBT_str
+ */
+XBT_PUBLIC std::string string_vprintf(const char* fmt, va_list ap) XBT_ATTRIB_PRINTF(1, 0);
+
#if SIMGRID_HAVE_MC
/** POD structure representation of a string
* * the [C++11-conforming implementation](https://gcc.gnu.org/gcc-5/changes.html)
* does not use refcouting/COW but has a small string optimization.
*/
-XBT_PUBLIC_CLASS string : private string_data {
+class XBT_PUBLIC string {
static char NUL;
+ string_data str;
public:
// Types
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef char& reference;
- typedef const char& const_reference;
- typedef char* pointer;
- typedef const char* const_pointer;
- typedef char* iterator;
- typedef const char* const_iterator;
+ using size_type = std::size_t;
+ using reference = char&;
+ using const_reference = const char&;
+ using iterator = char*;
+ using const_iterator = const char*;
// Dtor
~string()
{
- if (string_data::data != &NUL)
- delete[] string_data::data;
+ if (str.data != &NUL)
+ delete[] str.data;
}
// Ctors
string(const char* s, size_t size)
{
if (size == 0) {
- string_data::len = 0;
- string_data::data = &NUL;
+ str.len = 0;
+ str.data = &NUL;
} else {
- string_data::len = size;
- string_data::data = new char[string_data::len + 1];
- std::copy_n(s, string_data::len, string_data::data);
- string_data::data[string_data::len] = '\0';
+ str.len = size;
+ str.data = new char[str.len + 1];
+ std::copy_n(s, str.len, str.data);
+ str.data[str.len] = '\0';
}
}
string() : string(&NUL, 0) {}
- string(const char* s) : string(s, strlen(s)) {}
+ explicit string(const char* s) : string(s, strlen(s)) {}
string(string const& s) : string(s.c_str(), s.size()) {}
- string(string&& s)
+ string(string&& s) noexcept : str(s.str)
{
- string_data::len = s.string_data::len;
- string_data::data = s.string_data::data;
- s.string_data::len = 0;
- s.string_data::data = &NUL;
+ s.str.len = 0;
+ s.str.data = &NUL;
}
explicit string(std::string const& s) : string(s.c_str(), s.size()) {}
// Assign
void assign(const char* s, size_t size)
{
- if (string_data::data != &NUL) {
- delete[] string_data::data;
- string_data::data = nullptr;
- string_data::len = 0;
+ if (str.data != &NUL) {
+ delete[] str.data;
+ str.data = nullptr;
+ str.len = 0;
}
if (size != 0) {
- string_data::len = size;
- string_data::data = new char[string_data::len + 1];
- std::copy_n(s, string_data::len, string_data::data);
- string_data::data[string_data::len] = '\0';
+ str.len = size;
+ str.data = new char[str.len + 1];
+ std::copy_n(s, str.len, str.data);
+ str.data[str.len] = '\0';
}
}
}
string& operator=(string const& s)
{
- assign(s.c_str(), s.size());
+ if (this != &s)
+ assign(s.c_str(), s.size());
return *this;
}
string& operator=(std::string const& s)
}
// Capacity
- size_t size() const { return len; }
- size_t length() const { return len; }
- bool empty() const { return len != 0; }
+ size_t size() const { return str.len; }
+ size_t length() const { return str.len; }
+ bool empty() const { return str.len == 0; }
void shrink_to_fit() { /* Being there, but doing nothing */}
- // Alement access
- char* data() { return string_data::data; }
- const char* data() const { return string_data::data; }
- char* c_str() { return string_data::data; }
- const char* c_str() const { return string_data::data; };
+ // Element access
+ char* data() { return str.data; }
+ const char* data() const { return str.data; }
+ char* c_str() { return str.data; }
+ const char* c_str() const { return str.data; };
reference at(size_type i)
{
if (i >= size())
return data()[i];
}
// Conversion
- static string_data& to_string_data(string& s) { return s; }
+ static const string_data& to_string_data(const string& s) { return s.str; }
operator std::string() const { return std::string(this->c_str(), this->size()); }
// Iterators
// Operations
void clear()
{
- string_data::len = 0;
- string_data::data = &NUL;
+ str.len = 0;
+ str.data = &NUL;
+ }
+
+ size_t copy(char* s, size_t len, size_t pos = 0) const
+ {
+ if (pos > str.len)
+ throw std::out_of_range(string_printf("xbt::string::copy with pos > size() (%zu > %zu)", pos, str.len));
+ size_t count = std::min(len, str.len - pos);
+ std::copy_n(str.data + pos, count, s);
+ return count;
}
bool equals(const char* data, std::size_t len) const
typedef std::string string;
#endif
-
-/** Create a C++ string from a C-style format
- *
- * @ingroup XBT_str
-*/
-std::string string_printf(const char *fmt, ...);
-
-/** Create a C++ string from a C-style format
- *
- * @ingroup XBT_str
-*/
-std::string string_vprintf(const char *fmt, va_list ap);
-
}
}