From b8f1f113f31d6ce0c3a4878eafa2f254756af577 Mon Sep 17 00:00:00 2001 From: Pavel Sanda Date: Fri, 4 Oct 2024 20:49:55 +0200 Subject: [PATCH] Remove trivstring. Needed in times when std:string was not thread-safe, but should be ok nowadays. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21334 https://www.mail-archive.com/lyx-devel@lists.lyx.org/msg223068.html --- src/Encoding.h | 1 - src/Language.h | 1 - src/support/Makefile.am | 2 - src/support/docstring.h | 9 +- src/support/tests/check_trivstring.cpp | 1 - src/support/trivstring.cpp | 261 ------------------------- src/support/trivstring.h | 114 ----------- 7 files changed, 3 insertions(+), 386 deletions(-) delete mode 100644 src/support/trivstring.cpp delete mode 100644 src/support/trivstring.h diff --git a/src/Encoding.h b/src/Encoding.h index 297650c847..b097d7f44b 100644 --- a/src/Encoding.h +++ b/src/Encoding.h @@ -14,7 +14,6 @@ #define ENCODING_H #include "support/docstring.h" -#include "support/trivstring.h" #include "support/types.h" #include diff --git a/src/Language.h b/src/Language.h index ddd6edf7c2..56e324a359 100644 --- a/src/Language.h +++ b/src/Language.h @@ -16,7 +16,6 @@ #define LANGUAGE_H #include "support/docstring.h" -#include "support/trivstring.h" #include #include diff --git a/src/support/Makefile.am b/src/support/Makefile.am index 2122cc4a42..4ff0ebd2cb 100644 --- a/src/support/Makefile.am +++ b/src/support/Makefile.am @@ -115,8 +115,6 @@ liblyxsupport_a_SOURCES = \ Translator.h \ Timeout.cpp \ Timeout.h \ - trivstring.cpp \ - trivstring.h \ types.h \ unique_ptr.h \ userinfo.cpp \ diff --git a/src/support/docstring.h b/src/support/docstring.h index 2a760eacee..40806e1f40 100644 --- a/src/support/docstring.h +++ b/src/support/docstring.h @@ -65,14 +65,11 @@ std::string const & empty_string(); // defined in docstring.cpp bool operator==(docstring const &, char const *); -#ifdef STD_STRING_USES_COW -template class trivial_string; -typedef trivial_string trivstring; -typedef trivial_string trivdocstring; -#else +//trivstring signalizes thread-safety request; should not be needed for any +//C++11 conformant std::basic_string, e.g. GCC >= 5. +//Once properly tested we can ditch these two in favour of std::string/docstring. typedef std::string trivstring; typedef docstring trivdocstring; -#endif } // namespace lyx diff --git a/src/support/tests/check_trivstring.cpp b/src/support/tests/check_trivstring.cpp index 1b604657f4..844164510d 100644 --- a/src/support/tests/check_trivstring.cpp +++ b/src/support/tests/check_trivstring.cpp @@ -1,6 +1,5 @@ #include -#include "../trivstring.h" #include "../docstring.h" #include diff --git a/src/support/trivstring.cpp b/src/support/trivstring.cpp deleted file mode 100644 index c5102526a8..0000000000 --- a/src/support/trivstring.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/** - * \file trivstring.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Georg Baum - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "support/trivstring.h" -#include "support/docstring.h" - -#ifdef STD_STRING_USES_COW -#include -#include - -using namespace std; - -namespace lyx { - -template trivial_string::trivial_string(trivial_string const &); -template trivial_string::trivial_string(trivial_string const &); -template -trivial_string::trivial_string(trivial_string const & that) : size_(that.size_) -{ - if (use_sso()) - copy(that.data_sso(), that.data_sso() + size_ + 1, data_sso()); - else if (size_ > 0) { - data_ = new Char[size_ + 1]; - copy(that.data_, that.data_ + size_ + 1, data_); - } else { - // Happens only for really big Char types - data_ = 0; - } -} - - -template -trivial_string::trivial_string(Char const * that, size_t n) : size_(n) -{ - if (use_sso()) { - copy(that, that + size_, data_sso()); - data_sso()[size_] = '\0'; - } else if (size_ > 0) { - data_ = new Char[size_ + 1]; - copy(that, that + size_, data_); - data_[size_] = '\0'; - } else { - // Happens only for really big Char types - data_ = 0; - } -} - - -template trivial_string::trivial_string(string const &); -template trivial_string::trivial_string(docstring const &); -template -trivial_string::trivial_string(_stdstring const & that) - : size_(that.length()) -{ - if (use_sso()) { - copy(that.begin(), that.end(), data_sso()); - data_sso()[size_] = '\0'; - } else if (size_ > 0) { - data_ = new Char[size_ + 1]; - copy(that.begin(), that.end(), data_); - data_[size_] = '\0'; - } else { - // Happens only for really big Char types - data_ = 0; - } -} - - -template trivial_string & -trivial_string::operator=(trivial_string const &); -template trivial_string & -trivial_string::operator=(trivial_string const &); -template -trivial_string & trivial_string::operator=(trivial_string const & that) -{ - if (&that == this) - return *this; - if (!use_sso()) - delete[] data_; - size_ = that.size_; - if (use_sso()) - copy(that.data_sso(), that.data_sso() + size_ + 1, data_sso()); - else if (size_ > 0) { - data_ = new Char[size_ + 1]; - copy(that.data_, that.data_ + size_ + 1, data_); - } else { - // Happens only for really big Char types - data_ = 0; - } - return *this; -} - - -template trivial_string & -trivial_string::operator=(string const &); -template trivial_string & -trivial_string::operator=(docstring const &); -template -trivial_string & -trivial_string::operator=(_stdstring const & that) -{ - if (!use_sso()) - delete[] data_; - size_ = that.size(); - if (use_sso()) { - copy(that.begin(), that.end(), data_sso()); - data_sso()[size_] = '\0'; - } else if (size_ > 0) { - data_ = new Char[size_ + 1]; - copy(that.begin(), that.end(), data_); - } else { - // Happens only for really big Char types - data_ = 0; - } - return *this; -} - - -template void -trivial_string::swap(trivial_string &); -template void -trivial_string::swap(trivial_string &); -template -void trivial_string::swap(trivial_string & that) -{ - size_t const sizetmp = that.size_; - that.size_ = size_; - size_ = sizetmp; - Char * const datatmp = that.data_; - that.data_ = data_; - data_ = datatmp; -} - - -template -int trivial_string::compare(trivial_string const & other) const -{ - size_t const lsize = this->length(); - size_t const rsize = other.length(); - size_t const len = min(lsize, rsize); - int r = char_traits::compare(c_str(), other.c_str(), len); - if (r == 0) { - if (lsize > rsize) - r = 1; - else if (lsize < rsize) - r = -1; - } - return r; -} - - -template trivial_string trivial_string::substr(size_t, size_t) const; -template trivial_string trivial_string::substr(size_t, size_t) const; -template -trivial_string trivial_string::substr(size_t pos, size_t n) const -{ - if (pos > length()) - throw out_of_range("trivial_string::substr"); - if (n == _stdstring::npos) - n = length() - pos; - size_t const l = min(pos + n, length()); - return trivial_string(c_str() + pos, l - pos); -} - - -template trivial_string::operator string() const; -template trivial_string::operator docstring() const; -template -trivial_string::operator _stdstring() const -{ - if (use_sso()) - return _stdstring(data_sso(), size_); - if (size_ > 0) - return _stdstring(data_, size_); - // Happens only for really big Char types - return _stdstring(); -} - - -template char const * trivial_string::c_str() const; -template char_type const * trivial_string::c_str() const; -template Char const * trivial_string::c_str() const -{ - if (use_sso()) - return data_sso(); - if (size_ > 0) - return data_; - // Happens only for really big Char types - static const Char empty_char = '\0'; - return &empty_char; -} - - -template char trivial_string::operator[](size_t) const; -template char_type trivial_string::operator[](size_t) const; -template Char trivial_string::operator[](size_t i) const -{ - return c_str()[i]; -} - - -template bool operator<(trivial_string const &, - trivial_string const &); -template bool operator<(trivial_string const &, - trivial_string const &); -template -bool operator<(trivial_string const & lhs, trivial_string const & rhs) -{ - return lhs.compare(rhs) < 0; -} - - -template bool operator==(trivial_string const &, - trivial_string const &); -template bool operator==(trivial_string const &, - trivial_string const &); -template -bool operator==(trivial_string const & lhs, trivial_string const & rhs) -{ - return lhs.compare(rhs) == 0; -} - - -template bool operator==(trivial_string const &, char const *); -template bool operator==(trivial_string const &, char_type const *); -template -bool operator==(trivial_string const & lhs, Char const * rhs) -{ - return lhs.compare(trivial_string(rhs)) == 0; -} - - -template bool operator==(char const *, trivial_string const &); -template bool operator==(char_type const *, trivial_string const &); -template -bool operator==(Char const * lhs, trivial_string const & rhs) -{ - return rhs.compare(trivial_string(lhs)) == 0; -} - - -template ostream & operator<<(ostream &, trivial_string const &); -template odocstream & operator<<(odocstream &, trivial_string const &); -template -basic_ostream > & -operator<<(basic_ostream > & os, trivial_string const & s) -{ - return os << basic_string, allocator >(s); -} - -} // namespace lyx -#endif diff --git a/src/support/trivstring.h b/src/support/trivstring.h deleted file mode 100644 index 3b47f6dc85..0000000000 --- a/src/support/trivstring.h +++ /dev/null @@ -1,114 +0,0 @@ -// -*- C++ -*- -/** - * \file trivstring.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Georg Baum - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef LYX_TRIVSTRING_H -#define LYX_TRIVSTRING_H - -#ifdef STD_STRING_USES_COW -#include - -namespace lyx { - -/** - * Trivial string class with almost no features. - * The public interface is a subset of the std::basic_string interface. - * The only important feature is that any read-only access does not need - * synchronization between multiple threads, i.e. it is thread-safe without - * locking. - * Therefore you can safely use a const trivial_string object in multiple - * threads at the same time. This is not the case for std::basic_string in some - * STL implementations (e. g. GNU libcstd++, see bug 9336 and - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21334. - * This class should not be used for anything else than providing thread-safety. - * It should be removed as soon as LyX requires C++11, and all supported STL - * implementations provide a C++11 conformant std::basic_string. - * - * If you change anything in this class please ensure that the unit test - * tests/check_trivstring.cpp still tests 100% of the public interface. - */ -template class trivial_string -{ -public: - /// Corresponding std::basic_string - typedef std::basic_string, std::allocator > _stdstring; - /// Construct an empty string - trivial_string() : size_(0), data_(0) {} - /// Construct a string from a copy of \p that - trivial_string(trivial_string const & that); - /// Construct a string from a copy of \p that - trivial_string(Char const * that, size_t n); - /// Construct a string from a copy of \p that - trivial_string(_stdstring const & that); - /// - ~trivial_string() { if (!use_sso()) delete[] data_; } - /// Assign a copy of \p that - trivial_string & operator=(trivial_string const & that); - /// Assign a copy of \p that - trivial_string & operator=(_stdstring const & that); - /// Exchange contents with contents of \p that - void swap(trivial_string & that); - /// The length of the string, excluding the final 0 character - size_t length() const { return size_; } - /// Is this string empty? - bool empty() const { return size_ == 0; } - /// Is this string ordered before, at the same position or after \p other? - int compare(trivial_string const & other) const; - /// Return substring of length \p n starting at \p pos - trivial_string substr(size_t pos = 0, size_t n = _stdstring::npos) const; - /// Create a copy as std::basic_string - operator _stdstring() const; - /// Return a C-compatible string, terminated by a 0 character. - /// This is never a copy and only valid for the life time of the trivial_string instance. - Char const * c_str() const; - /// Return character at position \p i (validity of \i is not checked) - Char operator[](size_t i) const; -private: - /** - * Whether short string optimization is used. - * Short string optimization is a technique where no additional memory - * needs to be allocated to store the string contents. - * Instead, the memory which would be used to store the pointer to the - * character buffer is reinterpreted to be a Char * buffer. - * On most 64 bit systems and with Char == char this allows to store - * strings of up to 7 characters without allocating additional memory. - */ - bool use_sso() const { return (size_ + 1) * sizeof(Char) <= sizeof(Char *); } - /// The character storage if sso is used - Char * data_sso() { return reinterpret_cast(&data_); } - /// The character storage if sso is used - Char const * data_sso() const { return reinterpret_cast(&data_); } - /// The length of the string, excluding the final 0 character - size_t size_; - /// The character storage - Char * data_; -}; - - -/// Comparison operator (needed for std::set etc) -template bool operator<(trivial_string const & lhs, trivial_string const & rhs); - - -/// Equality operator -template bool operator==(trivial_string const & lhs, trivial_string const & rhs); -template bool operator==(trivial_string const & lhs, Char const * rhs); -template bool operator==(Char const * lhs, trivial_string const & rhs); - - -/// Stream output operator -template -std::basic_ostream > & -operator<<(std::basic_ostream > &, trivial_string const &); - -} // namespace lyx -#else -#include -#endif -#endif -- 2.39.5