Merge pull request #86 from BlackMATov/dev

Dev
This commit is contained in:
2024-02-11 10:54:20 +07:00
committed by GitHub
31 changed files with 1261 additions and 711 deletions

View File

@@ -2,7 +2,7 @@
## Backlog
- add variadic variant of invoking to meta_invoke
- add coverage information
## Version 1.0

File diff suppressed because it is too large Load Diff

View File

@@ -1,100 +0,0 @@
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/meta.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2021-2024, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#include <meta.hpp/meta_all.hpp>
#include <doctest/doctest.h>
TEST_CASE("meta/meta_base/hashed_string") {
namespace meta = meta_hpp;
using meta::detail::hashed_string;
SUBCASE("ctor/0") {
constexpr hashed_string hs{};
static_assert(hs == hashed_string{""});
static_assert(hs.get_hash() == hashed_string{""}.get_hash());
CHECK(hs == hashed_string{std::string{}});
CHECK(hs == hashed_string{std::string_view{}});
}
SUBCASE("ctor/1") {
constexpr hashed_string hs{"hello"};
static_assert(hs.get_hash() == meta::detail::fnv1a_hash("hello", 5));
CHECK(hs == hashed_string{std::string{"hello"}});
CHECK(hs == hashed_string{std::string_view{"hello"}});
}
SUBCASE("copy_ctor") {
constexpr hashed_string hs{"hello"};
constexpr hashed_string hs2{hs};
static_assert(hs == hs2);
static_assert(hs.get_hash() == hs2.get_hash());
}
SUBCASE("move_ctor") {
constexpr hashed_string hs{"hello"};
constexpr hashed_string hs2{std::move(hs)};
static_assert(hs == hs2);
static_assert(hs.get_hash() == hs2.get_hash());
}
SUBCASE("operator=/copy") {
constexpr hashed_string hs{"hello"};
constexpr hashed_string hs2 = [&hs](){
hashed_string r;
r = hs;
return r;
}();
static_assert(hs == hs2);
static_assert(hs.get_hash() == hs2.get_hash());
}
SUBCASE("operator=/move") {
constexpr hashed_string hs{"hello"};
constexpr hashed_string hs2 = [&hs](){
hashed_string r;
r = std::move(hs);
return r;
}();
static_assert(hs == hs2);
static_assert(hs.get_hash() == hs2.get_hash());
}
SUBCASE("get_hash") {
constexpr hashed_string hs1{"hello"};
constexpr hashed_string hs2{"world"};
static_assert(hs1.get_hash() == hashed_string{"hello"}.get_hash());
static_assert(hs1.get_hash() != hs2.get_hash());
CHECK(std::hash<hashed_string>{}(hs1) == hs1.get_hash());
}
SUBCASE("operator<") {
constexpr hashed_string hs1{"hello"};
constexpr hashed_string hs2{"hello"};
static_assert(!(hs1 < hs2) && !(hs2 < hs1));
static_assert(hs1 < hashed_string{"world"} || hashed_string{"world"} < hs1);
static_assert((hs1 < "world" || hs1 > "world"));
static_assert(("world" < hs1 || "world" > hs1));
}
SUBCASE("operator==") {
constexpr hashed_string hs1{"hello"};
static_assert(hs1 == hashed_string{"hello"});
static_assert(hs1 != hashed_string{"world"});
static_assert(hs1 == "hello");
static_assert("hello" == hs1);
static_assert("world" != hs1);
}
SUBCASE("swap") {
hashed_string hs1{"hello"};
hashed_string hs2{"world"};
swap(hs1, hs2);
CHECK(hs1 == hashed_string{"world"});
CHECK(hs2 == hashed_string{"hello"});
}
}

View File

@@ -0,0 +1,44 @@
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/meta.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2021-2024, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#include <meta.hpp/meta_all.hpp>
#include <doctest/doctest.h>
namespace
{
namespace meta = meta_hpp;
meta::scope sc;
int inner(int a, int b) {
return a + b;
}
struct A {
A() = default;
~A() = default;
A(const A&) {
std::array<int, 2> args{1, 2};
v = sc.get_function("inner").invoke_variadic(args.begin(), args.end()).as<int>();
}
int v{};
};
int outer(A l, A r) {
return l.v + r.v;
}
}
TEST_CASE("meta/meta_issues/random/8") {
sc = meta::local_scope_("")
.function_("inner", &inner)
.function_("outer", &outer);
std::array<A, 2> args{};
CHECK(sc.get_function("outer").invoke_variadic(args.begin(), args.end()).as<int>() == 6);
}

View File

@@ -9,6 +9,11 @@
namespace
{
struct ivec2 {
int x{};
int y{};
};
struct clazz {
int member{1};
int method(int i) const { return i; }
@@ -32,6 +37,14 @@ TEST_CASE("meta/meta_utilities/invoke") {
const meta::function& clazz_function = clazz_type.get_function("function");
REQUIRE((clazz_member && clazz_method && clazz_function));
std::vector<meta::uvalue> params;
params.push_back(3);
std::vector<meta::uvalue> wrong_params;
wrong_params.push_back(ivec2{});
wrong_params.push_back(ivec2{});
std::vector<int> typed_params;
typed_params.push_back(3);
{
CHECK(meta::invoke(&clazz::function, 3).as<int>() == 3);
CHECK(meta::invoke(&clazz::function, meta::uvalue{3}).as<int>() == 3);
@@ -43,19 +56,50 @@ TEST_CASE("meta/meta_utilities/invoke") {
CHECK(meta::try_invoke(&clazz::function, 3)->as<int>() == 3);
CHECK(meta::try_invoke(&clazz::function, meta::uvalue{3})->as<int>() == 3);
CHECK(meta::try_invoke(&clazz::function, meta::uresult{3})->as<int>() == 3);
CHECK_FALSE(meta::try_invoke(&clazz::function, ivec2{}));
CHECK_FALSE(meta::try_invoke(&clazz::function, meta::uvalue{ivec2{}}));
CHECK(meta::try_invoke(clazz_function, 3)->as<int>() == 3);
CHECK(meta::try_invoke(clazz_function, meta::uvalue{3})->as<int>() == 3);
CHECK(meta::try_invoke(clazz_function, meta::uresult{3})->as<int>() == 3);
CHECK_FALSE(meta::try_invoke(clazz_function, ivec2{}));
CHECK_FALSE(meta::try_invoke(clazz_function, meta::uvalue{ivec2{}}));
CHECK(meta::is_invocable_with(clazz_function, 3));
CHECK(meta::is_invocable_with(clazz_function, meta::uvalue{3}));
CHECK(meta::is_invocable_with(clazz_function, meta::uresult{3}));
CHECK_FALSE(meta::is_invocable_with(clazz_function, ivec2{}));
CHECK_FALSE(meta::is_invocable_with(clazz_function, meta::uvalue{ivec2{}}));
CHECK(meta::is_invocable_with<int>(clazz_function));
CHECK_FALSE(meta::is_invocable_with<ivec2>(clazz_function));
CHECK(meta::is_invocable_with(&clazz::function, 3));
CHECK(meta::is_invocable_with(&clazz::function, meta::uvalue{3}));
CHECK(meta::is_invocable_with(&clazz::function, meta::uresult{3}));
CHECK_FALSE(meta::is_invocable_with(&clazz::function, ivec2{}));
CHECK_FALSE(meta::is_invocable_with(&clazz::function, meta::uvalue{ivec2{}}));
CHECK(meta::is_invocable_with<int>(&clazz::function));
CHECK_FALSE(meta::is_invocable_with<ivec2>(&clazz::function));
}
{
CHECK(meta::invoke_variadic(&clazz::function, params.begin(), params.end()).as<int>() == 3);
CHECK(meta::invoke_variadic(&clazz::function, typed_params.begin(), typed_params.end()).as<int>() == 3);
CHECK(meta::invoke_variadic(clazz_function, params.begin(), params.end()).as<int>() == 3);
CHECK(meta::invoke_variadic(clazz_function, typed_params.begin(), typed_params.end()).as<int>() == 3);
CHECK((*meta::try_invoke_variadic(&clazz::function, params.begin(), params.end())).as<int>() == 3);
CHECK((*meta::try_invoke_variadic(&clazz::function, typed_params.begin(), typed_params.end())).as<int>() == 3);
CHECK_FALSE(meta::try_invoke_variadic(&clazz::function, wrong_params.begin(), wrong_params.end()));
CHECK((*meta::try_invoke_variadic(clazz_function, params.begin(), params.end())).as<int>() == 3);
CHECK((*meta::try_invoke_variadic(clazz_function, typed_params.begin(), typed_params.end())).as<int>() == 3);
CHECK_FALSE(meta::try_invoke_variadic(clazz_function, wrong_params.begin(), wrong_params.end()));
CHECK(meta::is_variadic_invocable_with(&clazz::function, params.begin(), params.end()));
CHECK(meta::is_variadic_invocable_with(&clazz::function, typed_params.begin(), typed_params.end()));
CHECK_FALSE(meta::is_variadic_invocable_with(&clazz::function, wrong_params.begin(), wrong_params.end()));
CHECK(meta::is_variadic_invocable_with(clazz_function, params.begin(), params.end()));
CHECK(meta::is_variadic_invocable_with(clazz_function, typed_params.begin(), typed_params.end()));
CHECK_FALSE(meta::is_variadic_invocable_with(clazz_function, wrong_params.begin(), wrong_params.end()));
}
{
@@ -71,19 +115,29 @@ TEST_CASE("meta/meta_utilities/invoke") {
CHECK(meta::try_invoke(&clazz::member, cl)->as<int>() == 1);
CHECK(meta::try_invoke(&clazz::member, meta::uvalue{cl})->as<int>() == 1);
CHECK(meta::try_invoke(&clazz::member, meta::uresult{cl})->as<int>() == 1);
CHECK_FALSE(meta::try_invoke(&clazz::member, ivec2{}));
CHECK_FALSE(meta::try_invoke(&clazz::member, meta::uvalue{ivec2{}}));
CHECK(meta::try_invoke(clazz_member, cl)->as<int>() == 1);
CHECK(meta::try_invoke(clazz_member, meta::uvalue{cl})->as<int>() == 1);
CHECK(meta::try_invoke(clazz_member, meta::uresult{cl})->as<int>() == 1);
CHECK_FALSE(meta::try_invoke(clazz_member, ivec2{}));
CHECK_FALSE(meta::try_invoke(clazz_member, meta::uvalue{ivec2{}}));
CHECK(meta::is_invocable_with(clazz_member, cl));
CHECK(meta::is_invocable_with(clazz_member, meta::uvalue{cl}));
CHECK(meta::is_invocable_with(clazz_member, meta::uresult{cl}));
CHECK(meta::is_invocable_with<const clazz&>(clazz_member));
CHECK_FALSE(meta::is_invocable_with(clazz_member, ivec2{}));
CHECK_FALSE(meta::is_invocable_with(clazz_member, meta::uvalue{ivec2{}}));
CHECK_FALSE(meta::is_invocable_with<const ivec2&>(clazz_member));
CHECK(meta::is_invocable_with(&clazz::member, cl));
CHECK(meta::is_invocable_with(&clazz::member, meta::uvalue{cl}));
CHECK(meta::is_invocable_with(&clazz::member, meta::uresult{cl}));
CHECK(meta::is_invocable_with<const clazz&>(&clazz::member));
CHECK_FALSE(meta::is_invocable_with(&clazz::member, ivec2{}));
CHECK_FALSE(meta::is_invocable_with(&clazz::member, meta::uvalue{ivec2{}}));
CHECK_FALSE(meta::is_invocable_with<const ivec2&>(&clazz::member));
}
{
@@ -99,18 +153,51 @@ TEST_CASE("meta/meta_utilities/invoke") {
CHECK(meta::try_invoke(&clazz::method, cl, 2)->as<int>() == 2);
CHECK(meta::try_invoke(&clazz::method, meta::uvalue{cl}, meta::uvalue{2})->as<int>() == 2);
CHECK(meta::try_invoke(&clazz::method, meta::uresult{cl}, meta::uresult{2})->as<int>() == 2);
CHECK_FALSE(meta::try_invoke(&clazz::method, cl, ivec2{}));
CHECK_FALSE(meta::try_invoke(&clazz::method, meta::uvalue{ivec2{}}, meta::uvalue{2}));
CHECK(meta::try_invoke(clazz_method, cl, 2)->as<int>() == 2);
CHECK(meta::try_invoke(clazz_method, meta::uvalue{cl}, meta::uvalue{2})->as<int>() == 2);
CHECK(meta::try_invoke(clazz_method, meta::uresult{cl}, meta::uresult{2})->as<int>() == 2);
CHECK_FALSE(meta::try_invoke(clazz_method, cl, ivec2{}));
CHECK_FALSE(meta::try_invoke(clazz_method, meta::uvalue{cl}, meta::uvalue{ivec2{}}));
CHECK(meta::is_invocable_with(clazz_method, cl, 2));
CHECK(meta::is_invocable_with(clazz_method, meta::uvalue{cl}, meta::uvalue{2}));
CHECK(meta::is_invocable_with(clazz_method, meta::uresult{cl}, meta::uresult{2}));
CHECK(meta::is_invocable_with<const clazz&, int>(clazz_method));
CHECK_FALSE(meta::is_invocable_with(clazz_method, cl, ivec2{}));
CHECK_FALSE(meta::is_invocable_with(clazz_method, meta::uvalue{cl}, meta::uvalue{ivec2{}}));
CHECK_FALSE(meta::is_invocable_with<const clazz&, ivec2>(clazz_method));
CHECK(meta::is_invocable_with(&clazz::method, cl, 2));
CHECK(meta::is_invocable_with(&clazz::method, meta::uvalue{cl}, meta::uvalue{2}));
CHECK(meta::is_invocable_with(&clazz::method, meta::uresult{cl}, meta::uresult{2}));
CHECK(meta::is_invocable_with<const clazz&, int>(&clazz::method));
CHECK_FALSE(meta::is_invocable_with(&clazz::method, cl, ivec2{}));
CHECK_FALSE(meta::is_invocable_with(&clazz::method, meta::uvalue{cl}, meta::uvalue{ivec2{}}));
CHECK_FALSE(meta::is_invocable_with<const clazz&, ivec2>(&clazz::method));
}
{
clazz cl;
CHECK(meta::invoke_variadic(&clazz::method, meta::uvalue{cl}, params.begin(), params.end()).as<int>() == 3);
CHECK(meta::invoke_variadic(&clazz::method, meta::uresult{cl}, typed_params.begin(), typed_params.end()).as<int>() == 3);
CHECK(meta::invoke_variadic(clazz_method, meta::uvalue{cl}, params.begin(), params.end()).as<int>() == 3);
CHECK(meta::invoke_variadic(clazz_method, meta::uresult{cl}, typed_params.begin(), typed_params.end()).as<int>() == 3);
CHECK(meta::try_invoke_variadic(&clazz::method, meta::uvalue{cl}, params.begin(), params.end())->as<int>() == 3);
CHECK(meta::try_invoke_variadic(&clazz::method, meta::uresult{cl}, typed_params.begin(), typed_params.end())->as<int>() == 3);
CHECK_FALSE(meta::try_invoke_variadic(&clazz::method, meta::uresult{cl}, wrong_params.begin(), wrong_params.end()));
CHECK(meta::try_invoke_variadic(clazz_method, meta::uvalue{cl}, params.begin(), params.end())->as<int>() == 3);
CHECK(meta::try_invoke_variadic(clazz_method, meta::uresult{cl}, typed_params.begin(), typed_params.end())->as<int>() == 3);
CHECK_FALSE(meta::try_invoke_variadic(clazz_method, meta::uresult{cl}, wrong_params.begin(), wrong_params.end()));
CHECK(meta::is_variadic_invocable_with(&clazz::method, meta::uvalue{cl}, params.begin(), params.end()));
CHECK(meta::is_variadic_invocable_with(&clazz::method, meta::uresult{cl}, typed_params.begin(), typed_params.end()));
CHECK_FALSE(meta::is_variadic_invocable_with(&clazz::method, meta::uresult{cl}, wrong_params.begin(), wrong_params.end()));
CHECK(meta::is_variadic_invocable_with(clazz_method, meta::uvalue{cl}, params.begin(), params.end()));
CHECK(meta::is_variadic_invocable_with(clazz_method, meta::uresult{cl}, typed_params.begin(), typed_params.end()));
CHECK_FALSE(meta::is_variadic_invocable_with(clazz_method, meta::uresult{cl}, wrong_params.begin(), wrong_params.end()));
}
}

View File

@@ -14,7 +14,7 @@
#include "meta_base/fixed_function.hpp"
#include "meta_base/fnv1a_hash.hpp"
#include "meta_base/hash_composer.hpp"
#include "meta_base/hashed_string.hpp"
#include "meta_base/inline_vector.hpp"
#include "meta_base/insert_or_assign.hpp"
#include "meta_base/is_in_place_type.hpp"
#include "meta_base/memory_buffer.hpp"
@@ -31,16 +31,12 @@ namespace meta_hpp
using detail::exception;
using detail::get_error_code_message;
using detail::hashed_string;
using detail::memory_buffer;
using detail::overloaded;
using detail::select_const;
using detail::select_non_const;
using detail::select_overload;
using detail::type_list;
}
namespace meta_hpp

View File

@@ -97,6 +97,13 @@
//
//
#define META_HPP_PP_CAT(x, y) META_HPP_PP_CAT_I(x, y)
#define META_HPP_PP_CAT_I(x, y) x##y
//
//
//
#define META_HPP_DETAIL_CLANG_COMPILER_ID 1
#define META_HPP_DETAIL_GCC_COMPILER_ID 2
#define META_HPP_DETAIL_MSVC_COMPILER_ID 3
@@ -116,6 +123,16 @@
//
//
#if META_HPP_DETAIL_COMPILER_ID == META_HPP_DETAIL_MSVC_COMPILER_ID
# define META_HPP_ALLOCA(size) _alloca(size)
#else
# define META_HPP_ALLOCA(size) __builtin_alloca(size)
#endif
//
//
//
#if META_HPP_DETAIL_COMPILER_ID == META_HPP_DETAIL_CLANG_COMPILER_ID
# define META_HPP_DETAIL_CLANG_PRAGMA_TO_STR(x) _Pragma(#x)
# define META_HPP_DETAIL_CLANG_IGNORE_WARNING(w) META_HPP_DETAIL_CLANG_PRAGMA_TO_STR(clang diagnostic ignored w)
@@ -154,6 +171,16 @@
//
//
#define META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_PUSH() \
META_HPP_DETAIL_CLANG_IGNORE_WARNINGS_PUSH() \
META_HPP_DETAIL_CLANG_IGNORE_WARNING("-Walloca")
#define META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_POP() META_HPP_DETAIL_CLANG_IGNORE_WARNINGS_POP()
//
//
//
#define META_HPP_DETAIL_IGNORE_OVERRIDE_WARNINGS_PUSH() \
META_HPP_DETAIL_CLANG_IGNORE_WARNINGS_PUSH() \
META_HPP_DETAIL_CLANG_IGNORE_WARNING("-Wunknown-warning-option") \

View File

@@ -9,7 +9,6 @@
#include "base.hpp"
#include "bitflags.hpp"
#include "fnv1a_hash.hpp"
#include "hashed_string.hpp"
namespace meta_hpp::detail
{
@@ -40,7 +39,7 @@ namespace meta_hpp::detail
}
constexpr hash_composer operator<<(std::string_view value) noexcept {
hash = combine(hash, hashed_string{value}.get_hash());
hash = combine(hash, fnv1a_hash(value.data(), value.size()));
return *this;
}

View File

@@ -1,69 +0,0 @@
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/meta.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2021-2024, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#pragma once
#include "base.hpp"
#include "fnv1a_hash.hpp"
namespace meta_hpp::detail
{
class hashed_string final {
public:
hashed_string() = default;
~hashed_string() = default;
hashed_string(hashed_string&&) = default;
hashed_string(const hashed_string&) = default;
hashed_string& operator=(hashed_string&&) = default;
hashed_string& operator=(const hashed_string&) = default;
constexpr hashed_string(std::string_view str) noexcept
: hash_{fnv1a_hash(str.data(), str.size())} {}
constexpr void swap(hashed_string& other) noexcept {
std::swap(hash_, other.hash_);
}
[[nodiscard]] constexpr std::size_t get_hash() const noexcept {
return hash_;
}
[[nodiscard]] constexpr bool operator==(hashed_string other) const noexcept {
return hash_ == other.hash_;
}
[[nodiscard]] constexpr std::strong_ordering operator<=>(hashed_string other) const noexcept {
return hash_ <=> other.hash_;
}
private:
std::size_t hash_{fnv1a_hash("", 0)};
};
constexpr void swap(hashed_string& l, hashed_string& r) noexcept {
l.swap(r);
}
[[nodiscard]] constexpr bool operator==(hashed_string l, std::string_view r) noexcept {
return l == hashed_string{r};
}
[[nodiscard]] constexpr std::strong_ordering operator<=>(hashed_string l, std::string_view r) noexcept {
return l <=> hashed_string{r};
}
}
namespace std
{
template <>
struct hash<meta_hpp::detail::hashed_string> {
size_t operator()(meta_hpp::detail::hashed_string hs) const noexcept {
return hs.get_hash();
}
};
}

View File

@@ -0,0 +1,67 @@
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/meta.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2021-2024, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#pragma once
#include "base.hpp"
namespace meta_hpp::detail
{
template < typename T >
class inline_vector final {
public:
inline_vector() = delete;
inline_vector(inline_vector&&) = delete;
inline_vector& operator=(inline_vector&&) = delete;
inline_vector(const inline_vector&) = delete;
inline_vector& operator=(const inline_vector&) = delete;
inline_vector(T* mem, std::size_t capacity)
: begin_{mem}
, end_{mem}
, capacity_{mem + capacity} {}
~inline_vector() {
std::destroy(begin_, end_);
}
// clang-format off
[[nodiscard]] T* data() noexcept { return begin_; }
[[nodiscard]] const T* data() const noexcept { return begin_; }
[[nodiscard]] T* begin() noexcept { return begin_; }
[[nodiscard]] const T* begin() const noexcept { return begin_; }
[[nodiscard]] const T* cbegin() const noexcept { return begin_; }
[[nodiscard]] T* end() noexcept { return end_; }
[[nodiscard]] const T* end() const noexcept { return end_; }
[[nodiscard]] const T* cend() const noexcept { return end_; }
// clang-format on
template < typename... Args >
T& emplace_back(Args&&... args) {
META_HPP_ASSERT(end_ < capacity_ && "full vector");
return *std::construct_at(end_++, std::forward<Args>(args)...);
}
[[nodiscard]] std::size_t get_size() const noexcept {
return static_cast<std::size_t>(end_ - begin_);
}
[[nodiscard]] std::size_t get_capacity() const noexcept {
return static_cast<std::size_t>(capacity_ - begin_);
}
private:
T* begin_{};
T* end_{};
T* capacity_{};
};
}

View File

@@ -11,13 +11,7 @@
namespace meta_hpp::detail
{
template < typename... Types >
struct type_list {
template < typename F >
// NOLINTNEXTLINE(*-missing-std-forward)
static constexpr void for_each(F&& f) {
(f.template operator()<Types>(), ...);
}
};
struct type_list {};
template < std::size_t I >
using size_constant = std::integral_constant<std::size_t, I>;

View File

@@ -152,9 +152,9 @@ namespace meta_hpp::detail::impl
hash << shared_type<typename traits::class_type>{}();
traits::argument_types::for_each([&hash]<typename Arg>() { //
hash << shared_type<Arg>{}();
});
[&hash]<typename... ArgTypes>(type_list<ArgTypes...>) {
((hash << shared_type<ArgTypes>{}()), ...);
}(typename traits::argument_types{});
return hash.hash;
}
@@ -201,9 +201,9 @@ namespace meta_hpp::detail::impl
hash << shared_type<typename traits::return_type>{}();
traits::argument_types::for_each([&hash]<typename Arg>() { //
hash << shared_type<Arg>{}();
});
[&hash]<typename... ArgTypes>(type_list<ArgTypes...>) {
((hash << shared_type<ArgTypes>{}()), ...);
}(typename traits::argument_types{});
return hash.hash;
}
@@ -237,9 +237,9 @@ namespace meta_hpp::detail::impl
hash << shared_type<typename traits::class_type>{}();
hash << shared_type<typename traits::return_type>{}();
traits::argument_types::for_each([&hash]<typename Arg>() { //
hash << shared_type<Arg>{}();
});
[&hash]<typename... ArgTypes>(type_list<ArgTypes...>) {
((hash << shared_type<ArgTypes>{}()), ...);
}(typename traits::argument_types{});
return hash.hash;
}

View File

@@ -38,9 +38,9 @@ namespace meta_hpp::detail
~uarg_base() = default;
uarg_base(uarg_base&&) = default;
uarg_base(const uarg_base&) = default;
uarg_base& operator=(uarg_base&&) = default;
uarg_base& operator=(uarg_base&&) = delete;
uarg_base(const uarg_base&) = delete;
uarg_base& operator=(const uarg_base&) = delete;
template < typename T, typename Tp = std::decay_t<T> >
@@ -114,9 +114,9 @@ namespace meta_hpp::detail
~uarg() = default;
uarg(uarg&&) = default;
uarg(const uarg&) = default;
uarg& operator=(uarg&&) = default;
uarg& operator=(uarg&&) = delete;
uarg(const uarg&) = delete;
uarg& operator=(const uarg&) = delete;
template < typename T, typename Tp = std::decay_t<T> >

View File

@@ -29,9 +29,9 @@ namespace meta_hpp::detail
~uinst_base() = default;
uinst_base(uinst_base&&) = default;
uinst_base(const uinst_base&) = default;
uinst_base& operator=(uinst_base&&) = default;
uinst_base& operator=(uinst_base&&) = delete;
uinst_base(const uinst_base&) = delete;
uinst_base& operator=(const uinst_base&) = delete;
template < typename T, typename Tp = std::decay_t<T> >
@@ -107,9 +107,9 @@ namespace meta_hpp::detail
~uinst() = default;
uinst(uinst&&) = default;
uinst(const uinst&) = default;
uinst& operator=(uinst&&) = default;
uinst& operator=(uinst&&) = delete;
uinst(const uinst&) = delete;
uinst& operator=(const uinst&) = delete;
template < typename T, typename Tp = std::decay_t<T> >

View File

@@ -25,6 +25,20 @@ namespace meta_hpp
template < function_pointer_kind Function, typename... Args >
uresult try_invoke(Function function_ptr, Args&&... args);
//
template < typename Iter >
uvalue invoke_variadic(const function& function, Iter first, Iter last);
template < typename Iter >
uresult try_invoke_variadic(const function& function, Iter first, Iter last);
template < function_pointer_kind Function, typename Iter >
uvalue invoke_variadic(Function function_ptr, Iter first, Iter last);
template < function_pointer_kind Function, typename Iter >
uresult try_invoke_variadic(Function function_ptr, Iter first, Iter last);
}
namespace meta_hpp
@@ -55,6 +69,20 @@ namespace meta_hpp
template < method_pointer_kind Method, typename Instance, typename... Args >
uresult try_invoke(Method method_ptr, Instance&& instance, Args&&... args);
//
template < typename Instance, typename Iter >
uvalue invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last);
template < typename Instance, typename Iter >
uresult try_invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last);
template < method_pointer_kind Method, typename Instance, typename Iter >
uvalue invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last);
template < method_pointer_kind Method, typename Instance, typename Iter >
uresult try_invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last);
}
namespace meta_hpp
@@ -82,6 +110,20 @@ namespace meta_hpp
template < typename... Args, function_pointer_kind Function >
uerror check_invocable_error(Function function_ptr, Args&&... args) noexcept;
//
template < typename Iter >
bool is_variadic_invocable_with(const function& function, Iter first, Iter last);
template < typename Iter, function_pointer_kind Function >
bool is_variadic_invocable_with(Function function_ptr, Iter first, Iter last);
template < typename Iter >
uerror check_variadic_invocable_error(const function& function, Iter first, Iter last);
template < typename Iter, function_pointer_kind Function >
uerror check_variadic_invocable_error(Function function_ptr, Iter first, Iter last);
}
namespace meta_hpp
@@ -136,4 +178,18 @@ namespace meta_hpp
template < typename Instance, typename... Args, method_pointer_kind Method >
uerror check_invocable_error(Method method_ptr, Instance&& instance, Args&&... args) noexcept;
//
template < typename Instance, typename Iter >
bool is_variadic_invocable_with(const method& method, Instance&& instance, Iter first, Iter last);
template < typename Instance, typename Iter, method_pointer_kind Method >
bool is_variadic_invocable_with(Method method_ptr, Instance&& instance, Iter first, Iter last);
template < typename Instance, typename Iter >
uerror check_variadic_invocable_error(const method& method, Instance&& instance, Iter first, Iter last);
template < typename Instance, typename Iter, method_pointer_kind Method >
uerror check_variadic_invocable_error(Method method_ptr, Instance&& instance, Iter first, Iter last);
}

View File

@@ -41,20 +41,48 @@ namespace meta_hpp
template < function_pointer_kind Function, typename... Args >
uresult try_invoke(Function function_ptr, Args&&... args) {
// doesn't actually move 'args', just checks conversion errors
if ( const uerror err = check_invocable_error(function_ptr, META_HPP_FWD(args)...) ) {
return err;
}
return invoke(function_ptr, META_HPP_FWD(args)...);
}
template < typename Iter >
uvalue invoke_variadic(const function& function, Iter first, Iter last) {
return function.invoke_variadic(first, last);
}
template < typename Iter >
uresult try_invoke_variadic(const function& function, Iter first, Iter last) {
return function.try_invoke_variadic(first, last);
}
template < function_pointer_kind Function, typename Iter >
uvalue invoke_variadic(Function function_ptr, Iter first, Iter last) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move 'args', just checks conversion errors
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
if ( const uerror err = raw_function_invoke_error<Function>(registry, vargs) ) {
return err;
using ft = function_traits<std::remove_pointer_t<Function>>;
std::array<uarg, ft::arity> vargs;
for ( std::size_t count{}; first != last; ++count, ++first ) {
if ( count >= ft::arity ) {
throw_exception(error_code::arity_mismatch);
}
vargs[count] = uarg{registry, *first};
}
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, META_HPP_FWD(args)}...};
return raw_function_invoke<function_policy::as_copy_t>(registry, function_ptr, vargs);
}
template < function_pointer_kind Function, typename Iter >
uresult try_invoke_variadic(Function function_ptr, Iter first, Iter last) {
if ( const uerror err = check_variadic_invocable_error(function_ptr, first, last) ) {
return err;
}
return invoke_variadic(function_ptr, first, last);
}
}
namespace meta_hpp
@@ -79,19 +107,11 @@ namespace meta_hpp
template < member_pointer_kind Member, typename Instance >
uresult try_invoke(Member member_ptr, Instance&& instance) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move an 'instance', just checks conversion errors
const uinst_base vinst{registry, META_HPP_FWD(instance)};
if ( const uerror err = raw_member_getter_error<Member>(registry, vinst) ) {
return err;
}
// doesn't actually move an 'instance', just checks conversion errors
if ( const uerror err = check_invocable_error(member_ptr, META_HPP_FWD(instance)) ) {
return err;
}
const uinst vinst{registry, META_HPP_FWD(instance)};
return raw_member_getter<member_policy::as_copy_t>(registry, member_ptr, vinst);
return invoke(member_ptr, META_HPP_FWD(instance));
}
}
@@ -118,22 +138,50 @@ namespace meta_hpp
template < method_pointer_kind Method, typename Instance, typename... Args >
uresult try_invoke(Method method_ptr, Instance&& instance, Args&&... args) {
// doesn't actually move an 'instance' and 'args', just checks conversion errors
if ( const uerror err = check_invocable_error(method_ptr, META_HPP_FWD(instance), META_HPP_FWD(args)...) ) {
return err;
}
return invoke(method_ptr, META_HPP_FWD(instance), META_HPP_FWD(args)...);
}
template < typename Instance, typename Iter >
uvalue invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last) {
return method.invoke_variadic(META_HPP_FWD(instance), first, last);
}
template < typename Instance, typename Iter >
uresult try_invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last) {
return method.try_invoke_variadic(META_HPP_FWD(instance), first, last);
}
template < method_pointer_kind Method, typename Instance, typename Iter >
uvalue invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last) {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move an 'instance' and 'args', just checks conversion errors
const uinst_base vinst{registry, META_HPP_FWD(instance)};
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
if ( const uerror err = raw_method_invoke_error<Method>(registry, vinst, vargs) ) {
return err;
using mt = method_traits<Method>;
std::array<uarg, mt::arity> vargs;
for ( std::size_t count{}; first != last; ++count, ++first ) {
if ( count >= mt::arity ) {
throw_exception(error_code::arity_mismatch);
}
vargs[count] = uarg{registry, *first};
}
const uinst vinst{registry, META_HPP_FWD(instance)};
const std::array<uarg, sizeof...(Args)> vargs{uarg{registry, META_HPP_FWD(args)}...};
return raw_method_invoke<method_policy::as_copy_t>(registry, method_ptr, vinst, vargs);
}
template < method_pointer_kind Method, typename Instance, typename Iter >
uresult try_invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last) {
// doesn't actually move an 'instance', just checks conversion errors
if ( const uerror err = check_variadic_invocable_error(method_ptr, META_HPP_FWD(instance), first, last) ) {
return err;
}
return invoke_variadic(method_ptr, META_HPP_FWD(instance), first, last);
}
}
namespace meta_hpp
@@ -183,6 +231,39 @@ namespace meta_hpp
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
return raw_function_invoke_error<Function>(registry, vargs);
}
template < typename Iter >
bool is_variadic_invocable_with(const function& function, Iter first, Iter last) {
return function.is_variadic_invocable_with(first, last);
}
template < typename Iter, function_pointer_kind Function >
bool is_variadic_invocable_with(Function function_ptr, Iter first, Iter last) {
return !check_variadic_invocable_error(function_ptr, first, last);
}
template < typename Iter >
uerror check_variadic_invocable_error(const function& function, Iter first, Iter last) {
return function.check_variadic_invocable_error(first, last);
}
template < typename Iter, function_pointer_kind Function >
uerror check_variadic_invocable_error(Function, Iter first, Iter last) {
using namespace detail;
type_registry& registry{type_registry::instance()};
using ft = function_traits<std::remove_pointer_t<Function>>;
std::array<uarg_base, ft::arity> vargs;
for ( std::size_t count{}; first != last; ++count, ++first ) {
if ( count >= ft::arity ) {
return uerror{error_code::arity_mismatch};
}
vargs[count] = uarg_base{registry, *first};
}
return raw_function_invoke_error<Function>(registry, vargs);
}
}
namespace meta_hpp
@@ -283,4 +364,38 @@ namespace meta_hpp
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
return raw_method_invoke_error<Method>(registry, vinst, vargs);
}
template < typename Instance, typename Iter >
bool is_variadic_invocable_with(const method& method, Instance&& instance, Iter first, Iter last) {
return method.is_variadic_invocable_with(META_HPP_FWD(instance), first, last);
}
template < typename Instance, typename Iter, method_pointer_kind Method >
bool is_variadic_invocable_with(Method method_ptr, Instance&& instance, Iter first, Iter last) {
return !check_variadic_invocable_error(method_ptr, META_HPP_FWD(instance), first, last);
}
template < typename Instance, typename Iter >
uerror check_variadic_invocable_error(const method& method, Instance&& instance, Iter first, Iter last) {
return method.check_variadic_invocable_error(META_HPP_FWD(instance), first, last);
}
template < typename Instance, typename Iter, method_pointer_kind Method >
uerror check_variadic_invocable_error(Method, Instance&& instance, Iter first, Iter last) {
using namespace detail;
type_registry& registry{type_registry::instance()};
using mt = method_traits<Method>;
std::array<uarg_base, mt::arity> vargs;
for ( std::size_t count{}; first != last; ++count, ++first ) {
if ( count >= mt::arity ) {
return uerror{error_code::arity_mismatch};
}
vargs[count] = uarg_base{registry, *first};
}
const uinst_base vinst{registry, META_HPP_FWD(instance)};
return raw_method_invoke_error<Method>(registry, vinst, vargs);
}
}

View File

@@ -86,16 +86,16 @@ namespace meta_hpp
uresult try_create_at(void* mem, Args&&... args) const;
template < typename... Args >
[[nodiscard]] bool is_invocable_with() const noexcept;
[[nodiscard]] bool is_invocable_with() const;
template < typename... Args >
[[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept;
[[nodiscard]] bool is_invocable_with(Args&&... args) const;
template < typename... Args >
[[nodiscard]] uerror check_invocable_error() const noexcept;
[[nodiscard]] uerror check_invocable_error() const;
template < typename... Args >
[[nodiscard]] uerror check_invocable_error(Args&&... args) const noexcept;
[[nodiscard]] uerror check_invocable_error(Args&&... args) const;
//
@@ -112,10 +112,10 @@ namespace meta_hpp
uresult try_create_variadic_at(void* mem, Iter first, Iter last) const;
template < typename Iter >
[[nodiscard]] bool is_variadic_invocable_with(Iter first, Iter last) const noexcept;
[[nodiscard]] bool is_variadic_invocable_with(Iter first, Iter last) const;
template < typename Iter >
[[nodiscard]] uerror check_variadic_invocable_error(Iter first, Iter last) const noexcept;
[[nodiscard]] uerror check_variadic_invocable_error(Iter first, Iter last) const;
};
class destructor final : public state_base<destructor> {
@@ -135,16 +135,16 @@ namespace meta_hpp
uresult try_destroy_at(void* mem) const;
template < typename Arg >
[[nodiscard]] bool is_invocable_with() const noexcept;
[[nodiscard]] bool is_invocable_with() const;
template < typename Arg >
[[nodiscard]] bool is_invocable_with(Arg&& arg) const noexcept;
[[nodiscard]] bool is_invocable_with(Arg&& arg) const;
template < typename Arg >
[[nodiscard]] uerror check_invocable_error() const noexcept;
[[nodiscard]] uerror check_invocable_error() const;
template < typename Arg >
[[nodiscard]] uerror check_invocable_error(Arg&& arg) const noexcept;
[[nodiscard]] uerror check_invocable_error(Arg&& arg) const;
};
class evalue final : public state_base<evalue> {
@@ -181,16 +181,16 @@ namespace meta_hpp
uvalue operator()(Args&&... args) const;
template < typename... Args >
[[nodiscard]] bool is_invocable_with() const noexcept;
[[nodiscard]] bool is_invocable_with() const;
template < typename... Args >
[[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept;
[[nodiscard]] bool is_invocable_with(Args&&... args) const;
template < typename... Args >
[[nodiscard]] uerror check_invocable_error() const noexcept;
[[nodiscard]] uerror check_invocable_error() const;
template < typename... Args >
[[nodiscard]] uerror check_invocable_error(Args&&... args) const noexcept;
[[nodiscard]] uerror check_invocable_error(Args&&... args) const;
//
@@ -233,28 +233,28 @@ namespace meta_hpp
void operator()(Instance&& instance, Value&& value) const;
template < typename Instance >
[[nodiscard]] bool is_gettable_with() const noexcept;
[[nodiscard]] bool is_gettable_with() const;
template < typename Instance >
[[nodiscard]] bool is_gettable_with(Instance&& instance) const noexcept;
[[nodiscard]] bool is_gettable_with(Instance&& instance) const;
template < typename Instance, typename Value >
[[nodiscard]] bool is_settable_with() const noexcept;
[[nodiscard]] bool is_settable_with() const;
template < typename Instance, typename Value >
[[nodiscard]] bool is_settable_with(Instance&& instance, Value&& value) const noexcept;
[[nodiscard]] bool is_settable_with(Instance&& instance, Value&& value) const;
template < typename Instance >
[[nodiscard]] uerror check_gettable_error() const noexcept;
[[nodiscard]] uerror check_gettable_error() const;
template < typename Instance >
[[nodiscard]] uerror check_gettable_error(Instance&& instance) const noexcept;
[[nodiscard]] uerror check_gettable_error(Instance&& instance) const;
template < typename Instance, typename Value >
[[nodiscard]] uerror check_settable_error() const noexcept;
[[nodiscard]] uerror check_settable_error() const;
template < typename Instance, typename Value >
[[nodiscard]] uerror check_settable_error(Instance&& instance, Value&& value) const noexcept;
[[nodiscard]] uerror check_settable_error(Instance&& instance, Value&& value) const;
};
class method final : public state_base<method> {
@@ -280,16 +280,16 @@ namespace meta_hpp
uvalue operator()(Instance&& instance, Args&&... args) const;
template < typename Instance, typename... Args >
[[nodiscard]] bool is_invocable_with() const noexcept;
[[nodiscard]] bool is_invocable_with() const;
template < typename Instance, typename... Args >
[[nodiscard]] bool is_invocable_with(Instance&& instance, Args&&... args) const noexcept;
[[nodiscard]] bool is_invocable_with(Instance&& instance, Args&&... args) const;
template < typename Instance, typename... Args >
[[nodiscard]] uerror check_invocable_error() const noexcept;
[[nodiscard]] uerror check_invocable_error() const;
template < typename Instance, typename... Args >
[[nodiscard]] uerror check_invocable_error(Instance&& instance, Args&&... args) const noexcept;
[[nodiscard]] uerror check_invocable_error(Instance&& instance, Args&&... args) const;
//
@@ -323,14 +323,14 @@ namespace meta_hpp
template < typename... Args >
[[nodiscard]] function get_function_with( //
std::string_view name
) const noexcept;
) const;
template < typename Iter >
[[nodiscard]] function get_function_with( //
std::string_view name,
Iter first,
Iter last
) const noexcept;
) const;
[[nodiscard]] function get_function_with( //
std::string_view name,
@@ -365,16 +365,16 @@ namespace meta_hpp
void operator()(Value&& value) const;
template < typename Value >
[[nodiscard]] bool is_settable_with() const noexcept;
[[nodiscard]] bool is_settable_with() const;
template < typename Value >
[[nodiscard]] bool is_settable_with(Value&& value) const noexcept;
[[nodiscard]] bool is_settable_with(Value&& value) const;
template < typename Value >
[[nodiscard]] uerror check_settable_error() const noexcept;
[[nodiscard]] uerror check_settable_error() const;
template < typename Value >
[[nodiscard]] uerror check_settable_error(Value&& value) const noexcept;
[[nodiscard]] uerror check_settable_error(Value&& value) const;
};
}

View File

@@ -148,10 +148,11 @@ namespace meta_hpp::detail
template < constructor_policy_family Policy, class_kind Class, typename... Args >
constructor_state::state_ptr constructor_state::make(metadata_map metadata) {
using ct = constructor_traits<Class, Args...>;
type_registry& registry{type_registry::instance()};
constructor_state state{
constructor_index{registry.resolve_by_traits<constructor_traits<Class, Args...>>()},
constructor_index{registry.resolve_by_traits<ct>()},
std::move(metadata),
};
@@ -217,17 +218,17 @@ namespace meta_hpp
}
template < typename... Args >
bool constructor::is_invocable_with() const noexcept {
bool constructor::is_invocable_with() const {
return !check_invocable_error<Args...>();
}
template < typename... Args >
bool constructor::is_invocable_with(Args&&... args) const noexcept {
bool constructor::is_invocable_with(Args&&... args) const {
return !check_invocable_error(META_HPP_FWD(args)...);
}
template < typename... Args >
uerror constructor::check_invocable_error() const noexcept {
uerror constructor::check_invocable_error() const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
@@ -235,7 +236,7 @@ namespace meta_hpp
}
template < typename... Args >
uerror constructor::check_invocable_error(Args&&... args) const noexcept {
uerror constructor::check_invocable_error(Args&&... args) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
@@ -245,18 +246,25 @@ namespace meta_hpp
template < typename Iter >
uvalue constructor::create_variadic(Iter first, Iter last) const {
using namespace detail;
const std::size_t arity = get_arity();
type_registry& registry{type_registry::instance()};
static thread_local std::vector<uarg> vargs;
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_PUSH()
vargs.clear();
vargs.reserve(get_type().get_arity());
void* vargs_mem = META_HPP_ALLOCA(sizeof(uarg) * arity);
detail::inline_vector<uarg> vargs{static_cast<uarg*>(vargs_mem), arity};
for ( ; first != last; ++first ) {
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_POP()
for ( std::size_t i{}; first != last; ++i, ++first ) {
if ( i >= arity ) {
throw_exception(error_code::arity_mismatch);
}
vargs.emplace_back(registry, *first);
}
return state_->create(vargs);
return state_->create({vargs.begin(), vargs.end()});
}
template < typename Iter >
@@ -270,18 +278,25 @@ namespace meta_hpp
template < typename Iter >
uvalue constructor::create_variadic_at(void* mem, Iter first, Iter last) const {
using namespace detail;
const std::size_t arity = get_arity();
type_registry& registry{type_registry::instance()};
static thread_local std::vector<uarg> vargs;
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_PUSH()
vargs.clear();
vargs.reserve(get_type().get_arity());
void* vargs_mem = META_HPP_ALLOCA(sizeof(uarg) * arity);
detail::inline_vector<uarg> vargs{static_cast<uarg*>(vargs_mem), arity};
for ( ; first != last; ++first ) {
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_POP()
for ( std::size_t i{}; first != last; ++i, ++first ) {
if ( i >= arity ) {
throw_exception(error_code::arity_mismatch);
}
vargs.emplace_back(registry, *first);
}
return state_->create_at(mem, vargs);
return state_->create_at(mem, {vargs.begin(), vargs.end()});
}
template < typename Iter >
@@ -293,24 +308,31 @@ namespace meta_hpp
}
template < typename Iter >
bool constructor::is_variadic_invocable_with(Iter first, Iter last) const noexcept {
bool constructor::is_variadic_invocable_with(Iter first, Iter last) const {
return !check_variadic_invocable_error(first, last);
}
template < typename Iter >
uerror constructor::check_variadic_invocable_error(Iter first, Iter last) const noexcept {
uerror constructor::check_variadic_invocable_error(Iter first, Iter last) const {
using namespace detail;
const std::size_t arity = get_arity();
type_registry& registry{type_registry::instance()};
static thread_local std::vector<uarg_base> vargs;
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_PUSH()
vargs.clear();
vargs.reserve(get_type().get_arity());
void* vargs_mem = META_HPP_ALLOCA(sizeof(uarg_base) * arity);
detail::inline_vector<uarg_base> vargs{static_cast<uarg_base*>(vargs_mem), arity};
for ( ; first != last; ++first ) {
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_POP()
for ( std::size_t i{}; first != last; ++i, ++first ) {
if ( i >= arity ) {
return uerror(error_code::arity_mismatch);
}
vargs.emplace_back(registry, *first);
}
return state_->create_error(vargs);
return state_->create_error({vargs.begin(), vargs.end()});
}
}

View File

@@ -136,17 +136,17 @@ namespace meta_hpp
}
template < typename Arg >
bool destructor::is_invocable_with() const noexcept {
bool destructor::is_invocable_with() const {
return !check_invocable_error<Arg>();
}
template < typename Arg >
bool destructor::is_invocable_with(Arg&& arg) const noexcept {
bool destructor::is_invocable_with(Arg&& arg) const {
return !check_invocable_error(META_HPP_FWD(arg));
}
template < typename Arg >
uerror destructor::check_invocable_error() const noexcept {
uerror destructor::check_invocable_error() const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uarg_base varg{registry, type_list<Arg>{}};
@@ -154,7 +154,7 @@ namespace meta_hpp
}
template < typename Arg >
uerror destructor::check_invocable_error(Arg&& arg) const noexcept {
uerror destructor::check_invocable_error(Arg&& arg) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uarg_base varg{registry, META_HPP_FWD(arg)};

View File

@@ -119,10 +119,11 @@ namespace meta_hpp::detail
template < function_policy_family Policy, function_pointer_kind Function >
function_state::state_ptr function_state::make(std::string name, Function function_ptr, metadata_map metadata) {
using ft = function_traits<std::remove_pointer_t<Function>>;
type_registry& registry{type_registry::instance()};
function_state state{
function_index{registry.resolve_by_type<std::remove_pointer_t<Function>>(), std::move(name)},
function_index{registry.resolve_by_traits<ft>(), std::move(name)},
std::move(metadata),
};
@@ -179,17 +180,17 @@ namespace meta_hpp
}
template < typename... Args >
bool function::is_invocable_with() const noexcept {
bool function::is_invocable_with() const {
return !check_invocable_error<Args...>();
}
template < typename... Args >
bool function::is_invocable_with(Args&&... args) const noexcept {
bool function::is_invocable_with(Args&&... args) const {
return !check_invocable_error(META_HPP_FWD(args)...);
}
template < typename... Args >
uerror function::check_invocable_error() const noexcept {
uerror function::check_invocable_error() const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, type_list<Args>{}}...};
@@ -197,7 +198,7 @@ namespace meta_hpp
}
template < typename... Args >
uerror function::check_invocable_error(Args&&... args) const noexcept {
uerror function::check_invocable_error(Args&&... args) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const std::array<uarg_base, sizeof...(Args)> vargs{uarg_base{registry, META_HPP_FWD(args)}...};
@@ -207,18 +208,25 @@ namespace meta_hpp
template < typename Iter >
uvalue function::invoke_variadic(Iter first, Iter last) const {
using namespace detail;
const std::size_t arity = get_arity();
type_registry& registry{type_registry::instance()};
static thread_local std::vector<uarg> vargs;
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_PUSH()
vargs.clear();
vargs.reserve(get_type().get_arity());
void* vargs_mem = META_HPP_ALLOCA(sizeof(uarg) * arity);
detail::inline_vector<uarg> vargs{static_cast<uarg*>(vargs_mem), arity};
for ( ; first != last; ++first ) {
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_POP()
for ( std::size_t i{}; first != last; ++i, ++first ) {
if ( i >= arity ) {
throw_exception(error_code::arity_mismatch);
}
vargs.emplace_back(registry, *first);
}
return state_->invoke(vargs);
return state_->invoke({vargs.begin(), vargs.end()});
}
template < typename Iter >
@@ -237,17 +245,24 @@ namespace meta_hpp
template < typename Iter >
uerror function::check_variadic_invocable_error(Iter first, Iter last) const {
using namespace detail;
const std::size_t arity = get_arity();
type_registry& registry{type_registry::instance()};
static thread_local std::vector<uarg_base> vargs;
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_PUSH()
vargs.clear();
vargs.reserve(get_type().get_arity());
void* vargs_mem = META_HPP_ALLOCA(sizeof(uarg_base) * arity);
detail::inline_vector<uarg_base> vargs{static_cast<uarg_base*>(vargs_mem), arity};
for ( ; first != last; ++first ) {
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_POP()
for ( std::size_t i{}; first != last; ++i, ++first ) {
if ( i >= arity ) {
return uerror(error_code::arity_mismatch);
}
vargs.emplace_back(registry, *first);
}
return state_->invoke_error(vargs);
return state_->invoke_error({vargs.begin(), vargs.end()});
}
}

View File

@@ -232,19 +232,11 @@ namespace meta_hpp
template < typename Instance >
uresult member::try_get(Instance&& instance) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move an 'instance', just checks conversion errors
const uinst_base vinst{registry, META_HPP_FWD(instance)};
if ( const uerror err = state_->getter_error(vinst) ) {
return err;
}
// doesn't actually move an 'instance', just checks conversion errors
if ( const uerror err = check_gettable_error(META_HPP_FWD(instance)) ) {
return err;
}
const uinst vinst{registry, META_HPP_FWD(instance)};
return state_->getter(vinst);
return get(META_HPP_FWD(instance));
}
template < typename Instance >
@@ -263,21 +255,11 @@ namespace meta_hpp
template < typename Instance, typename Value >
uresult member::try_set(Instance&& instance, Value&& value) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
{
// doesn't actually move an 'instance' and 'args', just checks conversion errors
const uinst_base vinst{registry, META_HPP_FWD(instance)};
const uarg_base vvalue{registry, META_HPP_FWD(value)};
if ( const uerror err = state_->setter_error(vinst, vvalue) ) {
return err;
}
// doesn't actually move an 'instance' and a 'value', just checks conversion errors
if ( const uerror err = check_settable_error(META_HPP_FWD(instance), META_HPP_FWD(value)) ) {
return err;
}
const uinst vinst{registry, META_HPP_FWD(instance)};
const uarg vvalue{registry, META_HPP_FWD(value)};
state_->setter(vinst, vvalue);
set(META_HPP_FWD(instance), META_HPP_FWD(value));
return uerror{error_code::no_error};
}
@@ -287,27 +269,27 @@ namespace meta_hpp
}
template < typename Instance >
[[nodiscard]] bool member::is_gettable_with() const noexcept {
[[nodiscard]] bool member::is_gettable_with() const {
return !check_gettable_error<Instance>();
}
template < typename Instance >
[[nodiscard]] bool member::is_gettable_with(Instance&& instance) const noexcept {
[[nodiscard]] bool member::is_gettable_with(Instance&& instance) const {
return !check_gettable_error(META_HPP_FWD(instance));
}
template < typename Instance, typename Value >
[[nodiscard]] bool member::is_settable_with() const noexcept {
[[nodiscard]] bool member::is_settable_with() const {
return !check_settable_error<Instance, Value>();
}
template < typename Instance, typename Value >
[[nodiscard]] bool member::is_settable_with(Instance&& instance, Value&& value) const noexcept {
[[nodiscard]] bool member::is_settable_with(Instance&& instance, Value&& value) const {
return !check_settable_error(META_HPP_FWD(instance), META_HPP_FWD(value));
}
template < typename Instance >
[[nodiscard]] uerror member::check_gettable_error() const noexcept {
[[nodiscard]] uerror member::check_gettable_error() const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uinst_base vinst{registry, type_list<Instance>{}};
@@ -315,7 +297,7 @@ namespace meta_hpp
}
template < typename Instance >
[[nodiscard]] uerror member::check_gettable_error(Instance&& instance) const noexcept {
[[nodiscard]] uerror member::check_gettable_error(Instance&& instance) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uinst_base vinst{registry, META_HPP_FWD(instance)};
@@ -323,7 +305,7 @@ namespace meta_hpp
}
template < typename Instance, typename Value >
[[nodiscard]] uerror member::check_settable_error() const noexcept {
[[nodiscard]] uerror member::check_settable_error() const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uinst_base vinst{registry, type_list<Instance>{}};
@@ -332,7 +314,7 @@ namespace meta_hpp
}
template < typename Instance, typename Value >
[[nodiscard]] uerror member::check_settable_error(Instance&& instance, Value&& value) const noexcept {
[[nodiscard]] uerror member::check_settable_error(Instance&& instance, Value&& value) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uinst_base vinst{registry, META_HPP_FWD(instance)};

View File

@@ -131,10 +131,11 @@ namespace meta_hpp::detail
template < method_policy_family Policy, method_pointer_kind Method >
method_state::state_ptr method_state::make(std::string name, Method method_ptr, metadata_map metadata) {
using mt = method_traits<Method>;
type_registry& registry{type_registry::instance()};
method_state state{
method_index{registry.resolve_by_type<Method>(), std::move(name)},
method_index{registry.resolve_by_traits<mt>(), std::move(name)},
std::move(metadata),
};
@@ -192,17 +193,17 @@ namespace meta_hpp
}
template < typename Instance, typename... Args >
bool method::is_invocable_with() const noexcept {
bool method::is_invocable_with() const {
return !check_invocable_error<Instance, Args...>();
}
template < typename Instance, typename... Args >
bool method::is_invocable_with(Instance&& instance, Args&&... args) const noexcept {
bool method::is_invocable_with(Instance&& instance, Args&&... args) const {
return !check_invocable_error(META_HPP_FWD(instance), META_HPP_FWD(args)...);
}
template < typename Instance, typename... Args >
uerror method::check_invocable_error() const noexcept {
uerror method::check_invocable_error() const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uinst_base vinst{registry, type_list<Instance>{}};
@@ -211,7 +212,7 @@ namespace meta_hpp
}
template < typename Instance, typename... Args >
uerror method::check_invocable_error(Instance&& instance, Args&&... args) const noexcept {
uerror method::check_invocable_error(Instance&& instance, Args&&... args) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uinst_base vinst{registry, META_HPP_FWD(instance)};
@@ -222,23 +223,31 @@ namespace meta_hpp
template < typename Instance, typename Iter >
uvalue method::invoke_variadic(Instance&& instance, Iter first, Iter last) const {
using namespace detail;
const std::size_t arity = get_arity();
type_registry& registry{type_registry::instance()};
const uinst vinst{registry, META_HPP_FWD(instance)};
static thread_local std::vector<uarg> vargs;
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_PUSH()
vargs.clear();
vargs.reserve(get_type().get_arity());
void* vargs_mem = META_HPP_ALLOCA(sizeof(uarg) * arity);
detail::inline_vector<uarg> vargs{static_cast<uarg*>(vargs_mem), arity};
for ( ; first != last; ++first ) {
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_POP()
for ( std::size_t i{}; first != last; ++i, ++first ) {
if ( i >= arity ) {
throw_exception(error_code::arity_mismatch);
}
vargs.emplace_back(registry, *first);
}
return state_->invoke(vinst, vargs);
const uinst vinst{registry, META_HPP_FWD(instance)};
return state_->invoke(vinst, {vargs.begin(), vargs.end()});
}
template < typename Instance, typename Iter >
uresult method::try_invoke_variadic(Instance&& instance, Iter first, Iter last) const {
// doesn't actually move an 'instance', just checks conversion errors
if ( const uerror err = check_variadic_invocable_error(META_HPP_FWD(instance), first, last) ) {
return err;
}
@@ -253,18 +262,25 @@ namespace meta_hpp
template < typename Instance, typename Iter >
uerror method::check_variadic_invocable_error(Instance&& instance, Iter first, Iter last) const {
using namespace detail;
const std::size_t arity = get_arity();
type_registry& registry{type_registry::instance()};
const uinst_base vinst{registry, META_HPP_FWD(instance)};
static thread_local std::vector<uarg_base> vargs;
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_PUSH()
vargs.clear();
vargs.reserve(get_type().get_arity());
void* vargs_mem = META_HPP_ALLOCA(sizeof(uarg_base) * arity);
detail::inline_vector<uarg_base> vargs{static_cast<uarg_base*>(vargs_mem), arity};
for ( ; first != last; ++first ) {
META_HPP_DETAIL_IGNORE_ALLOCA_WARNINGS_POP()
for ( std::size_t i{}; first != last; ++i, ++first ) {
if ( i >= arity ) {
return uerror(error_code::arity_mismatch);
}
vargs.emplace_back(registry, *first);
}
return state_->invoke_error(vinst, vargs);
const uinst_base vinst{registry, META_HPP_FWD(instance)};
return state_->invoke_error(vinst, {vargs.begin(), vargs.end()});
}
}

View File

@@ -77,7 +77,7 @@ namespace meta_hpp
template < typename... Args >
function scope::get_function_with( //
std::string_view name
) const noexcept {
) const {
detail::type_registry& registry{detail::type_registry::instance()};
return get_function_with(name, {registry.resolve_by_type<Args>()...});
}
@@ -87,7 +87,7 @@ namespace meta_hpp
std::string_view name,
Iter first,
Iter last
) const noexcept {
) const {
for ( const function& function : state_->functions ) {
if ( function.get_name() != name ) {
continue;

View File

@@ -186,17 +186,17 @@ namespace meta_hpp
}
template < typename Value >
bool variable::is_settable_with() const noexcept {
bool variable::is_settable_with() const {
return !check_settable_error<Value>();
}
template < typename Value >
bool variable::is_settable_with(Value&& value) const noexcept {
bool variable::is_settable_with(Value&& value) const {
return !check_settable_error(META_HPP_FWD(value));
}
template < typename Value >
uerror variable::check_settable_error() const noexcept {
uerror variable::check_settable_error() const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uarg_base vvalue{registry, type_list<Value>{}};
@@ -204,7 +204,7 @@ namespace meta_hpp
}
template < typename Value >
uerror variable::check_settable_error(Value&& value) const noexcept {
uerror variable::check_settable_error(Value&& value) const {
using namespace detail;
type_registry& registry{type_registry::instance()};
const uarg_base vvalue{registry, META_HPP_FWD(value)};

View File

@@ -180,19 +180,19 @@ namespace meta_hpp
bool destroy_at(void* mem) const;
template < class_kind Derived >
[[nodiscard]] bool is_base_of() const noexcept;
[[nodiscard]] bool is_base_of() const;
[[nodiscard]] bool is_base_of(const class_type& derived) const noexcept;
template < class_kind Derived >
[[nodiscard]] bool is_direct_base_of() const noexcept;
[[nodiscard]] bool is_direct_base_of() const;
[[nodiscard]] bool is_direct_base_of(const class_type& derived) const noexcept;
template < class_kind Base >
[[nodiscard]] bool is_derived_from() const noexcept;
[[nodiscard]] bool is_derived_from() const;
[[nodiscard]] bool is_derived_from(const class_type& base) const noexcept;
template < class_kind Base >
[[nodiscard]] bool is_direct_derived_from() const noexcept;
[[nodiscard]] bool is_direct_derived_from() const;
[[nodiscard]] bool is_direct_derived_from(const class_type& base) const noexcept;
[[nodiscard]] function get_function(std::string_view name, bool recursively = true) const noexcept;
@@ -202,9 +202,9 @@ namespace meta_hpp
[[nodiscard]] variable get_variable(std::string_view name, bool recursively = true) const noexcept;
template < typename... Args >
[[nodiscard]] constructor get_constructor_with() const noexcept;
[[nodiscard]] constructor get_constructor_with() const;
template < typename Iter >
[[nodiscard]] constructor get_constructor_with(Iter first, Iter last) const noexcept;
[[nodiscard]] constructor get_constructor_with(Iter first, Iter last) const;
[[nodiscard]] constructor get_constructor_with(std::span<const any_type> args) const noexcept;
[[nodiscard]] constructor get_constructor_with(std::initializer_list<any_type> args) const noexcept;
@@ -214,7 +214,7 @@ namespace meta_hpp
[[nodiscard]] function get_function_with( //
std::string_view name,
bool recursively = true
) const noexcept;
) const;
template < typename Iter >
[[nodiscard]] function get_function_with( //
@@ -222,7 +222,7 @@ namespace meta_hpp
Iter first,
Iter last,
bool recursively = true
) const noexcept;
) const;
[[nodiscard]] function get_function_with( //
std::string_view name,
@@ -240,7 +240,7 @@ namespace meta_hpp
[[nodiscard]] method get_method_with( //
std::string_view name,
bool recursively = true
) const noexcept;
) const;
template < typename Iter >
[[nodiscard]] method get_method_with( //
@@ -248,7 +248,7 @@ namespace meta_hpp
Iter first,
Iter last,
bool recursively = true
) const noexcept;
) const;
[[nodiscard]] method get_method_with( //
std::string_view name,
@@ -294,7 +294,7 @@ namespace meta_hpp
[[nodiscard]] evalue get_evalue(std::string_view name) const noexcept;
template < enum_kind Enum >
[[nodiscard]] std::string_view value_to_name(Enum value) const noexcept;
[[nodiscard]] std::string_view value_to_name(Enum value) const;
[[nodiscard]] const uvalue& name_to_value(std::string_view name) const noexcept;
};

View File

@@ -44,21 +44,19 @@ namespace meta_hpp::detail::class_type_data_impl
});
if constexpr ( check_base_info_enabled<Target> ) {
using target_base_info = get_meta_base_info<Target>;
target_base_info::for_each([&info]<class_kind TargetBase>() { //
add_upcast_info<Class, TargetBase>(info);
});
[&info]<typename... TargetBases>(type_list<TargetBases...>) {
(add_upcast_info<Class, TargetBases>(info), ...);
}(get_meta_base_info<Target>{});
}
}
template < class_kind Class >
void fill_upcast_info(new_base_info_t& info) {
if constexpr ( check_base_info_enabled<Class> ) {
using class_base_info = get_meta_base_info<Class>;
class_base_info::for_each([&info]<class_kind ClassBase>() {
info.base_classes.push_back(resolve_type<ClassBase>());
add_upcast_info<Class, ClassBase>(info);
});
[&info]<typename... ClassBases>(type_list<ClassBases...>) {
(info.base_classes.push_back(resolve_type<ClassBases>()), ...);
(add_upcast_info<Class, ClassBases>(info), ...);
}(get_meta_base_info<Class>{});
}
}
@@ -243,7 +241,7 @@ namespace meta_hpp
}
template < class_kind Derived >
bool class_type::is_base_of() const noexcept {
bool class_type::is_base_of() const {
return is_base_of(resolve_type<Derived>());
}
@@ -262,7 +260,7 @@ namespace meta_hpp
}
template < class_kind Derived >
bool class_type::is_direct_base_of() const noexcept {
bool class_type::is_direct_base_of() const {
return is_direct_base_of(resolve_type<Derived>());
}
@@ -281,7 +279,7 @@ namespace meta_hpp
}
template < class_kind Base >
bool class_type::is_derived_from() const noexcept {
bool class_type::is_derived_from() const {
return is_derived_from(resolve_type<Base>());
}
@@ -290,7 +288,7 @@ namespace meta_hpp
}
template < class_kind Base >
bool class_type::is_direct_derived_from() const noexcept {
bool class_type::is_direct_derived_from() const {
return is_direct_derived_from(resolve_type<Base>());
}
@@ -391,13 +389,13 @@ namespace meta_hpp
//
template < typename... Args >
constructor class_type::get_constructor_with() const noexcept {
constructor class_type::get_constructor_with() const {
detail::type_registry& registry{detail::type_registry::instance()};
return get_constructor_with({registry.resolve_by_type<Args>()...});
}
template < typename Iter >
constructor class_type::get_constructor_with(Iter first, Iter last) const noexcept {
constructor class_type::get_constructor_with(Iter first, Iter last) const {
for ( const constructor& constructor : data_->constructors ) {
const constructor_type& constructor_type = constructor.get_type();
const any_type_list& constructor_args = constructor_type.get_argument_types();
@@ -436,7 +434,7 @@ namespace meta_hpp
function class_type::get_function_with( //
std::string_view name,
bool recursively
) const noexcept {
) const {
detail::type_registry& registry{detail::type_registry::instance()};
return get_function_with(name, {registry.resolve_by_type<Args>()...}, recursively);
}
@@ -447,7 +445,7 @@ namespace meta_hpp
Iter first,
Iter last,
bool recursively
) const noexcept {
) const {
for ( const function& function : data_->functions ) {
if ( function.get_name() != name ) {
continue;
@@ -496,7 +494,7 @@ namespace meta_hpp
method class_type::get_method_with( //
std::string_view name,
bool recursively
) const noexcept {
) const {
detail::type_registry& registry{detail::type_registry::instance()};
return get_method_with(name, {registry.resolve_by_type<Args>()...}, recursively);
}
@@ -507,7 +505,7 @@ namespace meta_hpp
Iter first,
Iter last,
bool recursively
) const noexcept {
) const {
for ( const method& method : data_->methods ) {
if ( method.get_name() != name ) {
continue;

View File

@@ -49,7 +49,7 @@ namespace meta_hpp
}
template < enum_kind Enum >
std::string_view enum_type::value_to_name(Enum value) const noexcept {
std::string_view enum_type::value_to_name(Enum value) const {
if ( resolve_type<Enum>() != *this ) {
return std::string_view{};
}

View File

@@ -102,12 +102,16 @@
### Functions
| | |
| -------------------------------------------------------------- | --------------------- |
| [invoke](./api/invoke.md#invoke) | invoke |
| [try_invoke](./api/invoke.md#try_invoke) | try_invoke |
| [is_invocable_with](./api/invoke.md#is_invocable_with) | is_invocable_with |
| [check_invocable_error](./api/invoke.md#check_invocable_error) | check_invocable_error |
| | |
| -------------------------------------------------------------------------------- | ------------------------------ |
| [invoke](./api/invoke.md#invoke) | invoke |
| [invoke_variadic](./api/invoke.md#invoke_variadic) | invoke_variadic |
| [try_invoke](./api/invoke.md#try_invoke) | try_invoke |
| [try_invoke_variadic](./api/invoke.md#try_invoke_variadic) | try_invoke_variadic |
| [is_invocable_with](./api/invoke.md#is_invocable_with) | is_invocable_with |
| [is_variadic_invocable_with](./api/invoke.md#is_variadic_invocable_with) | is_variadic_invocable_with |
| [check_invocable_error](./api/invoke.md#check_invocable_error) | check_invocable_error |
| [check_variadic_invocable_error](./api/invoke.md#check_variadic_invocable_error) | check_variadic_invocable_error |
## Policies
@@ -156,7 +160,7 @@
| | |
| --------------------------------------------------- | ---------------- |
| [type_id](./api/basics.md#type_id) | type_id |
| [type_id](./api/types.md#type_id) | type_id |
| [type_base](./api/types.md#type_base) | type_base |
| [any_type](./api/types.md#any_type) | any_type |
| [array_type](./api/types.md#array_type) | array_type |

View File

@@ -1,9 +1,13 @@
- [API Invoke](#api-invoke)
- [Functions](#functions)
- [invoke](#invoke)
- [invoke\_variadic](#invoke_variadic)
- [try\_invoke](#try_invoke)
- [try\_invoke\_variadic](#try_invoke_variadic)
- [is\_invocable\_with](#is_invocable_with)
- [is\_variadic\_invocable\_with](#is_variadic_invocable_with)
- [check\_invocable\_error](#check_invocable_error)
- [check\_variadic\_invocable\_error](#check_variadic_invocable_error)
# API Invoke
@@ -35,6 +39,25 @@ template < method_pointer_kind Method, typename Instance, typename... Args >
uvalue invoke(Method method_ptr, Instance&& instance, Args&&... args);
```
### invoke_variadic
```cpp
template < typename Iter >
uvalue invoke_variadic(const function& function, Iter first, Iter last);
template < function_pointer_kind Function, typename Iter >
uvalue invoke_variadic(Function function_ptr, Iter first, Iter last);
//
template < typename Instance, typename Iter >
uvalue invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last);
template < method_pointer_kind Method, typename Instance, typename Iter >
uvalue invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last);
```
### try_invoke
```cpp
@@ -61,6 +84,24 @@ template < method_pointer_kind Method, typename Instance, typename... Args >
uresult try_invoke(Method method_ptr, Instance&& instance, Args&&... args);
```
### try_invoke_variadic
```cpp
template < typename Iter >
uresult try_invoke_variadic(const function& function, Iter first, Iter last);
template < function_pointer_kind Function, typename Iter >
uresult try_invoke_variadic(Function function_ptr, Iter first, Iter last);
//
template < typename Instance, typename Iter >
uresult try_invoke_variadic(const method& method, Instance&& instance, Iter first, Iter last);
template < method_pointer_kind Method, typename Instance, typename Iter >
uresult try_invoke_variadic(Method method_ptr, Instance&& instance, Iter first, Iter last);
```
### is_invocable_with
```cpp
@@ -105,6 +146,24 @@ template < typename Instance, typename... Args, method_pointer_kind Method >
bool is_invocable_with(Method method_ptr, Instance&& instance, Args&&... args) noexcept;
```
### is_variadic_invocable_with
```cpp
template < typename Iter >
bool is_variadic_invocable_with(const function& function, Iter first, Iter last);
template < typename Iter, function_pointer_kind Function >
bool is_variadic_invocable_with(Function function_ptr, Iter first, Iter last);
//
template < typename Instance, typename Iter >
bool is_variadic_invocable_with(const method& method, Instance&& instance, Iter first, Iter last);
template < typename Instance, typename Iter, method_pointer_kind Method >
bool is_variadic_invocable_with(Method method_ptr, Instance&& instance, Iter first, Iter last);
```
### check_invocable_error
```cpp
@@ -148,3 +207,21 @@ uerror check_invocable_error(Method method_ptr) noexcept;
template < typename Instance, typename... Args, method_pointer_kind Method >
uerror check_invocable_error(Method method_ptr, Instance&& instance, Args&&... args) noexcept;
```
### check_variadic_invocable_error
```cpp
template < typename Iter >
uerror check_variadic_invocable_error(const function& function, Iter first, Iter last);
template < typename Iter, function_pointer_kind Function >
uerror check_variadic_invocable_error(Function function_ptr, Iter first, Iter last);
//
template < typename Instance, typename Iter >
uerror check_variadic_invocable_error(const method& method, Instance&& instance, Iter first, Iter last);
template < typename Instance, typename Iter, method_pointer_kind Method >
uerror check_variadic_invocable_error(Method method_ptr, Instance&& instance, Iter first, Iter last);
```

View File

@@ -83,16 +83,16 @@ public:
uresult try_create_at(void* mem, Args&&... args) const;
template < typename... Args >
bool is_invocable_with() const noexcept;
bool is_invocable_with() const;
template < typename... Args >
bool is_invocable_with(Args&&... args) const noexcept;
bool is_invocable_with(Args&&... args) const;
template < typename... Args >
uerror check_invocable_error() const noexcept;
uerror check_invocable_error() const;
template < typename... Args >
uerror check_invocable_error(Args&&... args) const noexcept;
uerror check_invocable_error(Args&&... args) const;
//
@@ -109,10 +109,10 @@ public:
uresult try_create_variadic_at(void* mem, Iter first, Iter last) const;
template < typename Iter >
bool is_variadic_invocable_with(Iter first, Iter last) const noexcept;
bool is_variadic_invocable_with(Iter first, Iter last) const;
template < typename Iter >
uerror check_variadic_invocable_error(Iter first, Iter last) const noexcept;
uerror check_variadic_invocable_error(Iter first, Iter last) const;
};
```
@@ -136,16 +136,16 @@ public:
uresult try_destroy_at(void* mem) const;
template < typename Arg >
bool is_invocable_with() const noexcept;
bool is_invocable_with() const;
template < typename Arg >
bool is_invocable_with(Arg&& arg) const noexcept;
bool is_invocable_with(Arg&& arg) const;
template < typename Arg >
uerror check_invocable_error() const noexcept;
uerror check_invocable_error() const;
template < typename Arg >
uerror check_invocable_error(Arg&& arg) const noexcept;
uerror check_invocable_error(Arg&& arg) const;
};
```
@@ -190,16 +190,16 @@ public:
uvalue operator()(Args&&... args) const;
template < typename... Args >
bool is_invocable_with() const noexcept;
bool is_invocable_with() const;
template < typename... Args >
bool is_invocable_with(Args&&... args) const noexcept;
bool is_invocable_with(Args&&... args) const;
template < typename... Args >
uerror check_invocable_error() const noexcept;
uerror check_invocable_error() const;
template < typename... Args >
uerror check_invocable_error(Args&&... args) const noexcept;
uerror check_invocable_error(Args&&... args) const;
//
@@ -246,28 +246,28 @@ public:
void operator()(Instance&& instance, Value&& value) const;
template < typename Instance >
bool is_gettable_with() const noexcept;
bool is_gettable_with() const;
template < typename Instance >
bool is_gettable_with(Instance&& instance) const noexcept;
bool is_gettable_with(Instance&& instance) const;
template < typename Instance, typename Value >
bool is_settable_with() const noexcept;
bool is_settable_with() const;
template < typename Instance, typename Value >
bool is_settable_with(Instance&& instance, Value&& value) const noexcept;
bool is_settable_with(Instance&& instance, Value&& value) const;
template < typename Instance >
uerror check_gettable_error() const noexcept;
uerror check_gettable_error() const;
template < typename Instance >
uerror check_gettable_error(Instance&& instance) const noexcept;
uerror check_gettable_error(Instance&& instance) const;
template < typename Instance, typename Value >
uerror check_settable_error() const noexcept;
uerror check_settable_error() const;
template < typename Instance, typename Value >
uerror check_settable_error(Instance&& instance, Value&& value) const noexcept;
uerror check_settable_error(Instance&& instance, Value&& value) const;
};
```
@@ -297,16 +297,16 @@ public:
uvalue operator()(Instance&& instance, Args&&... args) const;
template < typename Instance, typename... Args >
bool is_invocable_with() const noexcept;
bool is_invocable_with() const;
template < typename Instance, typename... Args >
bool is_invocable_with(Instance&& instance, Args&&... args) const noexcept;
bool is_invocable_with(Instance&& instance, Args&&... args) const;
template < typename Instance, typename... Args >
uerror check_invocable_error() const noexcept;
uerror check_invocable_error() const;
template < typename Instance, typename... Args >
uerror check_invocable_error(Instance&& instance, Args&&... args) const noexcept;
uerror check_invocable_error(Instance&& instance, Args&&... args) const;
//
@@ -344,14 +344,14 @@ public:
template < typename... Args >
function get_function_with(
std::string_view name
) const noexcept;
) const;
template < typename Iter >
function get_function_with(
std::string_view name,
Iter first,
Iter last
) const noexcept;
) const;
function get_function_with(
std::string_view name,
@@ -390,15 +390,15 @@ public:
void operator()(Value&& value) const;
template < typename Value >
bool is_settable_with() const noexcept;
bool is_settable_with() const;
template < typename Value >
bool is_settable_with(Value&& value) const noexcept;
bool is_settable_with(Value&& value) const;
template < typename Value >
uerror check_settable_error() const noexcept;
uerror check_settable_error() const;
template < typename Value >
uerror check_settable_error(Value&& value) const noexcept;
uerror check_settable_error(Value&& value) const;
};
```

View File

@@ -185,19 +185,19 @@ public:
bool destroy_at(void* mem) const;
template < class_kind Derived >
bool is_base_of() const noexcept;
bool is_base_of() const;
bool is_base_of(const class_type& derived) const noexcept;
template < class_kind Derived >
bool is_direct_base_of() const noexcept;
bool is_direct_base_of() const;
bool is_direct_base_of(const class_type& derived) const noexcept;
template < class_kind Base >
bool is_derived_from() const noexcept;
bool is_derived_from() const;
bool is_derived_from(const class_type& base) const noexcept;
template < class_kind Base >
bool is_direct_derived_from() const noexcept;
bool is_direct_derived_from() const;
bool is_direct_derived_from(const class_type& base) const noexcept;
function get_function(std::string_view name, bool recursively = true) const noexcept;
@@ -207,9 +207,9 @@ public:
variable get_variable(std::string_view name, bool recursively = true) const noexcept;
template < typename... Args >
constructor get_constructor_with() const noexcept;
constructor get_constructor_with() const;
template < typename Iter >
constructor get_constructor_with(Iter first, Iter last) const noexcept;
constructor get_constructor_with(Iter first, Iter last) const;
constructor get_constructor_with(std::span<const any_type> args) const noexcept;
constructor get_constructor_with(std::initializer_list<any_type> args) const noexcept;
@@ -219,7 +219,7 @@ public:
function get_function_with(
std::string_view name,
bool recursively = true
) const noexcept;
) const;
template < typename Iter >
function get_function_with(
@@ -227,7 +227,7 @@ public:
Iter first,
Iter last,
bool recursively = true
) const noexcept;
) const;
function get_function_with(
std::string_view name,
@@ -245,7 +245,7 @@ public:
method get_method_with(
std::string_view name,
bool recursively = true
) const noexcept;
) const;
template < typename Iter >
method get_method_with(
@@ -253,7 +253,7 @@ public:
Iter first,
Iter last,
bool recursively = true
) const noexcept;
) const;
method get_method_with(
std::string_view name,
@@ -311,7 +311,7 @@ public:
evalue get_evalue(std::string_view name) const noexcept;
template < enum_kind Enum >
std::string_view value_to_name(Enum value) const noexcept;
std::string_view value_to_name(Enum value) const;
const uvalue& name_to_value(std::string_view name) const noexcept;
};
```