9#include "../../core/eosio/serialize.hpp"
10#include "../../core/eosio/datastream.hpp"
11#include "../../core/eosio/name.hpp"
12#include "../../core/eosio/fixed_bytes.hpp"
13#include "../../core/eosio/ignore.hpp"
14#include "../../core/eosio/time.hpp"
18 namespace internal_use_do_not_use {
42 void send_inline(
char *serialized_action,
size_t size);
45 void send_context_free_inline(
char *serialized_action,
size_t size);
95 constexpr size_t max_stack_buffer_size = 512;
97 char* buffer = (
char*)( max_stack_buffer_size <
size ? malloc(
size) : alloca(
size) );
99 return unpack<T>( buffer,
size );
130 template<
typename... accounts>
171 if (full_result ==
nullptr)
173 constexpr size_t max_stack_buffer_size = 50;
177 char* struct_buffer = (
char*)alloca(struct_buffer_size);
180 const VersionType STRUCT_VERSION = 0;
184 bool buffer_on_heap =
false;
185 if (response_size > struct_buffer_size) {
188 if (response_size > max_stack_buffer_size) {
189 struct_buffer = (
char*)malloc(response_size);
190 buffer_on_heap =
true;
192 struct_buffer = (
char*)alloca(response_size);
197 check(unpack<VersionType>(struct_buffer, struct_buffer_size) == STRUCT_VERSION,
198 "Hypervisor returned unexpected code hash struct version");
199 unpack(*full_result, struct_buffer, struct_buffer_size);
205 return full_result->code_hash;
359 :account(a),
name(n), authorization(1,auth), data(
pack(std::forward<T>(value))) {}
371 action( std::vector<permission_level> auths,
struct name a,
struct name n, T&& value )
372 :account(a),
name(n), authorization(std::move(auths)), data(
pack(std::forward<T>(value))) {}
384 auto serialize =
pack(*
this);
385 internal_use_do_not_use::send_inline(serialize.data(), serialize.size());
394 eosio::check( authorization.size() == 0,
"context free actions cannot have authorizations");
395 auto serialize =
pack(*
this);
396 internal_use_do_not_use::send_context_free_inline(serialize.data(), serialize.size());
407 return unpack<T>( &data[0], data.size() );
418 template <
typename T>
419 struct unwrap {
typedef T type; };
421 template <
typename T>
422 struct unwrap<ignore<T>> {
typedef T type; };
424 template <
typename R,
typename Act,
typename... Args>
425 auto get_args(R(Act::*p)(Args...)) {
426 return std::tuple<std::decay_t<typename unwrap<Args>::type>...>{};
429 template <
typename R,
typename Act,
typename... Args>
430 auto get_args_nounwrap(R(Act::*p)(Args...)) {
431 return std::tuple<std::decay_t<Args>...>{};
434 template <auto Action>
435 using deduced =
decltype(get_args(Action));
437 template <auto Action>
438 using deduced_nounwrap =
decltype(get_args_nounwrap(Action));
440 template <
typename T>
441 struct convert {
typedef T type; };
444 struct convert<const char*> {
typedef std::string type; };
447 struct convert<char*> {
typedef std::string type; };
449 template <
typename T,
typename U>
450 struct is_same {
static constexpr bool value = std::is_convertible<T,U>::value; };
452 template <
typename U>
453 struct is_same<bool,U> {
static constexpr bool value = std::is_integral<U>::value; };
455 template <
typename T>
456 struct is_same<T,bool> {
static constexpr bool value = std::is_integral<T>::value; };
458 template <
size_t N,
size_t I,
auto Arg,
auto... Args>
459 struct get_nth_impl {
static constexpr auto value = get_nth_impl<N,I+1,Args...>::value; };
461 template <
size_t N,
auto Arg,
auto... Args>
462 struct get_nth_impl<N, N, Arg, Args...> {
static constexpr auto value = Arg; };
464 template <
size_t N,
auto... Args>
465 struct get_nth {
static constexpr auto value = get_nth_impl<N,0,Args...>::value; };
467 template <
auto Action,
size_t I,
typename T,
typename... Rest>
469 static_assert(detail::is_same<typename convert<T>::type,
typename convert<typename std::tuple_element<I, deduced<Action>>::type>::type>::value);
470 using type = check_types<Action, I+1, Rest...>;
471 static constexpr bool value =
true;
473 template <auto Action,
size_t I,
typename T>
474 struct check_types<Action, I, T> {
475 static_assert(detail::is_same<typename convert<T>::type,
typename convert<typename std::tuple_element<I, deduced<Action>>::type>::type>::value);
476 static constexpr bool value =
true;
479 template <
auto Action,
typename... Ts>
480 constexpr bool type_check() {
481 static_assert(
sizeof...(Ts) == std::tuple_size<deduced<Action>>::value);
482 if constexpr (
sizeof...(Ts) != 0)
483 return check_types<Action, 0, Ts...>::value;
505 template <eosio::name::raw Name, auto Action>
507 template <
typename Code>
509 : code_name(std::forward<Code>(
code)), permissions(std::move(perms)) {}
511 template <
typename Code>
513 : code_name(std::forward<Code>(
code)), permissions(perms) {}
515 template <
typename Code>
517 : code_name(std::forward<Code>(
code)), permissions({1, std::move(perm)}) {}
519 template <
typename Code>
521 : code_name(std::forward<Code>(
code)), permissions({1, perm}) {}
523 template <
typename Code>
525 : code_name(std::forward<Code>(
code)) {}
535 template <
typename... Args>
537 static_assert(detail::type_check<Action, Args...>());
538 return action(permissions, code_name, action_name, detail::deduced<Action>{std::forward<Args>(args)...});
540 template <
typename... Args>
541 void send(Args&&... args)
const {
542 to_action(std::forward<Args>(args)...).send();
545 template <
typename... Args>
547 to_action(std::forward<Args>(args)...).send_context_free();
554 template <
typename Code>
556 : code_name(std::forward<Code>(
code)), permissions(std::move(perms)) {}
558 template <
typename Code>
560 : code_name(std::forward<Code>(
code)), permissions(perms) {}
562 template <
typename Code>
564 : code_name(std::forward<Code>(
code)), permissions({1, std::move(perm)}) {}
566 template <
typename Code>
568 : code_name(std::forward<Code>(
code)), permissions({1, perm}) {}
574 template <
size_t Variant>
576 return detail::get_nth<Variant, Actions...>::value;
579 template <
size_t Variant,
typename... Args>
581 static_assert(detail::type_check<detail::get_nth<Variant, Actions...>::value, Args...>());
583 return action(permissions, code_name, action_name, std::tuple_cat(std::make_tuple(var), detail::deduced<detail::get_nth<Variant, Actions...>::value>{std::forward<Args>(args)...}));
587 template <
size_t Variant,
typename... Args>
588 void send(Args&&... args)
const {
589 to_action<Variant>(std::forward<Args>(args)...).send();
592 template <
size_t Variant,
typename... Args>
594 to_action<Variant>(std::forward<Args>(args)...).send_context_free();
599 template<
typename... Args>
601 std::vector<permission_level> perms,
602 std::tuple<Args...> args ) {
606 template<
typename, name::raw>
610 template<
typename T,
name::raw Name,
typename... Args>
615 static void call(
name code, std::vector<permission_level> perms, std::tuple<Args...> args) {
622#define INLINE_ACTION_SENDER3( CONTRACT_CLASS, FUNCTION_NAME, ACTION_NAME )\
623::eosio::inline_dispatcher<decltype(&CONTRACT_CLASS::FUNCTION_NAME), ACTION_NAME>::call
625#define INLINE_ACTION_SENDER2( CONTRACT_CLASS, NAME )\
626INLINE_ACTION_SENDER3( CONTRACT_CLASS, NAME, ::eosio::name(#NAME) )
628#define INLINE_ACTION_SENDER(...) BLUEGRASS_META_OVERLOAD(INLINE_ACTION_SENDER,__VA_ARGS__)(__VA_ARGS__)
656#define SEND_INLINE_ACTION( CONTRACT, NAME, ... )\
657INLINE_ACTION_SENDER(std::decay_t<decltype(CONTRACT)>, NAME)( (CONTRACT).get_self(),__VA_ARGS__)