4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
12 #ifndef LYX_TRIVSTRING_H
13 #define LYX_TRIVSTRING_H
15 #include "support/strfwd.h"
17 #ifdef STD_STRING_USES_COW
23 * Trivial string class with almost no features.
24 * The public interface is a subset of the std::basic_string interface.
25 * The only important feature is that any read-only access does not need
26 * synchronization between multiple threads, i.e. it is thread-safe without
28 * Therefore you can safely use a const trivial_string object in multiple
29 * threads at the same time. This is not the case for std::basic_string in some
30 * STL implementations (e. g. GNU libcstd++, see bug 9336 and
31 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21334.
32 * This class should not be used for anything else than providing thread-safety.
33 * It should be removed as soon as LyX requires C++11, and all supported STL
34 * implementations provide a C++11 conformant std::basic_string.
36 * If you change anything in this class please ensure that the unit test
37 * tests/check_trivstring.cpp still tests 100% of the public interface.
39 template <typename Char> class trivial_string
42 /// Construct an empty string
43 trivial_string() : size_(0), data_(0) {}
44 /// Construct a string from a copy of \p that
45 trivial_string(trivial_string const & that);
46 /// Construct a string from a copy of \p that
47 trivial_string(std::basic_string<Char, std::char_traits<Char>, std::allocator<Char> > const & that);
49 ~trivial_string() { if (!use_sso()) delete[] data_; }
50 /// Assign a copy of \p that
51 trivial_string & operator=(trivial_string const & that);
52 /// Assign a copy of \p that
53 trivial_string & operator=(std::basic_string<Char, std::char_traits<Char>, std::allocator<Char> > const & that);
54 /// Exchange contents with contents of \p that
55 void swap(trivial_string & that);
56 /// The length of the string, excluding the final 0 character
57 size_t length() const { return size_; }
58 /// Is this string empty?
59 bool empty() const { return size_ == 0; }
60 /// Is this string ordered before, at the same position or after \p other?
61 int compare(trivial_string const & other) const;
62 /// Create a copy as std::basic_string
63 operator std::basic_string<Char, std::char_traits<Char>, std::allocator<Char> >() const;
64 /// Return a C-compatible string, terminated by a 0 character.
65 /// This is never a copy and only valid for the life time of the trivial_string instance.
66 Char const * c_str() const;
69 * Whether short string optimization is used.
70 * Short string optimization is a technique where no additional memory
71 * needs to be allocated to store the string contents.
72 * Instead, the memory which would be used to store the pointer to the
73 * character buffer is reinterpreted to be a Char * buffer.
74 * On most 64 bit systems and with Char == char this allows to store
75 * strings of up to 7 characters without allocating additional memory.
77 bool use_sso() const { return (size_ + 1) * sizeof(Char) <= sizeof(Char *); }
78 /// The character storage if sso is used
79 Char * data_sso() { return reinterpret_cast<Char * >(&data_); }
80 /// The character storage if sso is used
81 Char const * data_sso() const { return reinterpret_cast<Char const *>(&data_); }
82 /// The length of the string, excluding the final 0 character
84 /// The character storage
89 /// Comparison operator (needed for std::set etc)
90 template <typename Char> bool operator<(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs);
94 template <typename Char> bool operator==(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs);
95 template <typename Char> bool operator==(trivial_string<Char> const & lhs, Char const * rhs);
96 template <typename Char> bool operator==(Char const * lhs, trivial_string<Char> const & rhs);
99 /// Stream output operator
100 template <typename Char>
101 std::basic_ostream<Char, std::char_traits<Char> > &
102 operator<<(std::basic_ostream<Char, std::char_traits<Char> > &, trivial_string<Char> const &);