Genericized concat, added join, fixed operator[] and added indexOf

This commit is contained in:
Felipe Magno de Almeida 2014-09-17 17:05:50 -03:00
parent a702e88b53
commit 8ed4544bbc
3 changed files with 77 additions and 13 deletions

View File

@ -5,6 +5,8 @@
#include <Eina.hh>
#include <iterator>
namespace efl { namespace js {
struct eina_list_base
@ -13,12 +15,48 @@ struct eina_list_base
virtual std::size_t size() const = 0;
virtual eina_list_base* concat(eina_list_base const& rhs) const = 0;
//virtual v8::Local<v8::Value> operator[](std::size_t) const = 0;
virtual int index_of(v8::Isolate* isolate, v8::Local<v8::Value> v) const = 0;
virtual v8::Local<v8::Value> get(v8::Isolate*, std::size_t) const = 0;
virtual v8::Local<v8::String> to_string(v8::Isolate*) const = 0;
};
template <typename C>
struct eina_list_common : eina_list_base
struct eina_list_common;
template <typename C, typename T, typename Enable = void>
struct eina_list_type_specific;
template <typename C>
struct eina_list_type_specific<C, int> : eina_list_base
{
v8::Local<v8::Value> get(v8::Isolate* isolate, std::size_t index) const
{
return v8::Number::New(isolate, *std::next(container_get().begin(), index));
}
int index_of(v8::Isolate*, v8::Local<v8::Value> v) const
{
std::cout << "index_of" << std::endl;
if(v->IsInt32() || v->IsUint32())
{
int64_t value = v->IntegerValue();
typedef typename C::const_iterator iterator;
iterator first = container_get().begin()
, last = container_get().end()
, found = std::find(first, last, value);
if(found == last)
return -1;
else
return std::distance(first, found);
}
else
return -1;
}
C& container_get() { return static_cast<eina_list_common<C>&>(*this)._container; }
C const& container_get() const { return static_cast<eina_list_common<C>const&>(*this)._container; }
};
template <typename C>
struct eina_list_common : eina_list_type_specific<C, typename C::value_type>
{
eina_list_common() : _container(0) {}
eina_list_common(Eina_List* raw) : _container(raw) {}
@ -29,16 +67,14 @@ struct eina_list_common : eina_list_base
std::cout << "to_string" << std::endl;
typedef typename container_type::const_iterator iterator;
std::stringstream s;
s << '[';
for(iterator first = _container.begin()
, last = _container.end()
, last_elem = std::next(last, -1); first != last; ++first)
{
s << *first;
if(first != last)
s << ", ";
if(first != last_elem)
s << ",";
}
s << ']';
std::cout << "string " << s.str() << std::endl;
return v8::String::NewFromUtf8(isolate, s.str().c_str());
}
@ -47,6 +83,21 @@ struct eina_list_common : eina_list_base
typedef C container_type;
};
namespace detail {
template <typename T>
eina_list_base* concat(T const& self, eina_list_base const& other)
{
std::cout << __func__ << std::endl;
T const& rhs = static_cast<T const&>(other);
typedef typename T::container_type container_type;
container_type list(self._container.begin(), self._container.end());
list.insert(list.end(), rhs._container.begin(), rhs._container.end());
return new T(list.release_native_handle());
}
}
template <typename T>
struct eina_list : eina_list_common<efl::eina::list
<T
@ -67,11 +118,7 @@ struct eina_list : eina_list_common<efl::eina::list
eina_list_base* concat(eina_list_base const& other) const
{
std::cout << __func__ << std::endl;
eina_list<T>const& rhs = static_cast<eina_list<T>const&>(other);
container_type list(this->_container.begin(), this->_container.end());
list.insert(list.end(), rhs._container.begin(), rhs._container.end());
return new eina_list<T>(list.release_native_handle());
return detail::concat(*this, other);
}
};

View File

@ -65,7 +65,8 @@ void length(v8::Local<v8::String>, v8::PropertyCallbackInfo<v8::Value> const& in
void index_get(uint32_t index, v8::PropertyCallbackInfo<v8::Value>const& info)
{
std::cout << "index_get " << index << std::endl;
info.GetReturnValue().Set(5);
eina_list_base* self = static_cast<eina_list_base*>(info.This()->GetAlignedPointerFromInternalField(0));
info.GetReturnValue().Set(self->get(info.GetIsolate(), index));
}
void new_eina_list(v8::FunctionCallbackInfo<v8::Value> const& args)
@ -261,6 +262,10 @@ EAPI void eina_list_register(v8::Handle<v8::ObjectTemplate> global, v8::Isolate*
(isolate, "concat", &efl::js::concat, prototype);
efl::js::register_<efl::js::eina_list_base>
(isolate, "toString", std::bind(&efl::js::eina_list_base::to_string, _1, _2), prototype);
efl::js::register_<efl::js::eina_list_base>
(isolate, "join", std::bind(&efl::js::eina_list_base::to_string, _1, _2), prototype);
efl::js::register_<efl::js::eina_list_base, v8::Local<v8::Value> >
(isolate, "indexOf", std::bind(&efl::js::eina_list_base::index_of, _1, _2, _3), prototype);
efl::js::persistent_instance_template = v8::UniquePersistent<v8::ObjectTemplate> (isolate, instance_t);
efl::js::instance_template = constructor;

View File

@ -31,6 +31,18 @@ static const char script[] =
"var c = l1.concat(l2);\n"
"print (\"c \", c.toString());\n"
"assert (c.length == (l1.length + l2.length));\n"
"assert (c[0] == l1[0]);\n"
"assert (c[1] == l1[1]);\n"
"assert (c[2] == l1[2]);\n"
"assert (c[3] == l2[0]);\n"
"assert (c[4] == l2[1]);\n"
"assert (c[5] == l2[2]);\n"
"assert (c.indexOf(c[0]) == 0);\n"
"assert (c.indexOf(c[1]) == 1);\n"
"assert (c.indexOf(c[2]) == 2);\n"
"assert (c.indexOf(c[3]) == 0);\n"
"assert (c.indexOf(c[4]) == 1);\n"
"assert (c.indexOf(c[5]) == 2);\n"
;
const char* ToCString(const v8::String::Utf8Value& value) {
@ -59,7 +71,7 @@ bool ExecuteString(v8::Isolate* isolate,
if (result.IsEmpty()) {
std::cout << "Failed with exception thrown" << std::endl;
assert(try_catch.HasCaught());
//std::abort();
std::abort();
// Print errors that happened during execution.
// if (report_exceptions)
// ReportException(isolate, &try_catch);