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)
downloadefl-cfb33650607791567274ee6f9029a9e2c0cb210d.tar.gz
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 \
bindings/cxx/eina_cxx/eina_range_types.hh \
bindings/cxx/eina_cxx/eina_ref.hh \
bindings/cxx/eina_cxx/eina_stringshare.hh \
+bindings/cxx/eina_cxx/eina_strbuf.hh \
bindings/cxx/eina_cxx/eina_string_view.hh \
bindings/cxx/eina_cxx/eina_thread.hh \
bindings/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 @@
#include <eina_list.hh>
#include <eina_stringshare.hh>
#include <eina_string_view.hh>
+#include <eina_strbuf.hh>
#include <eina_error.hh>
#include <eina_accessor.hh>
#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 @@
+#ifndef EINA_CXX_STRBUF_HH
+#define EINA_CXX_STRBUF_HH
+
+#include <Eina.h>
+#include <eina_type_traits.hh>
+#include <eina_throw.hh>
+#include <eina_error.hh>
+
+#include <cstring>
+
+// FIXME: Needs doc, I guess :)
+
+namespace efl { namespace eina {
+
+template <typename strbuf_type, typename basic_type>
+struct _strbuf_view_trait
+{
+ typedef basic_type value_type;
+ typedef value_type& reference;
+ typedef value_type* pointer;
+ typedef value_type const& const_reference;
+ typedef value_type const* const_pointer;
+ typedef const_pointer const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::size_t size_type;
+
+ _strbuf_view_trait() = delete;
+
+ /** Create a new view from another _strbuf_view_trait */
+ _strbuf_view_trait(_strbuf_view_trait const& other)
+ : _sb(other._sb)
+ {
+ }
+
+ /** Create a new view from an existing Eina_Strbuf */
+ _strbuf_view_trait(Eina_Strbuf const* sb)
+ : _sb(const_cast<Eina_Strbuf *>(sb))
+ {
+ }
+
+ /**
+ * @brief Tells whether this object contains a real Eina_Strbuf or not
+ * @return true if wrapping an Eina_Strbuf, false if contains nullptr.
+ */
+ bool empty() const
+ {
+ return (_sb != nullptr);
+ }
+
+ /**
+ * @brief Get the contained C string
+ * @return A C-style string (const char*)
+ */
+ const char * c_str() const
+ {
+ return ::eina_strbuf_string_get(_sb);
+ }
+
+ /**
+ * @brief Convert to a string
+ * @return A std::string copy
+ */
+ operator std::string() const
+ {
+ return std::string(c_str());
+ }
+
+ /**
+ * @brief Get the size of the string.
+ * @return Number of characters in the string.
+ */
+ size_type size() const
+ {
+ return eina_strbuf_length_get(_sb);
+ }
+
+ /**
+ * @brief Alias to @ref size() const.
+ */
+ size_type length() const
+ {
+ return size();
+ }
+
+ /**
+ * @brief Get a constant iterator pointing to the first character of the string.
+ * @return Constant iterator to the initial position of the string.
+ *
+ * This member function returns a constant iterator pointing to the
+ * first character of the string. If the string is empty the iterator
+ * is equal to the one returned by @ref end() const.
+ */
+ const_iterator begin() const
+ {
+ return ::eina_strbuf_string_get(_sb);
+ }
+
+ /**
+ * @brief Get a constant iterator to the position following the last character of the string.
+ * @return Constant iterator to the final position of the string.
+ *
+ * This member function returns an constant iterator to the position
+ * following the last character in the string. If the string is empty
+ * the iterator is equal to the one returned by @ref begin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
+ const_iterator end() const
+ {
+ return begin() + size();
+ }
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the string.
+ * @return Constant reverse iterator pointing to the reverse begin of the string.
+ *
+ * This member function returns a constant reverse iterator pointing
+ * to the last character of the string. If the string is empty the
+ * returned reverse iterator is the same as the one returned by
+ * @ref rend() const.
+ */
+ const_reverse_iterator rbegin() const
+ {
+ return const_reverse_iterator(end());
+ }
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the string.
+ * @return Constant reverse iterator pointing to the reverse end of the string.
+ *
+ * This member function returns a constant reverse iterator pointing
+ * to the position before the first character of the string. If the
+ * string is empty the returned iterator is the same as the one
+ * returned by @ref rbegin() const.
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
+ const_reverse_iterator rend() const
+ {
+ return const_reverse_iterator(begin());
+ }
+
+ /**
+ * @brief Get a constant iterator to the position following the last character of the string.
+ * @return Constant iterator to the final position of the string.
+ *
+ * This member function works just like @ref end() const. But it is
+ * granted to always return a constant iterator.
+ */
+ const_iterator cend() const
+ {
+ return end();
+ }
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the string.
+ * @return Constant reverse iterator pointing to the reverse begin of the string.
+ *
+ * This member function works just like @ref rbegin() const. But it is
+ * granted to always return a constant reverse iterator.
+ */
+ const_reverse_iterator crbegin() const
+ {
+ return rbegin();
+ }
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the string.
+ * @return Constant reverse iterator pointing to the reverse end of the string.
+ *
+ * This member function works just like @ref rend() const. But it is
+ * granted to always return a constant reverse iterator.
+ */
+ const_reverse_iterator crend() const
+ {
+ return rend();
+ }
+
+ /**
+ * @brief Get the maximum number of characters a string can hold.
+ * @return Maximum number of characters a string can hold.
+ */
+ size_type max_size() const
+ {
+ return static_cast<size_type>(-1);
+ }
+
+ typedef strbuf_type* native_handle_type;
+ native_handle_type native_handle() const
+ {
+ return _sb;
+ }
+
+protected:
+ strbuf_type *_sb;
+};
+
+
+/** A read-only view of an existing Eina_Strbuf. */
+typedef _strbuf_view_trait<const Eina_Strbuf, const char> strbuf_view;
+
+static struct _strbuf_empty_t {} _strbuf_empty;
+
+
+/** Allocates and manages an Eina_Strbuf, this is a mutable object. */
+struct strbuf : public _strbuf_view_trait<Eina_Strbuf, char>
+{
+ strbuf(const char *str = nullptr)
+ : _strbuf_view_trait(::eina_strbuf_new())
+ {
+ if (!_sb) EFL_CXX_THROW(std::make_error_code(std::errc::not_enough_memory));
+ eina_strbuf_append(_sb, str);
+ }
+
+ explicit strbuf(_strbuf_empty_t)
+ : _strbuf_view_trait(nullptr)
+ {
+ }
+
+ explicit strbuf(Eina_Strbuf* sb) = delete;
+
+ strbuf(Eina_Strbuf const* sb)
+ : strbuf(eina_strbuf_string_get(sb))
+ {
+ }
+
+ strbuf(Eina_Strbuf const& sb)
+ : strbuf(eina_strbuf_string_get(&sb))
+ {
+ }
+
+ strbuf(strbuf_view const& other)
+ : strbuf(other.native_handle())
+ {
+ }
+
+ strbuf(strbuf&& other)
+ : strbuf(_strbuf_empty)
+ {
+ swap(other);
+ }
+
+ template <typename S>
+ strbuf(S const& str)
+ : strbuf(std::string(str).c_str())
+ {
+ }
+
+ ~strbuf()
+ {
+ ::eina_strbuf_free(_sb);
+ }
+
+ void swap(strbuf& other)
+ {
+ std::swap(_sb, other._sb);
+ }
+
+ strbuf dup()
+ {
+ return strbuf(c_str());
+ }
+
+ strbuf& reset()
+ {
+ ::eina_strbuf_reset(_sb);
+ return *this;
+ }
+
+ template <typename S>
+ strbuf& append(S const& str)
+ {
+ ::eina_strbuf_append(_sb, std::string(str).c_str());
+ return *this;
+ }
+
+ template <typename S, typename... Args>
+ strbuf& append_printf(S const& fmt, Args... args)
+ {
+ ::eina_strbuf_append_printf(_sb, std::string(fmt).c_str(), args...);
+ return *this;
+ }
+
+ template <typename S, typename... Args>
+ strbuf& insert_printf(S const& fmt, size_t pos, Args... args)
+ {
+ ::eina_strbuf_insert_printf(_sb, std::string(fmt).c_str(), pos, args...);
+ return *this;
+ }
+
+ template <typename S>
+ strbuf& append_strftime(S const& fmt, struct tm const& time)
+ {
+ ::eina_strbuf_append_strftime(_sb, std::string(fmt).c_str(), &time);
+ return *this;
+ }
+
+ template <typename S, typename... Args>
+ strbuf& insert_strftime(S const& fmt, size_t pos, struct tm const& time)
+ {
+ ::eina_strbuf_insert_printf(_sb, std::string(fmt).c_str(), pos, time);
+ return *this;
+ }
+
+ strbuf& trim()
+ {
+ ::eina_strbuf_trim(_sb);
+ return *this;
+ }
+
+ strbuf& ltrim()
+ {
+ ::eina_strbuf_ltrim(_sb);
+ return *this;
+ }
+
+ strbuf& rtrim()
+ {
+ ::eina_strbuf_rtrim(_sb);
+ return *this;
+ }
+
+ // FIXME: add toupper!!
+ strbuf& tolower()
+ {
+ ::eina_strbuf_tolower(_sb);
+ return *this;
+ }
+
+ strbuf substr_get(size_t pos, size_t len)
+ {
+ strbuf sb(_strbuf_empty);
+ sb._sb = ::eina_strbuf_substr_get(_sb, pos, len);
+ return sb;
+ }
+
+ char * steal()
+ {
+ return ::eina_strbuf_string_steal(_sb);
+ }
+
+ template <typename S>
+ strbuf& operator=(S const& other)
+ {
+ return reset().append(other);
+ }
+
+ template <typename S>
+ strbuf& operator+=(S const& other)
+ {
+ return append(other);
+ }
+};
+
+
+/** A writeable Eina_Strbuf wrapper, does not allocate or destroy the Eina_Strbuf. */
+struct strbuf_wrapper : public strbuf
+{
+ strbuf_wrapper() = delete;
+ strbuf_wrapper(strbuf_view const& other) = delete;
+
+ explicit strbuf_wrapper(Eina_Strbuf* sb)
+ : strbuf(_strbuf_empty)
+ {
+ _sb = sb;
+ }
+
+ strbuf_wrapper(Eina_Strbuf& sb)
+ : strbuf_wrapper(&sb)
+ {
+ }
+
+ ~strbuf_wrapper()
+ {
+ _sb = nullptr;
+ }
+};
+
+} }
+
+#endif