]> git.lyx.org Git - features.git/blob - src/support/trivstring.cpp
Make trivstring class ready for use
[features.git] / src / support / trivstring.cpp
1 /**
2  * \file trivstring.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Georg Baum
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "support/trivstring.h"
14 #include "support/docstring.h"
15
16 #ifdef STD_STRING_USES_COW
17 #include <algorithm>
18
19 using namespace std;
20
21 namespace lyx {
22
23 template trivial_string<char>::trivial_string(trivial_string const &);
24 template trivial_string<char_type>::trivial_string(trivial_string const &);
25 template<typename Char>
26 trivial_string<Char>::trivial_string(trivial_string const & that) : size_(that.size_)
27 {
28         if (use_sso())
29                 copy(that.data_sso(), that.data_sso() + size_ + 1, data_sso());
30         else if (size_ > 0) {
31                 data_ = new Char[size_ + 1];
32                 copy(that.data_, that.data_ + size_ + 1, data_);
33         }
34         // else Happens only for really big Char types
35 }
36
37
38 template trivial_string<char>::trivial_string(string const &);
39 template trivial_string<char_type>::trivial_string(docstring const &);
40 template<typename Char>
41 trivial_string<Char>::trivial_string(
42                 basic_string<Char, char_traits<Char>, allocator<Char> > const & that)
43         : size_(that.length())
44 {
45         if (use_sso()) {
46                 copy(that.begin(), that.end(), data_sso());
47                 data_sso()[size_] = '\0';
48         } else if (size_ > 0) {
49                 data_ = new Char[size_ + 1];
50                 copy(that.begin(), that.end(), data_);
51                 data_[size_] = '\0';
52         }
53         // else Happens only for really big Char types
54 }
55
56
57 template trivial_string<char> &
58 trivial_string<char>::operator=(trivial_string const &);
59 template trivial_string<char_type> &
60 trivial_string<char_type>::operator=(trivial_string const &);
61 template<typename Char>
62 trivial_string<Char> & trivial_string<Char>::operator=(trivial_string const & that)
63 {
64         if (&that == this)
65                 return *this;
66         if (!use_sso())
67                 delete[] data_;
68         size_ = that.size_;
69         if (use_sso())
70                 copy(that.data_sso(), that.data_sso() + size_ + 1, data_sso());
71         else if (size_ > 0) {
72                 data_ = new Char[size_ + 1];
73                 copy(that.data_, that.data_ + size_ + 1, data_);
74         } else {
75                 // Happens only for really big Char types
76                 data_ = 0;
77         }
78         return *this;
79 }
80
81
82 template trivial_string<char> &
83 trivial_string<char>::operator=(string const &);
84 template trivial_string<char_type> &
85 trivial_string<char_type>::operator=(docstring const &);
86 template<typename Char>
87 trivial_string<Char> &
88 trivial_string<Char>::operator=(basic_string<Char, char_traits<Char>, allocator<Char> > const & that)
89 {
90         if (!use_sso())
91                 delete[] data_;
92         size_ = that.size();
93         if (use_sso()) {
94                 copy(that.begin(), that.end(), data_sso());
95                 data_sso()[size_] = '\0';
96         } else if (size_ > 0) {
97                 data_ = new Char[size_ + 1];
98                 copy(that.begin(), that.end(), data_);
99         } else {
100                 // Happens only for really big Char types
101                 data_ = 0;
102         }
103         return *this;
104 }
105
106
107 template void
108 trivial_string<char>::swap(trivial_string<char> &);
109 template void
110 trivial_string<char_type>::swap(trivial_string<char_type> &);
111 template<typename Char>
112 void trivial_string<Char>::swap(trivial_string & that)
113 {
114         size_t const sizetmp = that.size_;
115         that.size_ = size_;
116         size_ = sizetmp;
117         Char * const datatmp = that.data_;
118         that.data_ = data_;
119         data_ = datatmp;
120 }
121
122
123 template<typename Char>
124 int trivial_string<Char>::compare(trivial_string const & other) const
125 {
126         size_t const lsize = this->length();
127         size_t const rsize = other.length();
128         size_t const len = min(lsize, rsize);
129         int r = char_traits<Char>::compare(c_str(), other.c_str(), len);
130         if (r == 0) {
131                 if (lsize > rsize)
132                         r = 1;
133                 else if (lsize < rsize)
134                         r = -1;
135         }
136         return r;
137 }
138
139
140 template trivial_string<char>::operator string() const;
141 template trivial_string<char_type>::operator docstring() const;
142 template<typename Char>
143 trivial_string<Char>::operator basic_string<Char, char_traits<Char>, allocator<Char> >() const
144 {
145         if (use_sso())
146                 return basic_string<Char, char_traits<Char>, allocator<Char> >(
147                                 data_sso(), size_);
148         if (size_ > 0)
149                 return basic_string<Char, char_traits<Char>, allocator<Char> >(
150                                 data_, size_);
151         // Happens only for really big Char types
152         return basic_string<Char, char_traits<Char>, allocator<Char> >();
153 }
154
155
156 template char const * trivial_string<char>::c_str() const;
157 template char_type const * trivial_string<char_type>::c_str() const;
158 template<typename Char> Char const * trivial_string<Char>::c_str() const
159 {
160         if (use_sso())
161                 return data_sso();
162         if (size_ > 0)
163                 return data_;
164         // Happens only for really big Char types
165         static const Char empty_char = '\0';
166         return &empty_char;
167 }
168
169
170 template bool operator<(trivial_string<char> const &,
171                         trivial_string<char> const &);
172 template bool operator<(trivial_string<char_type> const &,
173                         trivial_string<char_type> const &);
174 template <typename Char>
175 bool operator<(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs)
176 {
177         return lhs.compare(rhs) < 0;
178 }
179
180
181 template bool operator==(trivial_string<char> const &,
182                          trivial_string<char> const &);
183 template bool operator==(trivial_string<char_type> const &,
184                          trivial_string<char_type> const &);
185 template <typename Char>
186 bool operator==(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs)
187 {
188         return lhs.compare(rhs) == 0; 
189 }
190
191
192 template bool operator==(trivial_string<char> const &, char const *);
193 template bool operator==(trivial_string<char_type> const &, char_type const *);
194 template <typename Char>
195 bool operator==(trivial_string<Char> const & lhs, Char const * rhs)
196 {
197         return lhs.compare(trivial_string<Char>(rhs)) == 0; 
198 }
199
200
201 template bool operator==(char const *, trivial_string<char> const &);
202 template bool operator==(char_type const *, trivial_string<char_type> const &);
203 template <typename Char>
204 bool operator==(Char const * lhs, trivial_string<Char> const & rhs)
205 {
206         return rhs.compare(trivial_string<Char>(lhs)) == 0; 
207 }
208
209
210 template ostream & operator<<(ostream &, trivial_string<char> const &);
211 template odocstream & operator<<(odocstream &, trivial_string<char_type> const &);
212 template <typename Char>
213 basic_ostream<Char, char_traits<Char> > &
214 operator<<(basic_ostream<Char, char_traits<Char> > & os, trivial_string<Char> const & s)
215 {
216         return os << basic_string<Char, char_traits<Char>, allocator<Char> >(s);
217 }
218
219 } // namespace lyx
220 #endif