efl/src/lib/eina_cxx/eina_stringshare.hh

206 lines
4.1 KiB
C++

#ifndef _EINA_STRINGSHARE_HH
#define _EINA_STRINGSHARE_HH
#include <Eina.h>
#include <eina_type_traits.hh>
#include <cstring>
#include <stdexcept>
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_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 <typename InputIterator>
stringshare(InputIterator i, InputIterator j
, typename eina::enable_if
<!eina::is_integral<InputIterator>::value
&& !eina::is_contiguous_iterator<InputIterator>::value
>::type* = 0)
{
std::string tmp;
while(i != j)
{
tmp.push_back(*i);
++i;
}
_string = ::eina_stringshare_add(tmp.c_str());
}
template <typename ContiguousMemoryIterator>
stringshare(ContiguousMemoryIterator i, ContiguousMemoryIterator j
, typename eina::enable_if
<eina::is_contiguous_iterator<ContiguousMemoryIterator>::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<stringshare::const_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