11#ifndef CHAISCRIPT_PROXY_FUNCTIONS_HPP_
12#define CHAISCRIPT_PROXY_FUNCTIONS_HPP_
48 template<
typename FunctionType>
59 explicit Param_Types(std::vector<std::pair<std::string, Type_Info>> t_types)
60 : m_types(
std::move(t_types)),
69 m_types.emplace(m_types.begin(), std::move(t_name), t_ti);
75 return m_types == t_rhs.m_types;
80 for (
size_t i = 0; i < vals.size(); ++i)
82 const auto &
name = m_types[i].first;
84 const auto &bv = vals[i];
86 if (!bv.get_type_info().bare_equal(m_doti))
88 const auto &ti = m_types[i].second;
91 if (!bv.get_type_info().bare_equal(ti)) {
92 if (t_conversions->
converts(ti, bv.get_type_info())) {
119 bool needs_conversion =
false;
121 if (!m_has_types) {
return std::make_pair(
true, needs_conversion); }
122 if (vals.size() != m_types.size()) {
return std::make_pair(
false, needs_conversion); }
124 for (
size_t i = 0; i < vals.size(); ++i)
126 const auto &
name = m_types[i].first;
128 const auto &bv = vals[i];
130 if (bv.get_type_info().bare_equal(m_doti))
134 if (!(
name ==
"Dynamic_Object" ||
d.get_type_name() ==
name)) {
135 return std::make_pair(
false,
false);
137 }
catch (
const std::bad_cast &) {
138 return std::make_pair(
false,
false);
141 const auto &ti = m_types[i].second;
144 if (!bv.get_type_info().bare_equal(ti)) {
145 if (!t_conversions->
converts(ti, bv.get_type_info())) {
146 return std::make_pair(
false,
false);
148 needs_conversion =
true;
152 return std::make_pair(
false,
false);
158 return std::make_pair(
true, needs_conversion);
161 const std::vector<std::pair<std::string, Type_Info>> &
types()
const
167 void update_has_types()
169 for (
const auto &type : m_types)
171 if (!type.first.empty())
181 std::vector<std::pair<std::string, Type_Info>> m_types;
203 return do_call(params, t_conversions);
227 return std::vector<std::shared_ptr<const Proxy_Function_Base> >();
282 for (
size_t i = 1; i <
m_types.size(); ++i)
284 if (
m_types[i].is_arithmetic())
294 static bool compare_types(
const std::vector<Type_Info> &tis,
const std::vector<Boxed_Value> &bvs,
297 if (tis.size() - 1 != bvs.size())
301 const size_t size = bvs.size();
302 for (
size_t i = 0; i <
size; ++i)
330 :
std::runtime_error(
"Guard evaluation failed")
350 std::shared_ptr<AST_Node> t_parsenode,
355 m_guard(
std::move(t_guard)), m_parsenode(
std::move(t_parsenode))
366 || ((prhs !=
nullptr)
368 && !this->m_guard && !prhs->m_guard
384 return static_cast<bool>(m_parsenode);
392 throw std::runtime_error(
"Dynamic_Proxy_Function does not have parse_tree");
418 const auto comparison_result = [&](){
420 return std::make_pair(
true,
false);
421 }
else if (vals.size() ==
size_t(
m_arity)) {
424 return std::make_pair(
false,
false);
428 return std::make_pair(
429 comparison_result.first &&
test_guard(vals, t_conversions),
430 comparison_result.second
435 static std::vector<Type_Info> build_param_type_list(
const Param_Types &t_types)
440 for (
const auto &t : t_types.
types())
442 if (t.second.is_undef()) {
445 types.push_back(t.second);
457 std::shared_ptr<AST_Node> m_parsenode;
462 template<
typename Callable>
469 std::shared_ptr<AST_Node> t_parsenode =
AST_NodePtr(),
474 std::move(t_parsenode),
475 std::move(t_param_types),
487 if (match_results.first)
489 if (match_results.second) {
503 template<
typename Callable,
typename ...
Arg>
507 std::forward<Callable>(c), std::forward<Arg>(a)...);
524 const std::vector<Boxed_Value> &t_args)
526 m_f(t_f), m_args(t_args)
528 assert(m_f->get_arity() < 0 || m_f->get_arity() ==
static_cast<int>(m_args.size()));
544 return std::vector<Const_Proxy_Function>{m_f};
550 auto parg = params.begin();
551 auto barg = m_args.begin();
553 std::vector<Boxed_Value> args;
555 while (!(parg == params.end() && barg == m_args.end()))
557 while (barg != m_args.end()
560 args.push_back(*barg);
564 if (parg != params.end())
566 args.push_back(*parg);
570 if (barg != m_args.end()
582 const std::vector<Boxed_Value> &t_args)
584 assert(t_f->get_arity() < 0 || t_f->get_arity() ==
static_cast<int>(t_args.size()));
586 if (t_f->get_arity() < 0) {
return std::vector<Type_Info>(); }
588 const auto types = t_f->get_param_types();
589 assert(types.size() == t_args.size() + 1);
592 std::vector<Type_Info> retval{types[0]};
594 for (
size_t i = 0; i < types.size() - 1; ++i)
598 retval.push_back(types[i+1]);
612 std::vector<Boxed_Value> m_args;
625 return static_cast<int>(vals.size()) ==
get_arity()
635 template<
typename Func,
typename Callable>
675 virtual void assign(
const std::shared_ptr<const Proxy_Function_Base> &t_rhs) = 0;
678 template<
typename Func>
684 m_f(
std::move(t_f)), m_shared_ptr_holder(
std::move(t_ptr))
686 assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
704 void assign(
const std::shared_ptr<const Proxy_Function_Base> &t_rhs)
override {
716 std::reference_wrapper<std::function<Func>> m_f;
717 std::shared_ptr<std::function<Func>> m_shared_ptr_holder;
722 template<
typename T,
typename Class>
740 return m_attr == aa->m_attr;
748 if (vals.size() != 1)
763 return do_call_impl<T>(o);
766 return do_call_impl<T>(o);
771 template<
typename Type>
772 auto do_call_impl(
Class *o)
const -> std::enable_if_t<std::is_pointer<Type>::value,
Boxed_Value>
777 template<
typename Type>
778 auto do_call_impl(
const Class *o)
const -> std::enable_if_t<std::is_pointer<Type>::value,
Boxed_Value>
780 return detail::Handle_Return<const Type>::handle(o->*m_attr);
783 template<
typename Type>
784 auto do_call_impl(
Class *o)
const -> std::enable_if_t<!std::is_pointer<Type>::value, Boxed_Value>
786 return detail::Handle_Return<typename std::add_lvalue_reference<Type>::type>::handle(o->*m_attr);
789 template<
typename Type>
790 auto do_call_impl(
const Class *o)
const -> std::enable_if_t<!std::is_pointer<Type>::value, Boxed_Value>
792 return detail::Handle_Return<typename std::add_lvalue_reference<typename std::add_const<Type>::type>::type>::handle(o->*m_attr);
797 static std::vector<Type_Info> param_types()
799 return {user_type<T>(), user_type<Class>()};
817 std::vector<Const_Proxy_Function> t_functions)
823 std::vector<Const_Proxy_Function> t_functions,
824 const std::string &t_desc)
842 template<
typename FuncType>
846 const std::vector<Type_Info> &types = t_func->get_param_types();
848 if (t_func->get_arity() == -1) {
return false; }
850 assert(plist.size() == types.size() - 1);
852 return std::mismatch(plist.begin(), plist.end(),
855 return Proxy_Function_Base::compare_type_to_param(ti, bv, t_conversions)
856 || (bv.get_type_info().is_arithmetic() && ti.is_arithmetic());
858 ) == std::make_pair(plist.end(), types.end());
861 template<
typename InItr,
typename Funcs>
865 InItr matching_func(end);
871 if (matching_func == end)
873 matching_func = begin;
876 const auto &mat_fun_param_types = matching_func->second->get_param_types();
877 const auto &next_fun_param_types = begin->second->get_param_types();
879 if (plist[0].is_const() && !mat_fun_param_types[1].is_const() && next_fun_param_types[1].is_const()) {
880 matching_func = begin;
881 }
else if (!plist[0].is_const() && !mat_fun_param_types[1].is_const() && next_fun_param_types[1].is_const()) {
893 if (matching_func == end)
900 std::vector<Boxed_Value> newplist;
901 newplist.reserve(plist.size());
903 const std::vector<Type_Info> &tis = matching_func->second->get_param_types();
904 std::transform(tis.begin() + 1, tis.end(),
906 std::back_inserter(newplist),
908 if (ti.is_arithmetic() && param.get_type_info().is_arithmetic()
909 && param.get_type_info() != ti) {
910 return Boxed_Number(param).get_as(ti).bv;
918 return (*(matching_func->second))(newplist, t_conversions);
921 }
catch (
const exception::arity_error &) {
923 }
catch (
const exception::guard_error &) {
927 throw exception::dispatch_error(plist, std::vector<Const_Proxy_Function>(t_funcs.begin(), t_funcs.end()));
935 template<
typename Funcs>
939 std::vector<std::pair<size_t, const Proxy_Function_Base *>> ordered_funcs;
940 ordered_funcs.reserve(funcs.size());
942 for (
const auto &
func : funcs)
944 const auto arity =
func->get_arity();
948 ordered_funcs.emplace_back(plist.size(),
func.get());
949 }
else if (arity ==
static_cast<int>(plist.size())) {
951 for (
size_t i = 0; i < plist.size(); ++i)
953 if (!
func->get_param_types()[i+1].bare_equal(plist[i].get_type_info()))
958 ordered_funcs.emplace_back(numdiffs,
func.get());
963 for (
size_t i = 0; i <= plist.size(); ++i)
965 for (
const auto &
func : ordered_funcs )
968 if (
func.first == i && (i == 0 ||
func.second->filter(plist, t_conversions)))
970 return (*(
func.second))(plist, t_conversions);
P func(int c, EveryApi &ev)
Definition test.cpp:59
int get_arity() const
Returns the arity of the function, -1 if the function takes a variable number of parameters.
Represents any numeric type, generically. Used internally for generic operations between POD values.
Definition boxed_number.hpp:66
A wrapper for holding any valid C++ type. All types in ChaiScript are Boxed_Value objects.
Definition boxed_value.hpp:28
bool is_const() const noexcept
Definition boxed_value.hpp:235
const Type_Info & get_type_info() const noexcept
Definition boxed_value.hpp:224
Definition type_conversions.hpp:512
Type_Conversions::Conversion_Saves & saves() const
Definition type_conversions.hpp:529
Definition type_conversions.hpp:321
bool converts() const
Definition type_conversions.hpp:379
Boxed_Value boxed_type_conversion(Conversion_Saves &t_saves, const Boxed_Value &from) const
Definition type_conversions.hpp:396
Boxed_Value boxed_type_down_conversion(Conversion_Saves &t_saves, const Boxed_Value &to) const
Definition type_conversions.hpp:402
Compile time deduced information about a type.
Definition type_info.hpp:34
constexpr bool is_undef() const noexcept
Definition type_info.hpp:90
constexpr bool is_arithmetic() const noexcept
Definition type_info.hpp:89
constexpr bool bare_equal(const Type_Info &ti) const noexcept
Definition type_info.hpp:75
Thrown in the event that an Any cannot be cast to the desired type.
Definition any.hpp:22
std::function< Func > internal_function() const
Definition proxy_functions.hpp:699
Assignable_Proxy_Function_Impl(std::reference_wrapper< std::function< Func > > t_f, std::shared_ptr< std::function< Func > > t_ptr)
Definition proxy_functions.hpp:682
bool compare_types_with_cast(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:689
void assign(const std::shared_ptr< const Proxy_Function_Base > &t_rhs) override
Definition proxy_functions.hpp:704
bool operator==(const Proxy_Function_Base &t_func) const override
Definition proxy_functions.hpp:694
Boxed_Value do_call(const std::vector< Boxed_Value > ¶ms, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:709
virtual void assign(const std::shared_ptr< const Proxy_Function_Base > &t_rhs)=0
Assignable_Proxy_Function(const std::vector< Type_Info > &t_types)
Definition proxy_functions.hpp:670
Attribute_Access(T Class::*t_attr)
Definition proxy_functions.hpp:726
Boxed_Value do_call(const std::vector< Boxed_Value > ¶ms, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:757
bool is_attribute_function() const override
Definition proxy_functions.hpp:732
bool operator==(const Proxy_Function_Base &t_func) const override
Definition proxy_functions.hpp:734
bool call_match(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &) const override
Definition proxy_functions.hpp:746
Bound_Function(const Const_Proxy_Function &t_f, const std::vector< Boxed_Value > &t_args)
Definition proxy_functions.hpp:523
std::vector< Boxed_Value > build_param_list(const std::vector< Boxed_Value > ¶ms) const
Definition proxy_functions.hpp:548
Boxed_Value do_call(const std::vector< Boxed_Value > ¶ms, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:605
bool operator==(const Proxy_Function_Base &t_f) const override
Definition proxy_functions.hpp:531
std::vector< Const_Proxy_Function > get_contained_functions() const override
Definition proxy_functions.hpp:542
static std::vector< Type_Info > build_param_type_info(const Const_Proxy_Function &t_f, const std::vector< Boxed_Value > &t_args)
Definition proxy_functions.hpp:581
bool call_match(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:537
Definition dynamic_object.hpp:44
Dynamic_Proxy_Function_Impl(Callable t_f, int t_arity=-1, std::shared_ptr< AST_Node > t_parsenode=AST_NodePtr(), Param_Types t_param_types=Param_Types(), Proxy_Function t_guard=Proxy_Function())
Definition proxy_functions.hpp:466
Boxed_Value do_call(const std::vector< Boxed_Value > ¶ms, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:484
Proxy_Function get_guard() const
Definition proxy_functions.hpp:378
bool has_parse_tree() const
Definition proxy_functions.hpp:383
bool call_match(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:372
Dynamic_Proxy_Function(const int t_arity, std::shared_ptr< AST_Node > t_parsenode, Param_Types t_param_types=Param_Types(), Proxy_Function t_guard=Proxy_Function())
Definition proxy_functions.hpp:348
const AST_Node & get_parse_tree() const
Definition proxy_functions.hpp:387
std::pair< bool, bool > call_match_internal(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const
Definition proxy_functions.hpp:416
bool operator==(const Proxy_Function_Base &rhs) const override
Definition proxy_functions.hpp:361
bool test_guard(const std::vector< Boxed_Value > ¶ms, const Type_Conversions_State &t_conversions) const
Definition proxy_functions.hpp:398
Param_Types m_param_types
Definition proxy_functions.hpp:453
Definition proxy_functions.hpp:52
std::vector< Boxed_Value > convert(std::vector< Boxed_Value > vals, const Type_Conversions_State &t_conversions) const
Definition proxy_functions.hpp:78
Param_Types(std::vector< std::pair< std::string, Type_Info > > t_types)
Definition proxy_functions.hpp:59
void push_front(std::string t_name, Type_Info t_ti)
Definition proxy_functions.hpp:67
Param_Types()
Definition proxy_functions.hpp:54
bool operator==(const Param_Types &t_rhs) const
Definition proxy_functions.hpp:73
const std::vector< std::pair< std::string, Type_Info > > & types() const
Definition proxy_functions.hpp:161
std::pair< bool, bool > match(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const
Definition proxy_functions.hpp:117
Definition proxy_functions.hpp:196
static bool compare_types(const std::vector< Type_Info > &tis, const std::vector< Boxed_Value > &bvs, const Type_Conversions_State &t_conversions)
Definition proxy_functions.hpp:294
virtual bool is_attribute_function() const
Definition proxy_functions.hpp:218
virtual Boxed_Value do_call(const std::vector< Boxed_Value > ¶ms, const Type_Conversions_State &t_conversions) const =0
bool m_has_arithmetic_param
Definition proxy_functions.hpp:312
bool has_arithmetic_param() const
Definition proxy_functions.hpp:220
bool filter(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const
Definition proxy_functions.hpp:232
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const
Definition proxy_functions.hpp:271
Proxy_Function_Base(std::vector< Type_Info > t_types, int t_arity)
Definition proxy_functions.hpp:279
virtual bool call_match(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const =0
std::vector< Type_Info > m_types
Definition proxy_functions.hpp:310
virtual ~Proxy_Function_Base()=default
virtual bool operator==(const Proxy_Function_Base &) const =0
int get_arity() const
Definition proxy_functions.hpp:247
Boxed_Value operator()(const std::vector< Boxed_Value > ¶ms, const chaiscript::Type_Conversions_State &t_conversions) const
Definition proxy_functions.hpp:200
int m_arity
Definition proxy_functions.hpp:311
virtual std::vector< std::shared_ptr< const Proxy_Function_Base > > get_contained_functions() const
Definition proxy_functions.hpp:225
static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions_State &t_conversions)
Definition proxy_functions.hpp:252
const std::vector< Type_Info > & get_param_types() const
Definition proxy_functions.hpp:213
Boxed_Value do_call(const std::vector< Boxed_Value > ¶ms, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:657
bool operator==(const Proxy_Function_Base &t_func) const override
Definition proxy_functions.hpp:650
bool compare_types_with_cast(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:645
Proxy_Function_Callable_Impl(Callable f)
Definition proxy_functions.hpp:639
bool call_match(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const override
Definition proxy_functions.hpp:623
virtual bool compare_types_with_cast(const std::vector< Boxed_Value > &vals, const Type_Conversions_State &t_conversions) const =0
Proxy_Function_Impl_Base(const std::vector< Type_Info > &t_types)
Definition proxy_functions.hpp:618
Thrown in the event that a Boxed_Value cannot be cast to the desired type.
Definition bad_boxed_cast.hpp:34
Exception thrown in the case that a method dispatch fails because no matching function was found.
Definition proxy_functions.hpp:814
~dispatch_error() noexcept override=default
std::vector< Const_Proxy_Function > functions
Definition proxy_functions.hpp:834
dispatch_error(const dispatch_error &)=default
std::vector< Boxed_Value > parameters
Definition proxy_functions.hpp:833
dispatch_error(std::vector< Boxed_Value > t_parameters, std::vector< Const_Proxy_Function > t_functions, const std::string &t_desc)
Definition proxy_functions.hpp:822
dispatch_error(std::vector< Boxed_Value > t_parameters, std::vector< Const_Proxy_Function > t_functions)
Definition proxy_functions.hpp:816
Exception thrown if a function's guard fails.
Definition proxy_functions.hpp:327
guard_error() noexcept
Definition proxy_functions.hpp:329
~guard_error() noexcept override=default
guard_error(const guard_error &)=default
d
Definition meshpage.php:3895
iVBORw0KGgoAAAANSUhEUgAAANcAAAB5CAMAAACdtUQZAAAA51BMVEX</div ></div >< div style="padding: 0px 0px; width: 1324px;">< div style="height: 400px; width: 1324px;"></div >< div itemscope itemtype="https: </div><div itemscope itemtype="https:</div >< div itemscope itemtype="https: </div></div><p><div style="padding:0px 0px;width:1324px;"><div></div><div itemscope itemtype="https:< ul >< li >< b > Application name
8AkrcAgqgAs9wqQ0ey2tkAo8gAuuQfeI4hPUH09fXHy8z4+fng4uNKXF/Lz9BzfoAcgpkQMTUAKjAbOT4Qr9AXhJ8Rl7ktMCwTosA...
Definition meshpage.php:1610
n< br > font size
Definition meshpage.php:3536
Classes and functions reserved for internal use. Items in this namespace are not supported.
Definition callable_traits.hpp:14
Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const std::vector< Boxed_Value > &plist, const Type_Conversions_State &t_conversions, const Funcs &t_funcs)
Definition proxy_functions.hpp:862
Ret call_func(const chaiscript::dispatch::detail::Function_Signature< Ret(Params...)> &, std::index_sequence< I... >, const Callable &f, const std::vector< Boxed_Value > ¶ms, const Type_Conversions_State &t_conversions)
Definition proxy_functions_detail.hpp:97
bool compare_types_cast(Ret(*)(Params...), const std::vector< Boxed_Value > ¶ms, const Type_Conversions_State &t_conversions)
Definition proxy_functions_detail.hpp:80
bool types_match_except_for_arithmetic(const FuncType &t_func, const std::vector< Boxed_Value > &plist, const Type_Conversions_State &t_conversions)
Definition proxy_functions.hpp:843
Classes and functions specific to the runtime dispatch side of ChaiScript. Some items may be of use t...
Definition callable_traits.hpp:13
Proxy_Function make_dynamic_proxy_function(Callable &&c, Arg &&... a)
Definition proxy_functions.hpp:504
Boxed_Value dispatch(const Funcs &funcs, const std::vector< Boxed_Value > &plist, const Type_Conversions_State &t_conversions)
Definition proxy_functions.hpp:936
std::function< FunctionType > functor(const std::vector< Const_Proxy_Function > &funcs, const Type_Conversions_State *t_conversions)
Definition function_call.hpp:42
Classes which may be thrown during error cases when ChaiScript is executing.
Definition bad_boxed_cast.hpp:27
Namespace chaiscript contains every API call that the average user will be concerned with.
std::shared_ptr< dispatch::Proxy_Function_Base > Proxy_Function
Common typedef used for passing of any registered function in ChaiScript.
Definition proxy_functions.hpp:317
std::shared_ptr< const dispatch::Proxy_Function_Base > Const_Proxy_Function
Const version of Proxy_Function. Points to a const Proxy_Function. This is how most registered functi...
Definition proxy_functions.hpp:321
constexpr Type_Info user_type(const T &)
Creates a Type_Info object representing the type passed in.
Definition type_info.hpp:221
decltype(auto) boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions=nullptr)
Function for extracting a value stored in a Boxed_Value object.
Definition boxed_cast.hpp:76
std::shared_ptr< B > make_shared(Arg &&... arg)
Definition chaiscript_defines.hpp:87
@ Arg
Definition chaiscript_common.hpp:69
@ Class
Definition chaiscript_common.hpp:69
std::unique_ptr< AST_Node > AST_NodePtr
Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree.
Definition proxy_functions.hpp:44
double f(const std::string &, double, bool) noexcept
Definition profile_cpp_calls_2.cpp:4
Struct that doubles as both a parser ast_node and an AST node.
Definition chaiscript_common.hpp:497
static constexpr Type_Info get()
Definition type_info.hpp:138
Definition proxy_functions.hpp:513
Definition callable_traits.hpp:78
static Boxed_Value handle(T r)
Definition handle_return.hpp:40
Definition proxy_functions_detail.hpp:42