// -*- 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 #include "support/strfwd.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