summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-11-22 15:04:30 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-12-05 10:09:58 +0900
commitcfb33650607791567274ee6f9029a9e2c0cb210d (patch)
tree95e9895fe418c0fc10b9bb69782a90948dbfe032
parentbe267a071ecb66f339e461f5b95b2e0fae40c98d (diff)
cxx: Add strbuf support
Comes in two fashions: - strbuf_view (read-only) - strbuf (read/write)
-rw-r--r--src/Makefile_Cxx.am1
-rw-r--r--src/bindings/cxx/eina_cxx/Eina.hh1
-rw-r--r--src/bindings/cxx/eina_cxx/eina_strbuf.hh384
3 files changed, 386 insertions, 0 deletions
diff --git a/src/Makefile_Cxx.am b/src/Makefile_Cxx.am
index 24978ddcf1..cf99ea3db3 100644
--- a/src/Makefile_Cxx.am
+++ b/src/Makefile_Cxx.am
@@ -151,6 +151,7 @@ bindings/cxx/eina_cxx/eina_ptrlist.hh \
151bindings/cxx/eina_cxx/eina_range_types.hh \ 151bindings/cxx/eina_cxx/eina_range_types.hh \
152bindings/cxx/eina_cxx/eina_ref.hh \ 152bindings/cxx/eina_cxx/eina_ref.hh \
153bindings/cxx/eina_cxx/eina_stringshare.hh \ 153bindings/cxx/eina_cxx/eina_stringshare.hh \
154bindings/cxx/eina_cxx/eina_strbuf.hh \
154bindings/cxx/eina_cxx/eina_string_view.hh \ 155bindings/cxx/eina_cxx/eina_string_view.hh \
155bindings/cxx/eina_cxx/eina_thread.hh \ 156bindings/cxx/eina_cxx/eina_thread.hh \
156bindings/cxx/eina_cxx/eina_throw.hh \ 157bindings/cxx/eina_cxx/eina_throw.hh \
diff --git a/src/bindings/cxx/eina_cxx/Eina.hh b/src/bindings/cxx/eina_cxx/Eina.hh
index de2f374f69..85226d4b53 100644
--- a/src/bindings/cxx/eina_cxx/Eina.hh
+++ b/src/bindings/cxx/eina_cxx/Eina.hh
@@ -14,6 +14,7 @@
14#include <eina_list.hh> 14#include <eina_list.hh>
15#include <eina_stringshare.hh> 15#include <eina_stringshare.hh>
16#include <eina_string_view.hh> 16#include <eina_string_view.hh>
17#include <eina_strbuf.hh>
17#include <eina_error.hh> 18#include <eina_error.hh>
18#include <eina_accessor.hh> 19#include <eina_accessor.hh>
19#include <eina_thread.hh> 20#include <eina_thread.hh>
diff --git a/src/bindings/cxx/eina_cxx/eina_strbuf.hh b/src/bindings/cxx/eina_cxx/eina_strbuf.hh
new file mode 100644
index 0000000000..c81a98f95d
--- /dev/null
+++ b/src/bindings/cxx/eina_cxx/eina_strbuf.hh
@@ -0,0 +1,384 @@
1#ifndef EINA_CXX_STRBUF_HH
2#define EINA_CXX_STRBUF_HH
3
4#include <Eina.h>
5#include <eina_type_traits.hh>
6#include <eina_throw.hh>
7#include <eina_error.hh>
8
9#include <cstring>
10
11// FIXME: Needs doc, I guess :)
12
13namespace efl { namespace eina {
14
15template <typename strbuf_type, typename basic_type>
16struct _strbuf_view_trait
17{
18 typedef basic_type value_type;
19 typedef value_type& reference;
20 typedef value_type* pointer;
21 typedef value_type const& const_reference;
22 typedef value_type const* const_pointer;
23 typedef const_pointer const_iterator;
24 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
25 typedef std::ptrdiff_t difference_type;
26 typedef std::size_t size_type;
27
28 _strbuf_view_trait() = delete;
29
30 /** Create a new view from another _strbuf_view_trait */
31 _strbuf_view_trait(_strbuf_view_trait const& other)
32 : _sb(other._sb)
33 {
34 }
35
36 /** Create a new view from an existing Eina_Strbuf */
37 _strbuf_view_trait(Eina_Strbuf const* sb)
38 : _sb(const_cast<Eina_Strbuf *>(sb))
39 {
40 }
41
42 /**
43 * @brief Tells whether this object contains a real Eina_Strbuf or not
44 * @return true if wrapping an Eina_Strbuf, false if contains nullptr.
45 */
46 bool empty() const
47 {
48 return (_sb != nullptr);
49 }
50
51 /**
52 * @brief Get the contained C string
53 * @return A C-style string (const char*)
54 */
55 const char * c_str() const
56 {
57 return ::eina_strbuf_string_get(_sb);
58 }
59
60 /**
61 * @brief Convert to a string
62 * @return A std::string copy
63 */
64 operator std::string() const
65 {
66 return std::string(c_str());
67 }
68
69 /**
70 * @brief Get the size of the string.
71 * @return Number of characters in the string.
72 */
73 size_type size() const
74 {
75 return eina_strbuf_length_get(_sb);
76 }
77
78 /**
79 * @brief Alias to @ref size() const.
80 */
81 size_type length() const
82 {
83 return size();
84 }
85
86 /**
87 * @brief Get a constant iterator pointing to the first character of the string.
88 * @return Constant iterator to the initial position of the string.
89 *
90 * This member function returns a constant iterator pointing to the
91 * first character of the string. If the string is empty the iterator
92 * is equal to the one returned by @ref end() const.
93 */
94 const_iterator begin() const
95 {
96 return ::eina_strbuf_string_get(_sb);
97 }
98
99 /**
100 * @brief Get a constant iterator to the position following the last character of the string.
101 * @return Constant iterator to the final position of the string.
102 *
103 * This member function returns an constant iterator to the position
104 * following the last character in the string. If the string is empty
105 * the iterator is equal to the one returned by @ref begin().
106 *
107 * @note Note that attempting to access this position causes undefined
108 * behavior.
109 */
110 const_iterator end() const
111 {
112 return begin() + size();
113 }
114
115 /**
116 * @brief Get a constant reverse iterator pointing to the reverse begin of the string.
117 * @return Constant reverse iterator pointing to the reverse begin of the string.
118 *
119 * This member function returns a constant reverse iterator pointing
120 * to the last character of the string. If the string is empty the
121 * returned reverse iterator is the same as the one returned by
122 * @ref rend() const.
123 */
124 const_reverse_iterator rbegin() const
125 {
126 return const_reverse_iterator(end());
127 }
128
129 /**
130 * @brief Get a constant reverse iterator pointing to the reverse end of the string.
131 * @return Constant reverse iterator pointing to the reverse end of the string.
132 *
133 * This member function returns a constant reverse iterator pointing
134 * to the position before the first character of the string. If the
135 * string is empty the returned iterator is the same as the one
136 * returned by @ref rbegin() const.
137 *
138 * @note Note that attempting to access this position causes undefined
139 * behavior.
140 */
141 const_reverse_iterator rend() const
142 {
143 return const_reverse_iterator(begin());
144 }
145
146 /**
147 * @brief Get a constant iterator to the position following the last character of the string.
148 * @return Constant iterator to the final position of the string.
149 *
150 * This member function works just like @ref end() const. But it is
151 * granted to always return a constant iterator.
152 */
153 const_iterator cend() const
154 {
155 return end();
156 }
157
158 /**
159 * @brief Get a constant reverse iterator pointing to the reverse begin of the string.
160 * @return Constant reverse iterator pointing to the reverse begin of the string.
161 *
162 * This member function works just like @ref rbegin() const. But it is
163 * granted to always return a constant reverse iterator.
164 */
165 const_reverse_iterator crbegin() const
166 {
167 return rbegin();
168 }
169
170 /**
171 * @brief Get a constant reverse iterator pointing to the reverse end of the string.
172 * @return Constant reverse iterator pointing to the reverse end of the string.
173 *
174 * This member function works just like @ref rend() const. But it is
175 * granted to always return a constant reverse iterator.
176 */
177 const_reverse_iterator crend() const
178 {
179 return rend();
180 }
181
182 /**
183 * @brief Get the maximum number of characters a string can hold.
184 * @return Maximum number of characters a string can hold.
185 */
186 size_type max_size() const
187 {
188 return static_cast<size_type>(-1);
189 }
190
191 typedef strbuf_type* native_handle_type;
192 native_handle_type native_handle() const
193 {
194 return _sb;
195 }
196
197protected:
198 strbuf_type *_sb;
199};
200
201
202/** A read-only view of an existing Eina_Strbuf. */
203typedef _strbuf_view_trait<const Eina_Strbuf, const char> strbuf_view;
204
205static struct _strbuf_empty_t {} _strbuf_empty;
206
207
208/** Allocates and manages an Eina_Strbuf, this is a mutable object. */
209struct strbuf : public _strbuf_view_trait<Eina_Strbuf, char>
210{
211 strbuf(const char *str = nullptr)
212 : _strbuf_view_trait(::eina_strbuf_new())
213 {
214 if (!_sb) EFL_CXX_THROW(std::make_error_code(std::errc::not_enough_memory));
215 eina_strbuf_append(_sb, str);
216 }
217
218 explicit strbuf(_strbuf_empty_t)
219 : _strbuf_view_trait(nullptr)
220 {
221 }
222
223 explicit strbuf(Eina_Strbuf* sb) = delete;
224
225 strbuf(Eina_Strbuf const* sb)
226 : strbuf(eina_strbuf_string_get(sb))
227 {
228 }
229
230 strbuf(Eina_Strbuf const& sb)
231 : strbuf(eina_strbuf_string_get(&sb))
232 {
233 }
234
235 strbuf(strbuf_view const& other)
236 : strbuf(other.native_handle())
237 {
238 }
239
240 strbuf(strbuf&& other)
241 : strbuf(_strbuf_empty)
242 {
243 swap(other);
244 }
245
246 template <typename S>
247 strbuf(S const& str)
248 : strbuf(std::string(str).c_str())
249 {
250 }
251
252 ~strbuf()
253 {
254 ::eina_strbuf_free(_sb);
255 }
256
257 void swap(strbuf& other)
258 {
259 std::swap(_sb, other._sb);
260 }
261
262 strbuf dup()
263 {
264 return strbuf(c_str());
265 }
266
267 strbuf& reset()
268 {
269 ::eina_strbuf_reset(_sb);
270 return *this;
271 }
272
273 template <typename S>
274 strbuf& append(S const& str)
275 {
276 ::eina_strbuf_append(_sb, std::string(str).c_str());
277 return *this;
278 }
279
280 template <typename S, typename... Args>
281 strbuf& append_printf(S const& fmt, Args... args)
282 {
283 ::eina_strbuf_append_printf(_sb, std::string(fmt).c_str(), args...);
284 return *this;
285 }
286
287 template <typename S, typename... Args>
288 strbuf& insert_printf(S const& fmt, size_t pos, Args... args)
289 {
290 ::eina_strbuf_insert_printf(_sb, std::string(fmt).c_str(), pos, args...);
291 return *this;
292 }
293
294 template <typename S>
295 strbuf& append_strftime(S const& fmt, struct tm const& time)
296 {
297 ::eina_strbuf_append_strftime(_sb, std::string(fmt).c_str(), &time);
298 return *this;
299 }
300
301 template <typename S, typename... Args>
302 strbuf& insert_strftime(S const& fmt, size_t pos, struct tm const& time)
303 {
304 ::eina_strbuf_insert_printf(_sb, std::string(fmt).c_str(), pos, time);
305 return *this;
306 }
307
308 strbuf& trim()
309 {
310 ::eina_strbuf_trim(_sb);
311 return *this;
312 }
313
314 strbuf& ltrim()
315 {
316 ::eina_strbuf_ltrim(_sb);
317 return *this;
318 }
319
320 strbuf& rtrim()
321 {
322 ::eina_strbuf_rtrim(_sb);
323 return *this;
324 }
325
326 // FIXME: add toupper!!
327 strbuf& tolower()
328 {
329 ::eina_strbuf_tolower(_sb);
330 return *this;
331 }
332
333 strbuf substr_get(size_t pos, size_t len)
334 {
335 strbuf sb(_strbuf_empty);
336 sb._sb = ::eina_strbuf_substr_get(_sb, pos, len);
337 return sb;
338 }
339
340 char * steal()
341 {
342 return ::eina_strbuf_string_steal(_sb);
343 }
344
345 template <typename S>
346 strbuf& operator=(S const& other)
347 {
348 return reset().append(other);
349 }
350
351 template <typename S>
352 strbuf& operator+=(S const& other)
353 {
354 return append(other);
355 }
356};
357
358
359/** A writeable Eina_Strbuf wrapper, does not allocate or destroy the Eina_Strbuf. */
360struct strbuf_wrapper : public strbuf
361{
362 strbuf_wrapper() = delete;
363 strbuf_wrapper(strbuf_view const& other) = delete;
364
365 explicit strbuf_wrapper(Eina_Strbuf* sb)
366 : strbuf(_strbuf_empty)
367 {
368 _sb = sb;
369 }
370
371 strbuf_wrapper(Eina_Strbuf& sb)
372 : strbuf_wrapper(&sb)
373 {
374 }
375
376 ~strbuf_wrapper()
377 {
378 _sb = nullptr;
379 }
380};
381
382} }
383
384#endif