#ifndef _EINA_STRINGSHARE_HH #define _EINA_STRINGSHARE_HH #include #include #include #include namespace efl { namespace eina { struct steal_stringshare_ref_t {}; steal_stringshare_ref_t const steal_stringshare_ref = {}; struct stringshare { typedef char value_type; typedef value_type& reference; typedef value_type const& const_reference; typedef value_type* pointer; typedef value_type const* const_pointer; typedef const_pointer const_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef std::ptrdiff_t difference_type; typedef std::size_t size_type; stringshare() : _string( ::eina_stringshare_add("") ) {} stringshare(const char* str) : _string( ::eina_stringshare_add(str) ) { } stringshare(char* str, steal_stringshare_ref_t) : _string( str ) { } template stringshare(InputIterator i, InputIterator j , typename eina::enable_if ::value && !eina::is_contiguous_iterator::value >::type* = 0) { std::string tmp; while(i != j) { tmp.push_back(*i); ++i; } _string = ::eina_stringshare_add(tmp.c_str()); } template stringshare(ContiguousMemoryIterator i, ContiguousMemoryIterator j , typename eina::enable_if ::value>::type* = 0) : _string( ::eina_stringshare_add_length(&*i, j - i) ) { } ~stringshare() { ::eina_stringshare_del(_string); } stringshare(stringshare const& other) : _string( eina_stringshare_ref(other._string) ) {} stringshare& operator=(stringshare const& other) { ::eina_stringshare_refplace(&_string, other._string); return *this; } stringshare& operator=(const char* c_string) { ::eina_stringshare_replace(&_string, c_string); return *this; } const_iterator begin() const { return _string; } const_iterator end() const { return _string + size(); } const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(end()); } const_iterator cbegin() const { return begin(); } const_iterator cend() const { return end(); } const_reverse_iterator crbegin() const { return rbegin(); } const_reverse_iterator crend() const { return rend(); } size_type size() const { return eina_stringshare_strlen(_string); } size_type length() const { return size(); } size_type max_size() const { return -1; } bool empty() const { return _string[0] == 0; } const_reference operator[](size_type i) const { return _string[i]; } const_reference at(size_type i) const { if(i < size()) return (*this)[i]; else throw std::out_of_range(""); } const_reference back() const { return _string[size()-1]; } const_reference front() const { return _string[0]; } void swap(stringshare& other) { std::swap(_string, other._string); } const char* c_str() const { return _string; } const char* data() const { return _string; } private: Eina_Stringshare* _string; }; template <> struct is_contiguous_iterator : true_type {}; inline bool operator==(stringshare const& lhs, stringshare const& rhs) { return lhs.c_str() == rhs.c_str(); } inline bool operator!=(stringshare const& lhs, stringshare const& rhs) { return !(lhs == rhs); } inline bool operator==(stringshare const& lhs, const char* rhs) { return lhs.c_str() == rhs || std::strcmp(lhs.c_str(), rhs) == 0; } inline bool operator!=(stringshare const& lhs, const char* rhs) { return !(lhs == rhs); } inline bool operator==(const char* lhs, stringshare const& rhs) { return rhs == lhs; } inline bool operator!=(const char* lhs, stringshare const& rhs) { return !(lhs == rhs); } } } #endif