mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2025-12-07 17:26:55 +08:00
Avoid creating vectors when possible
This commit is contained in:
parent
425c679c6c
commit
28a59d2a6e
@ -105,47 +105,47 @@ namespace chaiscript {
|
||||
}
|
||||
|
||||
struct Build_Info {
|
||||
constexpr static int version_major() noexcept
|
||||
[[nodiscard]] constexpr static int version_major() noexcept
|
||||
{
|
||||
return chaiscript::version_major;
|
||||
}
|
||||
|
||||
constexpr static int version_minor() noexcept
|
||||
[[nodiscard]] constexpr static int version_minor() noexcept
|
||||
{
|
||||
return chaiscript::version_minor;
|
||||
}
|
||||
|
||||
constexpr static int version_patch() noexcept
|
||||
[[nodiscard]] constexpr static int version_patch() noexcept
|
||||
{
|
||||
return chaiscript::version_patch;
|
||||
}
|
||||
|
||||
static std::string version()
|
||||
[[nodiscard]] static std::string version()
|
||||
{
|
||||
return std::to_string(version_major()) + '.' + std::to_string(version_minor()) + '.' + std::to_string(version_patch());
|
||||
}
|
||||
|
||||
static std::string compiler_id()
|
||||
[[nodiscard]] static std::string compiler_id()
|
||||
{
|
||||
return compiler_name() + '-' + compiler_version();
|
||||
}
|
||||
|
||||
static std::string build_id()
|
||||
[[nodiscard]] static std::string build_id()
|
||||
{
|
||||
return compiler_id() + (debug_build()?"-Debug":"-Release");
|
||||
}
|
||||
|
||||
static std::string compiler_version()
|
||||
[[nodiscard]] static std::string compiler_version()
|
||||
{
|
||||
return chaiscript::compiler_version;
|
||||
}
|
||||
|
||||
static std::string compiler_name()
|
||||
[[nodiscard]] static std::string compiler_name()
|
||||
{
|
||||
return chaiscript::compiler_name;
|
||||
}
|
||||
|
||||
constexpr static bool debug_build() noexcept
|
||||
[[nodiscard]] constexpr static bool debug_build() noexcept
|
||||
{
|
||||
return chaiscript::debug_build;
|
||||
}
|
||||
@ -153,7 +153,8 @@ namespace chaiscript {
|
||||
|
||||
|
||||
template<typename T>
|
||||
constexpr auto parse_num(const std::string_view &t_str) noexcept -> typename std::enable_if<std::is_integral<T>::value, T>::type
|
||||
[[nodiscard]] constexpr auto parse_num(const std::string_view &t_str) noexcept
|
||||
-> typename std::enable_if<std::is_integral<T>::value, T>::type
|
||||
{
|
||||
T t = 0;
|
||||
for (const auto c : t_str) {
|
||||
@ -168,7 +169,8 @@ namespace chaiscript {
|
||||
|
||||
|
||||
template<typename T>
|
||||
auto parse_num(const std::string_view &t_str) noexcept -> typename std::enable_if<!std::is_integral<T>::value, T>::type
|
||||
[[nodiscard]] auto parse_num(const std::string_view &t_str) noexcept
|
||||
-> typename std::enable_if<!std::is_integral<T>::value, T>::type
|
||||
{
|
||||
T t = 0;
|
||||
T base = 0;
|
||||
@ -211,11 +213,11 @@ namespace chaiscript {
|
||||
}
|
||||
|
||||
struct str_less {
|
||||
bool operator()(const std::string &t_lhs, const std::string &t_rhs) const noexcept {
|
||||
[[nodiscard]] bool operator()(const std::string &t_lhs, const std::string &t_rhs) const noexcept {
|
||||
return t_lhs < t_rhs;
|
||||
}
|
||||
template<typename LHS, typename RHS>
|
||||
constexpr bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept {
|
||||
[[nodiscard]] constexpr bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept {
|
||||
return std::lexicographical_compare(t_lhs.begin(), t_lhs.end(), t_rhs.begin(), t_rhs.end());
|
||||
}
|
||||
struct is_transparent{};
|
||||
@ -229,6 +231,37 @@ namespace chaiscript {
|
||||
External_Scripts
|
||||
};
|
||||
|
||||
template<typename From, typename To>
|
||||
struct is_nothrow_forward_constructible
|
||||
: std::bool_constant<noexcept(To{std::declval<From>()})>
|
||||
{
|
||||
};
|
||||
|
||||
template< class From, class To >
|
||||
inline constexpr bool is_nothrow_forward_constructible_v
|
||||
= is_nothrow_forward_constructible<From, To>::value;
|
||||
|
||||
template<typename Container, typename ... T>
|
||||
[[nodiscard]] constexpr auto make_container(T && ... t)
|
||||
{
|
||||
Container c;
|
||||
c.reserve(sizeof...(t));
|
||||
(c.push_back(std::forward<T>(t)), ...);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
template<typename ... T>
|
||||
[[nodiscard]] auto make_vector(T && ... t)
|
||||
{
|
||||
using container_type =
|
||||
std::vector<std::common_type_t<std::decay_t<T>...>>;
|
||||
|
||||
return make_container<container_type>(std::forward<T>(t)...);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline std::vector<Options> default_options()
|
||||
{
|
||||
#ifdef CHAISCRIPT_NO_DYNLOAD
|
||||
|
||||
@ -42,7 +42,7 @@ namespace chaiscript
|
||||
{
|
||||
public:
|
||||
|
||||
static ModulePtr library()
|
||||
[[nodiscard]] static ModulePtr library()
|
||||
{
|
||||
auto lib = std::make_shared<Module>();
|
||||
bootstrap::Bootstrap::bootstrap(*lib);
|
||||
|
||||
@ -83,8 +83,8 @@ namespace chaiscript {
|
||||
public:
|
||||
// construct/copy/destruct
|
||||
constexpr Any() noexcept = default;
|
||||
Any(Any &&) = default;
|
||||
Any &operator=(Any &&t_any) = default;
|
||||
Any(Any &&) noexcept = default;
|
||||
Any &operator=(Any &&t_any) noexcept = default;
|
||||
|
||||
Any(const Any &t_any)
|
||||
: m_data(t_any.empty() ? nullptr : t_any.m_data->clone())
|
||||
@ -93,7 +93,7 @@ namespace chaiscript {
|
||||
|
||||
template<typename ValueType,
|
||||
typename = std::enable_if_t<!std::is_same_v<Any, std::decay_t<ValueType>>>>
|
||||
explicit Any(ValueType &&t_value)
|
||||
explicit Any(ValueType &&t_value) noexcept(is_nothrow_forward_constructible_v<decltype(t_value), std::decay_t<ValueType>>)
|
||||
: m_data(std::make_unique<Data_Impl<std::decay_t<ValueType>>>(std::forward<ValueType>(t_value)))
|
||||
{
|
||||
}
|
||||
@ -128,7 +128,7 @@ namespace chaiscript {
|
||||
// queries
|
||||
bool empty() const noexcept
|
||||
{
|
||||
return !bool(m_data);
|
||||
return !static_cast<bool>(m_data);
|
||||
}
|
||||
|
||||
const std::type_info & type() const noexcept
|
||||
|
||||
@ -241,7 +241,7 @@ namespace chaiscript
|
||||
|
||||
/// Create a bound function object. The first param is the function to bind
|
||||
/// the remaining parameters are the args to bind into the result
|
||||
static Boxed_Value bind_function(const std::vector<Boxed_Value> ¶ms)
|
||||
static Boxed_Value bind_function(const Function_Params ¶ms)
|
||||
{
|
||||
if (params.empty()) {
|
||||
throw exception::arity_error(0, 1);
|
||||
|
||||
@ -313,14 +313,14 @@ namespace chaiscript
|
||||
return arity;
|
||||
}
|
||||
|
||||
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
{
|
||||
return std::any_of(std::begin(m_funcs), std::end(m_funcs),
|
||||
[&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); });
|
||||
}
|
||||
|
||||
protected:
|
||||
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
return dispatch::dispatch(m_funcs, params, t_conversions);
|
||||
}
|
||||
@ -935,7 +935,7 @@ namespace chaiscript
|
||||
return m_conversions;
|
||||
}
|
||||
|
||||
static bool is_attribute_call(const std::vector<Proxy_Function> &t_funs, const std::vector<Boxed_Value> &t_params,
|
||||
static bool is_attribute_call(const std::vector<Proxy_Function> &t_funs, const Function_Params &t_params,
|
||||
bool t_has_params, const Type_Conversions_State &t_conversions) noexcept
|
||||
{
|
||||
if (!t_has_params || t_params.empty()) {
|
||||
@ -956,7 +956,7 @@ namespace chaiscript
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4715)
|
||||
#endif
|
||||
Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> ¶ms, bool t_has_params,
|
||||
Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const Function_Params ¶ms, bool t_has_params,
|
||||
const Type_Conversions_State &t_conversions)
|
||||
{
|
||||
uint_fast32_t loc = t_loc;
|
||||
@ -964,9 +964,9 @@ namespace chaiscript
|
||||
if (funs.first != loc) { t_loc = uint_fast32_t(funs.first); }
|
||||
|
||||
const auto do_attribute_call =
|
||||
[this](int l_num_params, const std::vector<Boxed_Value> &l_params, const std::vector<Proxy_Function> &l_funs, const Type_Conversions_State &l_conversions)->Boxed_Value
|
||||
[this](int l_num_params, Function_Params l_params, const std::vector<Proxy_Function> &l_funs, const Type_Conversions_State &l_conversions)->Boxed_Value
|
||||
{
|
||||
std::vector<Boxed_Value> attr_params{l_params.begin(), l_params.begin() + l_num_params};
|
||||
Function_Params attr_params(l_params.begin(), l_params.begin() + l_num_params);
|
||||
Boxed_Value bv = dispatch::dispatch(l_funs, attr_params, l_conversions);
|
||||
if (l_num_params < int(l_params.size()) || bv.get_type_info().bare_equal(user_type<dispatch::Proxy_Function_Base>())) {
|
||||
struct This_Foist {
|
||||
@ -1049,14 +1049,15 @@ namespace chaiscript
|
||||
if (!functions.empty()) {
|
||||
try {
|
||||
if (is_no_param) {
|
||||
auto tmp_params(params);
|
||||
auto tmp_params = params.to_vector();
|
||||
tmp_params.insert(tmp_params.begin() + 1, var(t_name));
|
||||
return do_attribute_call(2, tmp_params, functions, t_conversions);
|
||||
return do_attribute_call(2, Function_Params(tmp_params), functions, t_conversions);
|
||||
} else {
|
||||
return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))}, t_conversions);
|
||||
std::array<Boxed_Value, 3> p{params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))};
|
||||
return dispatch::dispatch(functions, Function_Params{p}, t_conversions);
|
||||
}
|
||||
} catch (const dispatch::option_explicit_set &e) {
|
||||
throw chaiscript::exception::dispatch_error(params, std::vector<Const_Proxy_Function>(funs.second->begin(), funs.second->end()),
|
||||
throw chaiscript::exception::dispatch_error(params, std::vector<Const_Proxy_Function>(funs.second->begin(), funs.second->end()),
|
||||
e.what());
|
||||
}
|
||||
}
|
||||
@ -1076,7 +1077,7 @@ namespace chaiscript
|
||||
|
||||
|
||||
|
||||
Boxed_Value call_function(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> ¶ms,
|
||||
Boxed_Value call_function(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc, Function_Params params,
|
||||
const Type_Conversions_State &t_conversions) const
|
||||
{
|
||||
uint_fast32_t loc = t_loc;
|
||||
@ -1132,7 +1133,7 @@ namespace chaiscript
|
||||
|
||||
/// Returns true if a call can be made that consists of the first parameter
|
||||
/// (the function) with the remaining parameters as its arguments.
|
||||
Boxed_Value call_exists(const std::vector<Boxed_Value> ¶ms) const
|
||||
Boxed_Value call_exists(const Function_Params ¶ms) const
|
||||
{
|
||||
if (params.empty())
|
||||
{
|
||||
@ -1142,7 +1143,7 @@ namespace chaiscript
|
||||
const auto &f = this->boxed_cast<Const_Proxy_Function>(params[0]);
|
||||
const Type_Conversions_State convs(m_conversions, m_conversions.conversion_saves());
|
||||
|
||||
return const_var(f->call_match(std::vector<Boxed_Value>(params.begin() + 1, params.end()), convs));
|
||||
return const_var(f->call_match(Function_Params(params.begin() + 1, params.end()), convs));
|
||||
}
|
||||
|
||||
/// Dump all system info to stdout
|
||||
@ -1203,11 +1204,6 @@ namespace chaiscript
|
||||
m_state = t_state;
|
||||
}
|
||||
|
||||
static void save_function_params(Stack_Holder &t_s, std::initializer_list<Boxed_Value> t_params)
|
||||
{
|
||||
t_s.call_params.back().insert(t_s.call_params.back().begin(), t_params);
|
||||
}
|
||||
|
||||
static void save_function_params(Stack_Holder &t_s, std::vector<Boxed_Value> &&t_params)
|
||||
{
|
||||
for (auto &¶m : t_params)
|
||||
@ -1216,22 +1212,17 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
|
||||
static void save_function_params(Stack_Holder &t_s, const std::vector<Boxed_Value> &t_params)
|
||||
static void save_function_params(Stack_Holder &t_s, const Function_Params &t_params)
|
||||
{
|
||||
t_s.call_params.back().insert(t_s.call_params.back().begin(), t_params.begin(), t_params.end());
|
||||
}
|
||||
|
||||
void save_function_params(std::initializer_list<Boxed_Value> t_params)
|
||||
{
|
||||
save_function_params(*m_stack_holder, t_params);
|
||||
}
|
||||
|
||||
void save_function_params(std::vector<Boxed_Value> &&t_params)
|
||||
{
|
||||
save_function_params(*m_stack_holder, std::move(t_params));
|
||||
}
|
||||
|
||||
void save_function_params(const std::vector<Boxed_Value> &t_params)
|
||||
void save_function_params(const Function_Params &t_params)
|
||||
{
|
||||
save_function_params(*m_stack_holder, t_params);
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ namespace chaiscript
|
||||
|
||||
bool is_attribute_function() const noexcept override { return m_is_attribute; }
|
||||
|
||||
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
{
|
||||
if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions))
|
||||
{
|
||||
@ -110,7 +110,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
protected:
|
||||
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions))
|
||||
{
|
||||
@ -159,7 +159,7 @@ namespace chaiscript
|
||||
|
||||
}
|
||||
|
||||
bool dynamic_object_typename_match(const std::vector<Boxed_Value> &bvs, const std::string &name,
|
||||
bool dynamic_object_typename_match(const Function_Params &bvs, const std::string &name,
|
||||
const std::unique_ptr<Type_Info> &ti, const Type_Conversions_State &t_conversions) const noexcept
|
||||
{
|
||||
if (!bvs.empty())
|
||||
@ -228,22 +228,22 @@ namespace chaiscript
|
||||
return (dc != nullptr) && dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func);
|
||||
}
|
||||
|
||||
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||
bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
std::vector<Boxed_Value> new_vals{Boxed_Value(Dynamic_Object(m_type_name))};
|
||||
new_vals.insert(new_vals.end(), vals.begin(), vals.end());
|
||||
|
||||
return m_func->call_match(new_vals, t_conversions);
|
||||
return m_func->call_match(Function_Params{new_vals}, t_conversions);
|
||||
}
|
||||
|
||||
protected:
|
||||
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
auto bv = Boxed_Value(Dynamic_Object(m_type_name), true);
|
||||
std::vector<Boxed_Value> new_params{bv};
|
||||
new_params.insert(new_params.end(), params.begin(), params.end());
|
||||
|
||||
(*m_func)(new_params, t_conversions);
|
||||
(*m_func)(Function_Params{new_params}, t_conversions);
|
||||
|
||||
return bv;
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ namespace chaiscript
|
||||
struct Function_Caller_Ret
|
||||
{
|
||||
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
|
||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State *t_conversions)
|
||||
const Function_Params ¶ms, const Type_Conversions_State *t_conversions)
|
||||
{
|
||||
if (t_conversions != nullptr) {
|
||||
return boxed_cast<Ret>(dispatch::dispatch(t_funcs, params, *t_conversions), t_conversions);
|
||||
@ -54,7 +54,7 @@ namespace chaiscript
|
||||
struct Function_Caller_Ret<Ret, true>
|
||||
{
|
||||
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
|
||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State *t_conversions)
|
||||
const Function_Params ¶ms, const Type_Conversions_State *t_conversions)
|
||||
{
|
||||
if (t_conversions != nullptr) {
|
||||
return Boxed_Number(dispatch::dispatch(t_funcs, params, *t_conversions)).get_as<Ret>();
|
||||
@ -74,7 +74,7 @@ namespace chaiscript
|
||||
struct Function_Caller_Ret<void, false>
|
||||
{
|
||||
static void call(const std::vector<Const_Proxy_Function> &t_funcs,
|
||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State *t_conversions)
|
||||
const Function_Params ¶ms, const Type_Conversions_State *t_conversions)
|
||||
{
|
||||
if (t_conversions != nullptr) {
|
||||
dispatch::dispatch(t_funcs, params, *t_conversions);
|
||||
@ -101,16 +101,14 @@ namespace chaiscript
|
||||
template<typename ... P>
|
||||
Ret operator()(P&& ... param)
|
||||
{
|
||||
std::array<Boxed_Value, sizeof...(P)> params{box<P>(std::forward<P>(param))...};
|
||||
|
||||
if (m_conversions) {
|
||||
Type_Conversions_State state(*m_conversions, m_conversions->conversion_saves());
|
||||
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value && !std::is_same<Ret, bool>::value>::call(m_funcs, {
|
||||
box<P>(std::forward<P>(param))...
|
||||
}, &state
|
||||
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value && !std::is_same<Ret, bool>::value>::call(m_funcs, Function_Params{params}, &state
|
||||
);
|
||||
} else {
|
||||
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value && !std::is_same<Ret, bool>::value>::call(m_funcs, {
|
||||
box<P>(std::forward<P>(param))...
|
||||
}, nullptr
|
||||
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value && !std::is_same<Ret, bool>::value>::call(m_funcs, Function_Params{params}, nullptr
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
81
include/chaiscript/dispatchkit/function_params.hpp
Normal file
81
include/chaiscript/dispatchkit/function_params.hpp
Normal file
@ -0,0 +1,81 @@
|
||||
// This file is distributed under the BSD License.
|
||||
// See "license.txt" for details.
|
||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||
// Copyright 2009-2017, Jason Turner (jason@emptycrate.com)
|
||||
// http://www.chaiscript.com
|
||||
|
||||
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
|
||||
|
||||
#ifndef CHAISCRIPT_FUNCTION_PARAMS_HPP
|
||||
#define CHAISCRIPT_FUNCTION_PARAMS_HPP
|
||||
|
||||
|
||||
#include "boxed_value.hpp"
|
||||
|
||||
namespace chaiscript {
|
||||
|
||||
class Function_Params
|
||||
{
|
||||
public:
|
||||
constexpr Function_Params(const Boxed_Value * const t_begin, const Boxed_Value * const t_end)
|
||||
: m_begin(t_begin), m_end(t_end)
|
||||
{
|
||||
}
|
||||
|
||||
explicit Function_Params(const Boxed_Value &bv)
|
||||
: m_begin(&bv), m_end(m_begin + 1)
|
||||
{
|
||||
}
|
||||
|
||||
explicit Function_Params(const std::vector<Boxed_Value> &vec)
|
||||
: m_begin(&vec.front()), m_end(&vec.front() + vec.size())
|
||||
{
|
||||
}
|
||||
|
||||
template<size_t Size>
|
||||
constexpr explicit Function_Params(const std::array<Boxed_Value, Size> &a)
|
||||
: m_begin(std::begin(a)), m_end(std::end(a))
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const Boxed_Value &operator[](const std::size_t t_i) const noexcept {
|
||||
return m_begin[t_i];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const Boxed_Value *begin() const noexcept {
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const Boxed_Value &front() const noexcept {
|
||||
return *m_begin;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const Boxed_Value *end() const noexcept {
|
||||
return m_end;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr std::size_t size() const noexcept {
|
||||
return m_end - m_begin;
|
||||
}
|
||||
|
||||
std::vector<Boxed_Value> to_vector() const {
|
||||
return std::vector<Boxed_Value>{m_begin, m_end};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool empty() const noexcept {
|
||||
return m_begin == m_end;
|
||||
}
|
||||
|
||||
private:
|
||||
const Boxed_Value *m_begin = nullptr;
|
||||
const Boxed_Value *m_end = nullptr;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "proxy_functions_detail.hpp"
|
||||
#include "type_info.hpp"
|
||||
#include "dynamic_object.hpp"
|
||||
#include "function_params.hpp"
|
||||
|
||||
namespace chaiscript {
|
||||
class Type_Conversions;
|
||||
@ -91,8 +92,9 @@ namespace chaiscript
|
||||
return m_types == t_rhs.m_types;
|
||||
}
|
||||
|
||||
std::vector<Boxed_Value> convert(std::vector<Boxed_Value> vals, const Type_Conversions_State &t_conversions) const
|
||||
std::vector<Boxed_Value> convert(Function_Params t_params, const Type_Conversions_State &t_conversions) const
|
||||
{
|
||||
auto vals = t_params.to_vector();
|
||||
constexpr auto dynamic_object_type_info = user_type<Dynamic_Object>();
|
||||
for (size_t i = 0; i < vals.size(); ++i)
|
||||
{
|
||||
@ -131,7 +133,7 @@ namespace chaiscript
|
||||
|
||||
// first result: is a match
|
||||
// second result: needs conversions
|
||||
std::pair<bool, bool> match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const noexcept
|
||||
std::pair<bool, bool> match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept
|
||||
{
|
||||
constexpr auto dynamic_object_type_info = user_type<Dynamic_Object>();
|
||||
bool needs_conversion = false;
|
||||
@ -154,7 +156,7 @@ namespace chaiscript
|
||||
}
|
||||
} catch (const std::bad_cast &) {
|
||||
return std::make_pair(false, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto &ti = m_types[i].second;
|
||||
if (!ti.is_undef())
|
||||
@ -214,7 +216,7 @@ namespace chaiscript
|
||||
public:
|
||||
virtual ~Proxy_Function_Base() = default;
|
||||
|
||||
Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms, const chaiscript::Type_Conversions_State &t_conversions) const
|
||||
Boxed_Value operator()(const Function_Params ¶ms, const chaiscript::Type_Conversions_State &t_conversions) const
|
||||
{
|
||||
if (m_arity < 0 || size_t(m_arity) == params.size()) {
|
||||
return do_call(params, t_conversions);
|
||||
@ -226,11 +228,11 @@ namespace chaiscript
|
||||
/// Returns a vector containing all of the types of the parameters the function returns/takes
|
||||
/// if the function is variadic or takes no arguments (arity of 0 or -1), the returned
|
||||
/// value contains exactly 1 Type_Info object: the return type
|
||||
/// \returns the types of all parameters.
|
||||
/// \returns the types of all parameters.
|
||||
const std::vector<Type_Info> &get_param_types() const noexcept { return m_types; }
|
||||
|
||||
virtual bool operator==(const Proxy_Function_Base &) const noexcept = 0;
|
||||
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const = 0;
|
||||
virtual bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const = 0;
|
||||
|
||||
virtual bool is_attribute_function() const noexcept { return false; }
|
||||
|
||||
@ -246,7 +248,7 @@ namespace chaiscript
|
||||
|
||||
//! Return true if the function is a possible match
|
||||
//! to the passed in values
|
||||
bool filter(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const noexcept
|
||||
bool filter(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept
|
||||
{
|
||||
assert(m_arity == -1 || (m_arity > 0 && static_cast<int>(vals.size()) == m_arity));
|
||||
|
||||
@ -272,13 +274,13 @@ namespace chaiscript
|
||||
constexpr auto boxed_number_ti = user_type<Boxed_Number>();
|
||||
constexpr auto function_ti = user_type<std::shared_ptr<const Proxy_Function_Base>>();
|
||||
|
||||
if (ti.is_undef()
|
||||
if (ti.is_undef()
|
||||
|| ti.bare_equal(boxed_value_ti)
|
||||
|| (!bv.get_type_info().is_undef()
|
||||
&& ( (ti.bare_equal(boxed_number_ti) && bv.get_type_info().is_arithmetic())
|
||||
|| ti.bare_equal(bv.get_type_info())
|
||||
|| bv.get_type_info().bare_equal(function_ti)
|
||||
|| t_conversions->converts(ti, bv.get_type_info())
|
||||
|| t_conversions->converts(ti, bv.get_type_info())
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -296,7 +298,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const = 0;
|
||||
virtual Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const = 0;
|
||||
|
||||
Proxy_Function_Base(std::vector<Type_Info> t_types, int t_arity)
|
||||
: m_types(std::move(t_types)), m_arity(t_arity), m_has_arithmetic_param(false)
|
||||
@ -313,7 +315,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
|
||||
static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs,
|
||||
static bool compare_types(const std::vector<Type_Info> &tis, const Function_Params &bvs,
|
||||
const Type_Conversions_State &t_conversions) noexcept
|
||||
{
|
||||
if (tis.size() - 1 != bvs.size())
|
||||
@ -367,10 +369,8 @@ namespace chaiscript
|
||||
virtual Param_Types get_dynamic_param_types() const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A Proxy_Function implementation that is not type safe, the called function
|
||||
* is expecting a vector<Boxed_Value> that it works with how it chooses.
|
||||
*/
|
||||
/// A Proxy_Function implementation that is not type safe, the called function
|
||||
/// is expecting a vector<Boxed_Value> that it works with how it chooses.
|
||||
class Dynamic_Proxy_Function : public Proxy_Function_Base, public Dynamic_Function_Interface
|
||||
{
|
||||
public:
|
||||
@ -398,7 +398,7 @@ namespace chaiscript
|
||||
&& this->m_param_types == prhs->m_param_types);
|
||||
}
|
||||
|
||||
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||
bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
return call_match_internal(vals, t_conversions).first;
|
||||
}
|
||||
@ -431,7 +431,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
protected:
|
||||
bool test_guard(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const
|
||||
bool test_guard(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const
|
||||
{
|
||||
if (m_guard)
|
||||
{
|
||||
@ -449,7 +449,7 @@ namespace chaiscript
|
||||
|
||||
// first result: is a match
|
||||
// second result: needs conversions
|
||||
std::pair<bool, bool> call_match_internal(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const
|
||||
std::pair<bool, bool> call_match_internal(const Function_Params &vals, const Type_Conversions_State &t_conversions) const
|
||||
{
|
||||
const auto comparison_result = [&](){
|
||||
if (m_arity < 0) {
|
||||
@ -462,7 +462,7 @@ namespace chaiscript
|
||||
}();
|
||||
|
||||
return std::make_pair(
|
||||
comparison_result.first && test_guard(vals, t_conversions),
|
||||
comparison_result.first && test_guard(vals, t_conversions),
|
||||
comparison_result.second
|
||||
);
|
||||
}
|
||||
@ -500,7 +500,7 @@ namespace chaiscript
|
||||
{
|
||||
public:
|
||||
Dynamic_Proxy_Function_Impl(
|
||||
Callable t_f,
|
||||
Callable t_f,
|
||||
int t_arity=-1,
|
||||
std::shared_ptr<AST_Node> t_parsenode = AST_NodePtr(),
|
||||
Param_Types t_param_types = Param_Types(),
|
||||
@ -517,13 +517,13 @@ namespace chaiscript
|
||||
|
||||
|
||||
protected:
|
||||
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
const auto match_results = call_match_internal(params, t_conversions);
|
||||
if (match_results.first)
|
||||
const auto [is_a_match, needs_conversions] = call_match_internal(params, t_conversions);
|
||||
if (is_a_match)
|
||||
{
|
||||
if (match_results.second) {
|
||||
return m_f(m_param_types.convert(params, t_conversions));
|
||||
if (needs_conversions) {
|
||||
return m_f(Function_Params{m_param_types.convert(params, t_conversions)});
|
||||
} else {
|
||||
return m_f(params);
|
||||
}
|
||||
@ -556,7 +556,7 @@ namespace chaiscript
|
||||
class Bound_Function final : public Proxy_Function_Base
|
||||
{
|
||||
public:
|
||||
Bound_Function(const Const_Proxy_Function &t_f,
|
||||
Bound_Function(const Const_Proxy_Function &t_f,
|
||||
const std::vector<Boxed_Value> &t_args)
|
||||
: Proxy_Function_Base(build_param_type_info(t_f, t_args), (t_f->get_arity()<0?-1:static_cast<int>(build_param_type_info(t_f, t_args).size())-1)),
|
||||
m_f(t_f), m_args(t_args)
|
||||
@ -570,9 +570,9 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
|
||||
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||
bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
return m_f->call_match(build_param_list(vals), t_conversions);
|
||||
return m_f->call_match(Function_Params(build_param_list(vals)), t_conversions);
|
||||
}
|
||||
|
||||
std::vector<Const_Proxy_Function> get_contained_functions() const override
|
||||
@ -581,7 +581,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
|
||||
std::vector<Boxed_Value> build_param_list(const std::vector<Boxed_Value> ¶ms) const
|
||||
std::vector<Boxed_Value> build_param_list(const Function_Params ¶ms) const
|
||||
{
|
||||
auto parg = params.begin();
|
||||
auto barg = m_args.begin();
|
||||
@ -590,7 +590,7 @@ namespace chaiscript
|
||||
|
||||
while (!(parg == params.end() && barg == m_args.end()))
|
||||
{
|
||||
while (barg != m_args.end()
|
||||
while (barg != m_args.end()
|
||||
&& !(barg->get_type_info() == chaiscript::detail::Get_Type_Info<Placeholder_Object>::get()))
|
||||
{
|
||||
args.push_back(*barg);
|
||||
@ -603,18 +603,18 @@ namespace chaiscript
|
||||
++parg;
|
||||
}
|
||||
|
||||
if (barg != m_args.end()
|
||||
if (barg != m_args.end()
|
||||
&& barg->get_type_info() == chaiscript::detail::Get_Type_Info<Placeholder_Object>::get())
|
||||
{
|
||||
++barg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
static std::vector<Type_Info> build_param_type_info(const Const_Proxy_Function &t_f,
|
||||
static std::vector<Type_Info> build_param_type_info(const Const_Proxy_Function &t_f,
|
||||
const std::vector<Boxed_Value> &t_args)
|
||||
{
|
||||
assert(t_f->get_arity() < 0 || t_f->get_arity() == static_cast<int>(t_args.size()));
|
||||
@ -638,9 +638,9 @@ namespace chaiscript
|
||||
return retval;
|
||||
}
|
||||
|
||||
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
return (*m_f)(build_param_list(params), t_conversions);
|
||||
return (*m_f)(Function_Params{build_param_list(params)}, t_conversions);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -656,13 +656,13 @@ namespace chaiscript
|
||||
{
|
||||
}
|
||||
|
||||
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
{
|
||||
return static_cast<int>(vals.size()) == get_arity()
|
||||
return static_cast<int>(vals.size()) == get_arity()
|
||||
&& (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions));
|
||||
}
|
||||
|
||||
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const noexcept = 0;
|
||||
virtual bool compare_types_with_cast(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -678,7 +678,7 @@ namespace chaiscript
|
||||
{
|
||||
}
|
||||
|
||||
bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
bool compare_types_with_cast(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
{
|
||||
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
|
||||
}
|
||||
@ -690,7 +690,7 @@ namespace chaiscript
|
||||
|
||||
|
||||
protected:
|
||||
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
return detail::call_func(static_cast<Func *>(nullptr), m_f, params, t_conversions);
|
||||
}
|
||||
@ -722,7 +722,7 @@ namespace chaiscript
|
||||
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
|
||||
}
|
||||
|
||||
bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
bool compare_types_with_cast(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override
|
||||
{
|
||||
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
|
||||
}
|
||||
@ -742,7 +742,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
protected:
|
||||
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
return detail::call_func(static_cast<Func *>(nullptr), m_f.get(), params, t_conversions);
|
||||
}
|
||||
@ -765,11 +765,11 @@ namespace chaiscript
|
||||
{
|
||||
}
|
||||
|
||||
bool is_attribute_function() const noexcept override { return true; }
|
||||
bool is_attribute_function() const noexcept override { return true; }
|
||||
|
||||
bool operator==(const Proxy_Function_Base &t_func) const noexcept override
|
||||
{
|
||||
const Attribute_Access<T, Class> * aa
|
||||
const Attribute_Access<T, Class> * aa
|
||||
= dynamic_cast<const Attribute_Access<T, Class> *>(&t_func);
|
||||
|
||||
if (aa) {
|
||||
@ -779,7 +779,7 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
|
||||
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &) const noexcept override
|
||||
bool call_match(const Function_Params &vals, const Type_Conversions_State &) const noexcept override
|
||||
{
|
||||
if (vals.size() != 1)
|
||||
{
|
||||
@ -790,7 +790,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
protected:
|
||||
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||
{
|
||||
const Boxed_Value &bv = params[0];
|
||||
if (bv.is_const())
|
||||
@ -839,22 +839,22 @@ namespace chaiscript
|
||||
{
|
||||
/// \brief Exception thrown in the case that a method dispatch fails
|
||||
/// because no matching function was found
|
||||
///
|
||||
///
|
||||
/// May be thrown due to an arity_error, a guard_error or a bad_boxed_cast
|
||||
/// exception
|
||||
class dispatch_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
dispatch_error(std::vector<Boxed_Value> t_parameters,
|
||||
dispatch_error(const Function_Params &t_parameters,
|
||||
std::vector<Const_Proxy_Function> t_functions)
|
||||
: std::runtime_error("Error with function dispatch"), parameters(std::move(t_parameters)), functions(std::move(t_functions))
|
||||
: std::runtime_error("Error with function dispatch"), parameters(t_parameters.to_vector()), functions(std::move(t_functions))
|
||||
{
|
||||
}
|
||||
|
||||
dispatch_error(std::vector<Boxed_Value> t_parameters,
|
||||
dispatch_error(const Function_Params &t_parameters,
|
||||
std::vector<Const_Proxy_Function> t_functions,
|
||||
const std::string &t_desc)
|
||||
: std::runtime_error(t_desc), parameters(std::move(t_parameters)), functions(std::move(t_functions))
|
||||
: std::runtime_error(t_desc), parameters(t_parameters.to_vector()), functions(std::move(t_functions))
|
||||
{
|
||||
}
|
||||
|
||||
@ -865,14 +865,14 @@ namespace chaiscript
|
||||
std::vector<Boxed_Value> parameters;
|
||||
std::vector<Const_Proxy_Function> functions;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace dispatch
|
||||
{
|
||||
namespace detail
|
||||
namespace detail
|
||||
{
|
||||
template<typename FuncType>
|
||||
bool types_match_except_for_arithmetic(const FuncType &t_func, const std::vector<Boxed_Value> &plist,
|
||||
bool types_match_except_for_arithmetic(const FuncType &t_func, const Function_Params &plist,
|
||||
const Type_Conversions_State &t_conversions) noexcept
|
||||
{
|
||||
const std::vector<Type_Info> &types = t_func->get_param_types();
|
||||
@ -891,7 +891,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
template<typename InItr, typename Funcs>
|
||||
Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const std::vector<Boxed_Value> &plist,
|
||||
Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const Function_Params &plist,
|
||||
const Type_Conversions_State &t_conversions, const Funcs &t_funcs)
|
||||
{
|
||||
InItr matching_func(end);
|
||||
@ -947,7 +947,7 @@ namespace chaiscript
|
||||
);
|
||||
|
||||
try {
|
||||
return (*(matching_func->second))(newplist, t_conversions);
|
||||
return (*(matching_func->second))(Function_Params{newplist}, t_conversions);
|
||||
} catch (const exception::bad_boxed_cast &) {
|
||||
//parameter failed to cast
|
||||
} catch (const exception::arity_error &) {
|
||||
@ -966,7 +966,7 @@ namespace chaiscript
|
||||
/// function is found or throw dispatch_error if no matching function is found
|
||||
template<typename Funcs>
|
||||
Boxed_Value dispatch(const Funcs &funcs,
|
||||
const std::vector<Boxed_Value> &plist, const Type_Conversions_State &t_conversions)
|
||||
const Function_Params &plist, const Type_Conversions_State &t_conversions)
|
||||
{
|
||||
std::vector<std::pair<size_t, const Proxy_Function_Base *>> ordered_funcs;
|
||||
ordered_funcs.reserve(funcs.size());
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "boxed_value.hpp"
|
||||
#include "handle_return.hpp"
|
||||
#include "type_info.hpp"
|
||||
#include "function_params.hpp"
|
||||
|
||||
namespace chaiscript {
|
||||
class Type_Conversions_State;
|
||||
@ -77,7 +78,7 @@ namespace chaiscript
|
||||
*/
|
||||
template<typename Ret, typename ... Params>
|
||||
bool compare_types_cast(Ret (*)(Params...),
|
||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) noexcept
|
||||
const Function_Params ¶ms, const Type_Conversions_State &t_conversions) noexcept
|
||||
{
|
||||
try {
|
||||
std::vector<Boxed_Value>::size_type i = 0;
|
||||
@ -92,7 +93,7 @@ namespace chaiscript
|
||||
template<typename Callable, typename Ret, typename ... Params, size_t ... I>
|
||||
Ret call_func(Ret (*)(Params...),
|
||||
std::index_sequence<I...>, const Callable &f,
|
||||
[[maybe_unused]] const std::vector<Boxed_Value> ¶ms,
|
||||
[[maybe_unused]] const Function_Params ¶ms,
|
||||
[[maybe_unused]] const Type_Conversions_State &t_conversions)
|
||||
{
|
||||
return f(boxed_cast<Params>(params[I], &t_conversions)...);
|
||||
@ -105,7 +106,7 @@ namespace chaiscript
|
||||
/// the bad_boxed_cast is passed up to the caller.
|
||||
template<typename Callable, typename Ret, typename ... Params>
|
||||
Boxed_Value call_func(Ret (*sig)(Params...), const Callable &f,
|
||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions)
|
||||
const Function_Params ¶ms, const Type_Conversions_State &t_conversions)
|
||||
{
|
||||
if constexpr (std::is_same_v<Ret, void>) {
|
||||
call_func(sig, std::index_sequence_for<Params...>{}, f, params, t_conversions);
|
||||
|
||||
@ -95,7 +95,7 @@ namespace chaiscript
|
||||
Logical_And, Logical_Or, Reference, Switch, Case, Default, Noop, Class, Binary, Arg, Global_Decl, Constant, Compiled
|
||||
};
|
||||
|
||||
enum class Operator_Precidence { Ternary_Cond, Logical_Or,
|
||||
enum class Operator_Precedence { Ternary_Cond, Logical_Or,
|
||||
Logical_And, Bitwise_Or, Bitwise_Xor, Bitwise_And,
|
||||
Equality, Comparison, Shift, Addition, Multiplication, Prefix };
|
||||
|
||||
@ -732,12 +732,7 @@ namespace chaiscript
|
||||
m_ds->pop_function_call(m_ds.stack_holder(), m_ds.conversion_saves());
|
||||
}
|
||||
|
||||
void save_params(const std::vector<Boxed_Value> &t_params)
|
||||
{
|
||||
m_ds->save_function_params(t_params);
|
||||
}
|
||||
|
||||
void save_params(std::initializer_list<Boxed_Value> t_params)
|
||||
void save_params(const Function_Params &t_params)
|
||||
{
|
||||
m_ds->save_function_params(t_params);
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ namespace chaiscript
|
||||
|
||||
m_engine.add(
|
||||
dispatch::make_dynamic_proxy_function(
|
||||
[this](const std::vector<Boxed_Value> &t_params) {
|
||||
[this](const Function_Params &t_params) {
|
||||
return m_engine.call_exists(t_params);
|
||||
})
|
||||
, "call_exists");
|
||||
@ -154,7 +154,7 @@ namespace chaiscript
|
||||
m_engine.add(fun(
|
||||
[=](const dispatch::Proxy_Function_Base &t_fun, const std::vector<Boxed_Value> &t_params) -> Boxed_Value {
|
||||
Type_Conversions_State s(this->m_engine.conversions(), this->m_engine.conversions().conversion_saves());
|
||||
return t_fun(t_params, s);
|
||||
return t_fun(Function_Params{t_params}, s);
|
||||
}), "call");
|
||||
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ namespace chaiscript
|
||||
{
|
||||
/// Helper function that will set up the scope around a function call, including handling the named function parameters
|
||||
template<typename T>
|
||||
static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_Node_Impl<T> &t_node, const std::vector<std::string> &t_param_names, const std::vector<Boxed_Value> &t_vals, const std::map<std::string, Boxed_Value> *t_locals=nullptr, bool has_this_capture = false) {
|
||||
static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_Node_Impl<T> &t_node, const std::vector<std::string> &t_param_names, const Function_Params &t_vals, const std::map<std::string, Boxed_Value> *t_locals=nullptr, bool has_this_capture = false) {
|
||||
chaiscript::detail::Dispatch_State state(t_ss);
|
||||
|
||||
const Boxed_Value *thisobj = [&]() -> const Boxed_Value *{
|
||||
@ -183,8 +183,9 @@ namespace chaiscript
|
||||
}
|
||||
} else {
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
fpp.save_params({t_lhs, m_rhs});
|
||||
return t_ss->call_function(t_oper_string, m_loc, {t_lhs, m_rhs}, t_ss.conversions());
|
||||
std::array params{t_lhs, m_rhs};
|
||||
fpp.save_params(Function_Params{params});
|
||||
return t_ss->call_function(t_oper_string, m_loc, Function_Params{params}, t_ss.conversions());
|
||||
}
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
@ -229,8 +230,9 @@ namespace chaiscript
|
||||
}
|
||||
} else {
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
fpp.save_params({t_lhs, t_rhs});
|
||||
return t_ss->call_function(t_oper_string, m_loc, {t_lhs, t_rhs}, t_ss.conversions());
|
||||
std::array params{t_lhs, t_rhs};
|
||||
fpp.save_params(Function_Params(params));
|
||||
return t_ss->call_function(t_oper_string, m_loc, Function_Params(params), t_ss.conversions());
|
||||
}
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
@ -304,13 +306,13 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
if (Save_Params) {
|
||||
fpp.save_params(params);
|
||||
fpp.save_params(Function_Params{params});
|
||||
}
|
||||
|
||||
Boxed_Value fn(this->children[0]->eval(t_ss));
|
||||
|
||||
try {
|
||||
return (*t_ss->boxed_cast<const dispatch::Proxy_Function_Base *>(fn))(params, t_ss.conversions());
|
||||
return (*t_ss->boxed_cast<const dispatch::Proxy_Function_Base *>(fn))(Function_Params{params}, t_ss.conversions());
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, *t_ss);
|
||||
@ -319,7 +321,7 @@ namespace chaiscript
|
||||
try {
|
||||
Const_Proxy_Function f = t_ss->boxed_cast<const Const_Proxy_Function &>(fn);
|
||||
// handle the case where there is only 1 function to try to call and dispatch fails on it
|
||||
throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, {f}, false, *t_ss);
|
||||
throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, make_vector(f), false, *t_ss);
|
||||
} catch (const exception::bad_boxed_cast &) {
|
||||
throw exception::eval_error("'" + this->children[0]->pretty_print() + "' does not evaluate to a function.");
|
||||
}
|
||||
@ -425,25 +427,25 @@ namespace chaiscript
|
||||
|
||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
Boxed_Value rhs = this->children[1]->eval(t_ss);
|
||||
Boxed_Value lhs = this->children[0]->eval(t_ss);
|
||||
|
||||
if (m_oper != Operators::Opers::invalid && lhs.get_type_info().is_arithmetic() &&
|
||||
rhs.get_type_info().is_arithmetic())
|
||||
std::array params{this->children[0]->eval(t_ss), this->children[1]->eval(t_ss)};
|
||||
|
||||
if (m_oper != Operators::Opers::invalid && params[0].get_type_info().is_arithmetic() &&
|
||||
params[0].get_type_info().is_arithmetic())
|
||||
{
|
||||
try {
|
||||
return Boxed_Number::do_oper(m_oper, lhs, rhs);
|
||||
return Boxed_Number::do_oper(m_oper, params[0], params[1]);
|
||||
} catch (const std::exception &) {
|
||||
throw exception::eval_error("Error with unsupported arithmetic assignment operation");
|
||||
}
|
||||
} else if (m_oper == Operators::Opers::assign) {
|
||||
if (lhs.is_return_value()) {
|
||||
if (params[0].is_return_value()) {
|
||||
throw exception::eval_error("Error, cannot assign to temporary value.");
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
if (lhs.is_undef()) {
|
||||
if (params[0].is_undef()) {
|
||||
if (!this->children.empty()
|
||||
&& ((this->children[0]->identifier == AST_Node_Type::Reference)
|
||||
|| (!this->children[0]->children.empty()
|
||||
@ -454,20 +456,20 @@ namespace chaiscript
|
||||
{
|
||||
/// \todo This does not handle the case of an unassigned reference variable
|
||||
/// being assigned outside of its declaration
|
||||
lhs.assign(rhs);
|
||||
lhs.reset_return_value();
|
||||
return rhs;
|
||||
params[0].assign(params[1]);
|
||||
params[0].reset_return_value();
|
||||
return params[1];
|
||||
} else {
|
||||
if (!rhs.is_return_value())
|
||||
if (!params[1].is_return_value())
|
||||
{
|
||||
rhs = t_ss->call_function("clone", m_clone_loc, {rhs}, t_ss.conversions());
|
||||
params[1] = t_ss->call_function("clone", m_clone_loc, Function_Params{¶ms[0], std::end(params)}, t_ss.conversions());
|
||||
}
|
||||
rhs.reset_return_value();
|
||||
params[1].reset_return_value();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return t_ss->call_function(this->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions());
|
||||
return t_ss->call_function(this->text, m_loc, Function_Params{params}, t_ss.conversions());
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Unable to find appropriate'" + this->text + "' operator.", e.parameters, e.functions, false, *t_ss);
|
||||
@ -478,22 +480,22 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
else if (this->text == ":=") {
|
||||
if (lhs.is_undef() || Boxed_Value::type_match(lhs, rhs)) {
|
||||
lhs.assign(rhs);
|
||||
lhs.reset_return_value();
|
||||
if (params[0].is_undef() || Boxed_Value::type_match(params[0], params[1])) {
|
||||
params[0].assign(params[1]);
|
||||
params[0].reset_return_value();
|
||||
} else {
|
||||
throw exception::eval_error("Mismatched types in equation");
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
return t_ss->call_function(this->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions());
|
||||
return t_ss->call_function(this->text, m_loc, Function_Params{params}, t_ss.conversions());
|
||||
} catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Unable to find appropriate'" + this->text + "' operator.", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
}
|
||||
|
||||
return rhs;
|
||||
return params[1];
|
||||
}
|
||||
|
||||
private:
|
||||
@ -550,11 +552,11 @@ namespace chaiscript
|
||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
|
||||
const std::vector<Boxed_Value> params{this->children[0]->eval(t_ss), this->children[1]->eval(t_ss)};
|
||||
std::array params{this->children[0]->eval(t_ss), this->children[1]->eval(t_ss)};
|
||||
|
||||
try {
|
||||
fpp.save_params(params);
|
||||
return t_ss->call_function("[]", m_loc, params, t_ss.conversions());
|
||||
fpp.save_params(Function_Params{params});
|
||||
return t_ss->call_function("[]", m_loc, Function_Params{params}, t_ss.conversions());
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, false, *t_ss );
|
||||
@ -579,7 +581,7 @@ namespace chaiscript
|
||||
|
||||
|
||||
Boxed_Value retval = this->children[0]->eval(t_ss);
|
||||
std::vector<Boxed_Value> params{retval};
|
||||
auto params = make_vector(retval);
|
||||
|
||||
bool has_function_params = false;
|
||||
if (this->children[1]->children.size() > 1) {
|
||||
@ -589,10 +591,10 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
|
||||
fpp.save_params(params);
|
||||
fpp.save_params(Function_Params{params});
|
||||
|
||||
try {
|
||||
retval = t_ss->call_member(m_fun_name, m_loc, std::move(params), has_function_params, t_ss.conversions());
|
||||
retval = t_ss->call_member(m_fun_name, m_loc, Function_Params{params}, has_function_params, t_ss.conversions());
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
if (e.functions.empty())
|
||||
@ -608,7 +610,8 @@ namespace chaiscript
|
||||
|
||||
if (this->children[1]->identifier == AST_Node_Type::Array_Call) {
|
||||
try {
|
||||
retval = t_ss->call_function("[]", m_array_loc, {retval, this->children[1]->children[1]->eval(t_ss)}, t_ss.conversions());
|
||||
std::array p{retval, this->children[1]->children[1]->eval(t_ss)};
|
||||
retval = t_ss->call_function("[]", m_array_loc, Function_Params{p}, t_ss.conversions());
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, true, *t_ss);
|
||||
@ -657,7 +660,7 @@ namespace chaiscript
|
||||
return Boxed_Value(
|
||||
dispatch::make_dynamic_proxy_function(
|
||||
[engine, lambda_node = this->m_lambda_node, param_names = this->m_param_names, captures,
|
||||
this_capture = this->m_this_capture] (const std::vector<Boxed_Value> &t_params)
|
||||
this_capture = this->m_this_capture] (const Function_Params &t_params)
|
||||
{
|
||||
return detail::eval_function(engine, *lambda_node, param_names, t_params, &captures, this_capture);
|
||||
},
|
||||
@ -771,7 +774,7 @@ namespace chaiscript
|
||||
std::shared_ptr<dispatch::Proxy_Function_Base> guard;
|
||||
if (m_guard_node) {
|
||||
guard = dispatch::make_dynamic_proxy_function(
|
||||
[engine, guardnode = m_guard_node, t_param_names](const std::vector<Boxed_Value> &t_params)
|
||||
[engine, guardnode = m_guard_node, t_param_names](const Function_Params &t_params)
|
||||
{
|
||||
return detail::eval_function(engine, *guardnode, t_param_names, t_params);
|
||||
},
|
||||
@ -782,7 +785,7 @@ namespace chaiscript
|
||||
const std::string & l_function_name = this->children[0]->text;
|
||||
t_ss->add(
|
||||
dispatch::make_dynamic_proxy_function(
|
||||
[engine, func_node = m_body_node, t_param_names](const std::vector<Boxed_Value> &t_params)
|
||||
[engine, func_node = m_body_node, t_param_names](const Function_Params &t_params)
|
||||
{
|
||||
return detail::eval_function(engine, *func_node, t_param_names, t_params);
|
||||
},
|
||||
@ -873,7 +876,7 @@ namespace chaiscript
|
||||
};
|
||||
|
||||
const auto call_function = [&t_ss](const auto &t_funcs, const Boxed_Value &t_param) {
|
||||
return dispatch::dispatch(*t_funcs, {t_param}, t_ss.conversions());
|
||||
return dispatch::dispatch(*t_funcs, Function_Params{t_param}, t_ss.conversions());
|
||||
};
|
||||
|
||||
|
||||
@ -988,7 +991,8 @@ namespace chaiscript
|
||||
if (this->children[currentCase]->identifier == AST_Node_Type::Case) {
|
||||
//This is a little odd, but because want to see both the switch and the case simultaneously, I do a downcast here.
|
||||
try {
|
||||
if (hasMatched || boxed_cast<bool>(t_ss->call_function("==", m_loc, {match_value, this->children[currentCase]->children[0]->eval(t_ss)}, t_ss.conversions()))) {
|
||||
std::array p{match_value, this->children[currentCase]->children[0]->eval(t_ss)};
|
||||
if (hasMatched || boxed_cast<bool>(t_ss->call_function("==", m_loc, Function_Params{p}, t_ss.conversions()))) {
|
||||
this->children[currentCase]->eval(t_ss);
|
||||
hasMatched = true;
|
||||
}
|
||||
@ -1057,7 +1061,7 @@ namespace chaiscript
|
||||
for (const auto &child : this->children[0]->children) {
|
||||
if (auto obj = child->eval(t_ss);
|
||||
!obj.is_return_value()) {
|
||||
vec.push_back(t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions()));
|
||||
vec.push_back(t_ss->call_function("clone", m_loc, Function_Params{obj}, t_ss.conversions()));
|
||||
} else {
|
||||
vec.push_back(std::move(obj));
|
||||
}
|
||||
@ -1087,7 +1091,7 @@ namespace chaiscript
|
||||
for (const auto &child : this->children[0]->children) {
|
||||
auto obj = child->children[1]->eval(t_ss);
|
||||
if (!obj.is_return_value()) {
|
||||
obj = t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions());
|
||||
obj = t_ss->call_function("clone", m_loc, Function_Params{obj}, t_ss.conversions());
|
||||
}
|
||||
|
||||
retval[t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss))] = std::move(obj);
|
||||
@ -1174,8 +1178,8 @@ namespace chaiscript
|
||||
return Boxed_Number::do_oper(m_oper, bv);
|
||||
} else {
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
fpp.save_params({bv});
|
||||
return t_ss->call_function(this->text, m_loc, {std::move(bv)}, t_ss.conversions());
|
||||
fpp.save_params(Function_Params{bv});
|
||||
return t_ss->call_function(this->text, m_loc, Function_Params{bv}, t_ss.conversions());
|
||||
}
|
||||
} catch (const exception::dispatch_error &e) {
|
||||
throw exception::eval_error("Error with prefix operator evaluation: '" + this->text + "'", e.parameters, e.functions, false, *t_ss);
|
||||
@ -1240,9 +1244,12 @@ namespace chaiscript
|
||||
|
||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
||||
try {
|
||||
auto oper1 = this->children[0]->children[0]->children[0]->eval(t_ss);
|
||||
auto oper2 = this->children[0]->children[0]->children[1]->eval(t_ss);
|
||||
return t_ss->call_function("generate_range", m_loc, {oper1, oper2}, t_ss.conversions());
|
||||
std::array params{
|
||||
this->children[0]->children[0]->children[0]->eval(t_ss),
|
||||
this->children[0]->children[0]->children[1]->eval(t_ss)
|
||||
};
|
||||
|
||||
return t_ss->call_function("generate_range", m_loc, Function_Params{params}, t_ss.conversions());
|
||||
}
|
||||
catch (const exception::dispatch_error &e) {
|
||||
throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, e.functions, false, *t_ss);
|
||||
@ -1280,7 +1287,7 @@ namespace chaiscript
|
||||
|
||||
if (dispatch::Param_Types(
|
||||
std::vector<std::pair<std::string, Type_Info>>{Arg_List_AST_Node<T>::get_arg_type(*catch_block.children[0], t_ss)}
|
||||
).match(std::vector<Boxed_Value>{t_except}, t_ss.conversions()).first)
|
||||
).match(Function_Params{t_except}, t_ss.conversions()).first)
|
||||
{
|
||||
t_ss.add_object(name, t_except);
|
||||
|
||||
@ -1410,7 +1417,7 @@ namespace chaiscript
|
||||
std::reference_wrapper<chaiscript::detail::Dispatch_Engine> engine(*t_ss);
|
||||
if (m_guard_node) {
|
||||
guard = dispatch::make_dynamic_proxy_function(
|
||||
[engine, t_param_names, guardnode = m_guard_node](const std::vector<Boxed_Value> &t_params) {
|
||||
[engine, t_param_names, guardnode = m_guard_node](const Function_Params &t_params) {
|
||||
return chaiscript::eval::detail::eval_function(engine, *guardnode, t_param_names, t_params);
|
||||
},
|
||||
static_cast<int>(numparams), m_guard_node);
|
||||
@ -1425,7 +1432,7 @@ namespace chaiscript
|
||||
t_ss->add(
|
||||
std::make_shared<dispatch::detail::Dynamic_Object_Constructor>(class_name,
|
||||
dispatch::make_dynamic_proxy_function(
|
||||
[engine, t_param_names, node = m_body_node](const std::vector<Boxed_Value> &t_params) {
|
||||
[engine, t_param_names, node = m_body_node](const Function_Params &t_params) {
|
||||
return chaiscript::eval::detail::eval_function(engine, *node, t_param_names, t_params);
|
||||
},
|
||||
static_cast<int>(numparams), m_body_node, param_types, guard
|
||||
@ -1442,7 +1449,7 @@ namespace chaiscript
|
||||
t_ss->add(
|
||||
std::make_shared<dispatch::detail::Dynamic_Object_Function>(class_name,
|
||||
dispatch::make_dynamic_proxy_function(
|
||||
[engine, t_param_names, node = m_body_node](const std::vector<Boxed_Value> &t_params) {
|
||||
[engine, t_param_names, node = m_body_node](const Function_Params &t_params) {
|
||||
return chaiscript::eval::detail::eval_function(engine, *node, t_param_names, t_params);
|
||||
},
|
||||
static_cast<int>(numparams), m_body_node, param_types, guard), type),
|
||||
|
||||
@ -263,20 +263,20 @@ namespace chaiscript
|
||||
|
||||
};
|
||||
|
||||
constexpr static std::array<Operator_Precidence, 12> create_operators() noexcept {
|
||||
std::array<Operator_Precidence, 12> operators = { {
|
||||
Operator_Precidence::Ternary_Cond,
|
||||
Operator_Precidence::Logical_Or,
|
||||
Operator_Precidence::Logical_And,
|
||||
Operator_Precidence::Bitwise_Or,
|
||||
Operator_Precidence::Bitwise_Xor,
|
||||
Operator_Precidence::Bitwise_And,
|
||||
Operator_Precidence::Equality,
|
||||
Operator_Precidence::Comparison,
|
||||
Operator_Precidence::Shift,
|
||||
Operator_Precidence::Addition,
|
||||
Operator_Precidence::Multiplication,
|
||||
Operator_Precidence::Prefix
|
||||
constexpr static std::array<Operator_Precedence, 12> create_operators() noexcept {
|
||||
std::array<Operator_Precedence, 12> operators = { {
|
||||
Operator_Precedence::Ternary_Cond,
|
||||
Operator_Precedence::Logical_Or,
|
||||
Operator_Precedence::Logical_And,
|
||||
Operator_Precedence::Bitwise_Or,
|
||||
Operator_Precedence::Bitwise_Xor,
|
||||
Operator_Precedence::Bitwise_And,
|
||||
Operator_Precedence::Equality,
|
||||
Operator_Precedence::Comparison,
|
||||
Operator_Precedence::Shift,
|
||||
Operator_Precedence::Addition,
|
||||
Operator_Precedence::Multiplication,
|
||||
Operator_Precedence::Prefix
|
||||
} };
|
||||
return operators;
|
||||
}
|
||||
@ -2363,7 +2363,7 @@ namespace chaiscript
|
||||
bool retval = false;
|
||||
const auto prev_stack_top = m_match_stack.size();
|
||||
|
||||
if (m_operators[t_precedence] != Operator_Precidence::Prefix) {
|
||||
if (m_operators[t_precedence] != Operator_Precedence::Prefix) {
|
||||
if (Operator(t_precedence+1)) {
|
||||
retval = true;
|
||||
std::string oper;
|
||||
@ -2375,7 +2375,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
switch (m_operators[t_precedence]) {
|
||||
case(Operator_Precidence::Ternary_Cond) :
|
||||
case(Operator_Precedence::Ternary_Cond) :
|
||||
if (Symbol(":")) {
|
||||
if (!Operator(t_precedence+1)) {
|
||||
throw exception::eval_error("Incomplete '" + oper + "' expression",
|
||||
@ -2389,24 +2389,24 @@ namespace chaiscript
|
||||
}
|
||||
break;
|
||||
|
||||
case(Operator_Precidence::Addition) :
|
||||
case(Operator_Precidence::Multiplication) :
|
||||
case(Operator_Precidence::Shift) :
|
||||
case(Operator_Precidence::Equality) :
|
||||
case(Operator_Precidence::Bitwise_And) :
|
||||
case(Operator_Precidence::Bitwise_Xor) :
|
||||
case(Operator_Precidence::Bitwise_Or) :
|
||||
case(Operator_Precidence::Comparison) :
|
||||
case(Operator_Precedence::Addition) :
|
||||
case(Operator_Precedence::Multiplication) :
|
||||
case(Operator_Precedence::Shift) :
|
||||
case(Operator_Precedence::Equality) :
|
||||
case(Operator_Precedence::Bitwise_And) :
|
||||
case(Operator_Precedence::Bitwise_Xor) :
|
||||
case(Operator_Precedence::Bitwise_Or) :
|
||||
case(Operator_Precedence::Comparison) :
|
||||
build_match<eval::Binary_Operator_AST_Node<Tracer>>(prev_stack_top, oper);
|
||||
break;
|
||||
|
||||
case(Operator_Precidence::Logical_And) :
|
||||
case(Operator_Precedence::Logical_And) :
|
||||
build_match<eval::Logical_And_AST_Node<Tracer>>(prev_stack_top, oper);
|
||||
break;
|
||||
case(Operator_Precidence::Logical_Or) :
|
||||
case(Operator_Precedence::Logical_Or) :
|
||||
build_match<eval::Logical_Or_AST_Node<Tracer>>(prev_stack_top, oper);
|
||||
break;
|
||||
case(Operator_Precidence::Prefix) :
|
||||
case(Operator_Precedence::Prefix) :
|
||||
assert(false); // cannot reach here because of if() statement at the top
|
||||
break;
|
||||
|
||||
|
||||
63
include/chaiscript/utility/stack_vector.hpp
Normal file
63
include/chaiscript/utility/stack_vector.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
// This file is distributed under the BSD License.
|
||||
// See "license.txt" for details.
|
||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||
// Copyright 2009-2017, Jason Turner (jason@emptycrate.com)
|
||||
// http://www.chaiscript.com
|
||||
|
||||
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
|
||||
|
||||
#ifndef CHAISCRIPT_STACK_VECTOR_HPP_
|
||||
#define CHAISCRIPT_STACK_VECTOR_HPP_
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
template<typename T, std::size_t MaxSize>
|
||||
struct Stack_Vector
|
||||
{
|
||||
constexpr static auto aligned_size = sizeof(T) + (sizeof(T) & std::alignment_of_v<T>) > 0 ? std::alignment_of_v<T> : 0;
|
||||
|
||||
alignas(std::alignment_of_v<T>) char data[aligned_size * MaxSize];
|
||||
|
||||
[[nodiscard]] T & operator[](const std::size_t idx) noexcept {
|
||||
return *reinterpret_cast<T*>(&data + aligned_size * idx);
|
||||
}
|
||||
|
||||
[[nodiscard]] const T & operator[](const std::size_t idx) const noexcept {
|
||||
return *reinterpret_cast<const T*>(&data + aligned_size * idx);
|
||||
}
|
||||
|
||||
template<typename ... Param>
|
||||
T& emplace_back(Param && ... param) {
|
||||
auto *p = new(&(*this)[m_size++]) T(std::forward<Param>(param)...);
|
||||
return *p;
|
||||
};
|
||||
|
||||
auto size() const noexcept {
|
||||
return m_size;
|
||||
};
|
||||
|
||||
void pop_back() noexcept(std::is_nothrow_destructible_v<T>) {
|
||||
(*this)[m_size--].~T();
|
||||
}
|
||||
|
||||
~Stack_Vector() noexcept(std::is_nothrow_destructible_v<T>)
|
||||
{
|
||||
auto loc = m_size - 1;
|
||||
for (std::size_t pos = 0; pos < m_size; ++pos) {
|
||||
(*this)[loc--].~T();
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t m_size{0};
|
||||
|
||||
};
|
||||
|
||||
#endif CHAISCRIPT_STACK_VECTOR_HPP_
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user