mirror of
https://github.com/matrix-construct/construct
synced 2024-11-26 08:42:34 +01:00
241 lines
5 KiB
C++
241 lines
5 KiB
C++
/*
|
|
* Copyright (C) 2016 Charybdis Development Team
|
|
* Copyright (C) 2016 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.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#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
|