+++ /dev/null
-/**
- * \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 <config.h>
-
-#include "support/trivstring.h"
-#include "support/docstring.h"
-
-#ifdef STD_STRING_USES_COW
-#include <algorithm>
-#include <stdexcept>
-
-using namespace std;
-
-namespace lyx {
-
-template trivial_string<char>::trivial_string(trivial_string const &);
-template trivial_string<char_type>::trivial_string(trivial_string const &);
-template<typename Char>
-trivial_string<Char>::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<typename Char>
-trivial_string<Char>::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<char>::trivial_string(string const &);
-template trivial_string<char_type>::trivial_string(docstring const &);
-template<typename Char>
-trivial_string<Char>::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<char> &
-trivial_string<char>::operator=(trivial_string const &);
-template trivial_string<char_type> &
-trivial_string<char_type>::operator=(trivial_string const &);
-template<typename Char>
-trivial_string<Char> & trivial_string<Char>::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<char> &
-trivial_string<char>::operator=(string const &);
-template trivial_string<char_type> &
-trivial_string<char_type>::operator=(docstring const &);
-template<typename Char>
-trivial_string<Char> &
-trivial_string<Char>::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<char>::swap(trivial_string<char> &);
-template void
-trivial_string<char_type>::swap(trivial_string<char_type> &);
-template<typename Char>
-void trivial_string<Char>::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<typename Char>
-int trivial_string<Char>::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<Char>::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<char> trivial_string<char>::substr(size_t, size_t) const;
-template trivial_string<char_type> trivial_string<char_type>::substr(size_t, size_t) const;
-template<typename Char>
-trivial_string<Char> trivial_string<Char>::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<char>::operator string() const;
-template trivial_string<char_type>::operator docstring() const;
-template<typename Char>
-trivial_string<Char>::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<char>::c_str() const;
-template char_type const * trivial_string<char_type>::c_str() const;
-template<typename Char> Char const * trivial_string<Char>::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<char>::operator[](size_t) const;
-template char_type trivial_string<char_type>::operator[](size_t) const;
-template <typename Char> Char trivial_string<Char>::operator[](size_t i) const
-{
- return c_str()[i];
-}
-
-
-template bool operator<(trivial_string<char> const &,
- trivial_string<char> const &);
-template bool operator<(trivial_string<char_type> const &,
- trivial_string<char_type> const &);
-template <typename Char>
-bool operator<(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs)
-{
- return lhs.compare(rhs) < 0;
-}
-
-
-template bool operator==(trivial_string<char> const &,
- trivial_string<char> const &);
-template bool operator==(trivial_string<char_type> const &,
- trivial_string<char_type> const &);
-template <typename Char>
-bool operator==(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs)
-{
- return lhs.compare(rhs) == 0;
-}
-
-
-template bool operator==(trivial_string<char> const &, char const *);
-template bool operator==(trivial_string<char_type> const &, char_type const *);
-template <typename Char>
-bool operator==(trivial_string<Char> const & lhs, Char const * rhs)
-{
- return lhs.compare(trivial_string<Char>(rhs)) == 0;
-}
-
-
-template bool operator==(char const *, trivial_string<char> const &);
-template bool operator==(char_type const *, trivial_string<char_type> const &);
-template <typename Char>
-bool operator==(Char const * lhs, trivial_string<Char> const & rhs)
-{
- return rhs.compare(trivial_string<Char>(lhs)) == 0;
-}
-
-
-template ostream & operator<<(ostream &, trivial_string<char> const &);
-template odocstream & operator<<(odocstream &, trivial_string<char_type> const &);
-template <typename Char>
-basic_ostream<Char, char_traits<Char> > &
-operator<<(basic_ostream<Char, char_traits<Char> > & os, trivial_string<Char> const & s)
-{
- return os << basic_string<Char, char_traits<Char>, allocator<Char> >(s);
-}
-
-} // namespace lyx
-#endif
+++ /dev/null
-// -*- 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 <cstdlib>
-
-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 <typename Char> class trivial_string
-{
-public:
- /// Corresponding std::basic_string
- typedef std::basic_string<Char, std::char_traits<Char>, std::allocator<Char> > _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<Char * >(&data_); }
- /// The character storage if sso is used
- Char const * data_sso() const { return reinterpret_cast<Char const *>(&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 <typename Char> bool operator<(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs);
-
-
-/// Equality operator
-template <typename Char> bool operator==(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs);
-template <typename Char> bool operator==(trivial_string<Char> const & lhs, Char const * rhs);
-template <typename Char> bool operator==(Char const * lhs, trivial_string<Char> const & rhs);
-
-
-/// Stream output operator
-template <typename Char>
-std::basic_ostream<Char, std::char_traits<Char> > &
-operator<<(std::basic_ostream<Char, std::char_traits<Char> > &, trivial_string<Char> const &);
-
-} // namespace lyx
-#else
-#include <string>
-#endif
-#endif