forked from enlightenment/efl
386 lines
7.5 KiB
C++
386 lines
7.5 KiB
C++
#ifndef _EFL_EINA_EINA_VALUE_HH
|
|
#define _EFL_EINA_EINA_VALUE_HH
|
|
|
|
#include <Eina.h>
|
|
|
|
#include <eina_stringshare.hh>
|
|
#include <eina_type_traits.hh>
|
|
|
|
namespace efl { namespace eina {
|
|
|
|
template <typename T, typename Enable = void>
|
|
struct _eina_value_traits;
|
|
|
|
template <typename T>
|
|
struct _eina_value_traits_base;
|
|
|
|
template <typename T>
|
|
struct _eina_value_traits_aux;
|
|
|
|
template <typename T>
|
|
struct _eina_value_traits_base
|
|
{
|
|
typedef T type;
|
|
|
|
static ::Eina_Value* create()
|
|
{
|
|
return eina_value_new(_eina_value_traits<T>::value_type());
|
|
}
|
|
static void set_type( ::Eina_Value* v)
|
|
{
|
|
eina_value_setup(v, _eina_value_traits<T>::value_type());
|
|
}
|
|
static void set( ::Eina_Value* v, type c)
|
|
{
|
|
::eina_value_set(v, c);
|
|
}
|
|
static type get( ::Eina_Value* v)
|
|
{
|
|
if(_eina_value_traits<T>::value_type() == eina_value_type_get(v))
|
|
{
|
|
type vv;
|
|
if(::eina_value_get(v, &vv))
|
|
return vv;
|
|
else
|
|
throw eina::system_error(eina::get_error_code());
|
|
}
|
|
else
|
|
throw eina::system_error(EINA_ERROR_VALUE_FAILED, eina::eina_error_category());
|
|
}
|
|
};
|
|
|
|
// Indirection for uint64_t. uint64_t can be a typedef for unsigned
|
|
// long, so we can't specialize on the same template
|
|
template <>
|
|
struct _eina_value_traits_aux<uint64_t>
|
|
: _eina_value_traits_base<uint64_t>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_UINT64;
|
|
}
|
|
};
|
|
|
|
template <typename T, typename Enable>
|
|
struct _eina_value_traits : _eina_value_traits_aux<T>
|
|
{
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<unsigned char>
|
|
: _eina_value_traits_base<unsigned char>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_UCHAR;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<unsigned short>
|
|
: _eina_value_traits_base<unsigned short>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_USHORT;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<unsigned int>
|
|
: _eina_value_traits_base<unsigned int>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_UINT;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<unsigned long>
|
|
: _eina_value_traits_base<unsigned long>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_ULONG;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<char>
|
|
: _eina_value_traits_base<char>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_CHAR;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<short>
|
|
: _eina_value_traits_base<short>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_SHORT;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<int>
|
|
: _eina_value_traits_base<int>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_INT;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<long>
|
|
: _eina_value_traits_base<long>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_LONG;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<float>
|
|
: _eina_value_traits_base<float>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_FLOAT;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<double>
|
|
: _eina_value_traits_base<double>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_DOUBLE;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<stringshare>
|
|
: _eina_value_traits_base<stringshare>
|
|
{
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_STRINGSHARE;
|
|
}
|
|
static void set( ::Eina_Value* v, type c)
|
|
{
|
|
::eina_value_set(v, c.data());
|
|
}
|
|
static type get( ::Eina_Value* v)
|
|
{
|
|
char* c_str;
|
|
::eina_value_get(v, &c_str);
|
|
return stringshare(c_str, steal_stringshare_ref);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct _eina_value_traits<std::string>
|
|
: _eina_value_traits_base<std::string>
|
|
{
|
|
typedef typename _eina_value_traits_base<std::string>::type type;
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_STRING;
|
|
}
|
|
static void set( ::Eina_Value* v, type c)
|
|
{
|
|
::eina_value_set(v, c.c_str());
|
|
}
|
|
static type get( ::Eina_Value* v)
|
|
{
|
|
char* c_str;
|
|
::eina_value_get(v, &c_str);
|
|
std::string r(c_str);
|
|
::free(c_str);
|
|
return r;
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct _eina_value_traits<T[], typename eina::enable_if<eina::is_pod<T>::value>::type>
|
|
: _eina_value_traits_base<T[]>
|
|
{
|
|
typedef typename _eina_value_traits_base<T[]>::type type;
|
|
static ::Eina_Value_Type const* value_type()
|
|
{
|
|
return EINA_VALUE_TYPE_ARRAY;
|
|
}
|
|
static void set( ::Eina_Value* v, type c)
|
|
{
|
|
::eina_value_set(v, c.c_str());
|
|
}
|
|
static type get( ::Eina_Value* v)
|
|
{
|
|
char* c_str;
|
|
::eina_value_get(v, &c_str);
|
|
std::string r(c_str);
|
|
::free(c_str);
|
|
return r;
|
|
}
|
|
};
|
|
|
|
class value;
|
|
|
|
template <typename T>
|
|
T get(value const& v);
|
|
|
|
class value
|
|
{
|
|
template <typename T>
|
|
void primitive_init(T v)
|
|
{
|
|
_raw = _eina_value_traits<T>::create();
|
|
_eina_value_traits<T>::set(_raw, v);
|
|
}
|
|
public:
|
|
value()
|
|
: _raw(_eina_value_traits<char>::create())
|
|
{
|
|
}
|
|
template <typename T>
|
|
value(T v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(char v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(short v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(int v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(long v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(unsigned char v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(unsigned short v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(unsigned int v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(unsigned long v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(float v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
value(double v)
|
|
{
|
|
primitive_init(v);
|
|
}
|
|
|
|
~value()
|
|
{
|
|
eina_value_free(_raw);
|
|
}
|
|
|
|
value(value const& other)
|
|
: _raw(_eina_value_traits<char>::create())
|
|
{
|
|
if(!eina_value_copy(const_cast<Eina_Value const*>(other._raw), _raw))
|
|
throw eina::system_error(eina::get_error_code());
|
|
}
|
|
value& operator=(value const& other)
|
|
{
|
|
eina_value_flush(_raw);
|
|
if(!eina_value_copy(const_cast<Eina_Value const*>(other._raw), _raw))
|
|
throw eina::system_error(eina::get_error_code());
|
|
return *this;
|
|
}
|
|
|
|
void swap(value& other)
|
|
{
|
|
std::swap(_raw, other._raw);
|
|
}
|
|
|
|
typedef Eina_Value* native_handle_type;
|
|
native_handle_type native_handle() const
|
|
{
|
|
return _raw;
|
|
}
|
|
typedef Eina_Value_Type const* type_info_t;
|
|
type_info_t type_info() const
|
|
{
|
|
return ::eina_value_type_get(_raw);
|
|
}
|
|
private:
|
|
::Eina_Value* _raw;
|
|
|
|
template <typename T>
|
|
friend T get(value const& v)
|
|
{
|
|
return _eina_value_traits<T>::get(v._raw);
|
|
}
|
|
};
|
|
|
|
inline void swap(value& lhs, value& rhs)
|
|
{
|
|
lhs.swap(rhs);
|
|
}
|
|
|
|
inline bool operator==(value const& lhs, value const& rhs)
|
|
{
|
|
return lhs.type_info() == rhs.type_info()
|
|
&& eina_value_compare(lhs.native_handle(), rhs.native_handle()) == 0;
|
|
}
|
|
|
|
inline bool operator<(value const& lhs, value const& rhs)
|
|
{
|
|
return std::less<Eina_Value_Type const*>()(lhs.type_info(), rhs.type_info())
|
|
|| (lhs.type_info() == rhs.type_info()
|
|
&& eina_value_compare(lhs.native_handle(), rhs.native_handle()) < 0);
|
|
}
|
|
|
|
inline bool operator>(value const& lhs, value const& rhs)
|
|
{
|
|
return std::less<Eina_Value_Type const*>()(rhs.type_info(), lhs.type_info())
|
|
|| (rhs.type_info() == lhs.type_info()
|
|
&& eina_value_compare(lhs.native_handle(), rhs.native_handle()) > 0);
|
|
}
|
|
|
|
inline bool operator<=(value const& lhs, value const& rhs)
|
|
{
|
|
return !(lhs > rhs);
|
|
}
|
|
|
|
inline bool operator>=(value const& lhs, value const& rhs)
|
|
{
|
|
return !(lhs < rhs);
|
|
}
|
|
|
|
inline bool operator!=(value const& lhs, value const& rhs)
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
} }
|
|
|
|
#endif
|