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