0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-10-30 02:18:58 +01:00
construct/include/ircd/js/vector.h
2018-02-05 21:24:34 -08:00

230 lines
4.4 KiB
C++

// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_JS_VECTOR_H
namespace ircd {
namespace js {
template<class T>
struct vector
:JS::AutoVectorRooter<T>
{
using jsapi_type = T;
using local_type = T;
vector(const size_t &size)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
this->resize(size);
}
vector()
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
}
vector(vector &&other) noexcept
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
this->reserve(other.length());
for(auto &t : other)
this->infallibleAppend(t);
other.clear();
}
};
template<>
struct vector<value>
:JS::AutoVectorRooter<JS::Value>
{
using jsapi_type = JS::Value;
using local_type = value;
struct handle
:JS::HandleValueArray
{
handle()
:JS::HandleValueArray{JS::HandleValueArray::empty()}
{}
handle(const JS::CallArgs &args)
:JS::HandleValueArray{args}
{}
handle(const size_t &len, const JS::Value *const &elems)
:JS::HandleValueArray{JS::HandleValueArray::fromMarkedLocation(len, elems)}
{}
};
operator handle() const
{
return { length(), begin() };
}
/*
// Construct vector from initializer list of raw `JS::Value`
// ex: JS::Value a; vector foo {{ a, a, ... }};
explicit vector(const std::initializer_list<jsapi_type> &list)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
reserve(list.size());
for(auto &t : list)
infallibleAppend(t);
}
*/
// Construct from initializer list of our `struct value` wrapper
// ex: value a(1); vector foo {{ a, a, ... }};
vector(const std::initializer_list<value> &list)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
reserve(list.size());
for(auto &t : list)
infallibleAppend(t);
}
// Construct from initializer list of any type passed through `struct value` ctor
// ex: int a; vector foo {{ a, 3, 123, ... }};
/*
template<class U>
vector(const std::initializer_list<U> &list)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
reserve(list.size());
for(auto &t : list)
infallibleAppend(value(t));
}
*/
explicit vector(const object &obj)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
if(!is_array(obj))
throw internal_error("Object is not an array");
const auto len(obj.size());
reserve(obj.size());
for(size_t i(0); i < len; ++i)
infallibleAppend(get(obj, i));
}
vector(const value &val)
:vector(object(val))
{
}
vector(const handle &h)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
reserve(h.length());
for(size_t i(0); i < h.length(); ++i)
infallibleAppend(h[i]);
}
vector(const size_t &size)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
resize(size);
}
vector()
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
}
vector(vector &&other) noexcept
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
reserve(other.length());
for(auto &t : other)
infallibleAppend(t);
other.clear();
}
};
// Specialization for vector of objects
template<>
struct vector<object>
:JS::AutoVectorRooter<JSObject *>
{
using jsapi_type = JSObject *;
using local_type = object;
vector(const std::initializer_list<jsapi_type> &list)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
reserve(list.size());
for(auto &t : list)
infallibleAppend(t);
}
vector(const std::initializer_list<local_type> &list)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
reserve(list.size());
for(auto &t : list)
infallibleAppend(t.get());
}
vector(const size_t &size)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
resize(size);
}
vector()
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
}
};
template<>
struct vector<id>
:JS::AutoVectorRooter<jsid>
{
using jsapi_type = jsid;
using local_type = id;
using base_type = JS::AutoVectorRooter<jsapi_type>;
/*
vector(const std::initializer_list<jsapi_type> &list)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
reserve(list.size());
for(auto &t : list)
infallibleAppend(t);
}
*/
vector(const std::initializer_list<local_type> &list)
:base_type{*cx}
{
reserve(list.size());
for(auto &t : list)
infallibleAppend(t.get());
}
vector(const size_t &size)
:base_type{*cx}
{
resize(size);
}
vector()
:base_type{*cx}
{
reserve(8);
}
};
} // namespace js
} // namespace ircd