Add make_foreign_object() overload
It's only available when users define WRENPP_WITH_NAME_GUESSING and it automatically retrieves the class name of T using new code in guess_class_name.hpp. Only tested on gcc so far. Microsoft compiler doesn't seem to understand consteval keyword.
This commit is contained in:
parent
10e3c9adac
commit
5d6575f328
7 changed files with 106 additions and 5 deletions
1
include/meson.build
Normal file
1
include/meson.build
Normal file
|
@ -0,0 +1 @@
|
||||||
|
subdir('wrenpp')
|
63
include/wrenpp/guess_class_name.hpp
Normal file
63
include/wrenpp/guess_class_name.hpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#include "string_bt.hpp"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace wren {
|
||||||
|
namespace detail {
|
||||||
|
consteval std::size_t find_last (const char* str, std::size_t len, char c) {
|
||||||
|
for (std::size_t z = len; z > 0; --z) {
|
||||||
|
if (str[z - 1] == c)
|
||||||
|
return z - 1;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
consteval std::size_t find_token_end (const char* str, std::size_t len) {
|
||||||
|
for (std::size_t z = 0; z < len; ++z) {
|
||||||
|
const bool is_lower = str[z] >= 'a' and str[z] <= 'z';
|
||||||
|
const bool is_upper = str[z] >= 'A' and str[z] <= 'Z';
|
||||||
|
const bool is_num = str[z] >= '0' and str[z] <= '9';
|
||||||
|
const bool is_special = str[z] == '_' or str[z] == ':';
|
||||||
|
if (not (is_lower or is_upper or is_num or is_special))
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
consteval auto guess_class_name_impl() {
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
constexpr auto fname = __PRETTY_FUNCTION__;
|
||||||
|
constexpr auto fname_len = sizeof(__PRETTY_FUNCTION__) / sizeof(__PRETTY_FUNCTION__[0]) - 1;
|
||||||
|
static_assert(fname_len > 0);
|
||||||
|
|
||||||
|
# if defined(__clang__)
|
||||||
|
//clang: void figure_out_name() [T = MyTest]
|
||||||
|
# else
|
||||||
|
//gcc: void figure_out_name() [with T = MyTest]
|
||||||
|
# endif
|
||||||
|
constexpr auto last_colon = detail::find_last(fname, fname_len, ':');
|
||||||
|
constexpr auto last_space = detail::find_last(fname, fname_len, ' ');
|
||||||
|
constexpr auto last_whatever = (last_colon == fname_len ? last_space : last_colon);
|
||||||
|
constexpr auto from = last_whatever + (last_whatever == fname_len ? 0 : 1);
|
||||||
|
constexpr auto len = detail::find_token_end(fname + from, fname_len - from);
|
||||||
|
|
||||||
|
constexpr dhandy::bt::string<len> retval{std::make_index_sequence<len>{}, fname + from};
|
||||||
|
return retval;
|
||||||
|
//#elif defined(_MSC_VER)
|
||||||
|
//void __cdecl guess_class_name<class MyTest>(void)
|
||||||
|
//__FUNCSIG__
|
||||||
|
#else
|
||||||
|
# error "Unsupported compiler"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t S=guess_class_name_impl<T>().size()>
|
||||||
|
static constinit dhandy::bt::string g_class_names = {guess_class_name_impl<T>()};
|
||||||
|
} //namespace detail
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
const char* guess_class_name() {
|
||||||
|
return detail::g_class_names<T>.data;
|
||||||
|
}
|
||||||
|
} //namespace wren
|
16
include/wrenpp/meson.build
Normal file
16
include/wrenpp/meson.build
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
include_files = [
|
||||||
|
'configuration.hpp',
|
||||||
|
'def_configuration.hpp',
|
||||||
|
'error_type.hpp',
|
||||||
|
'guess_class_name.hpp',
|
||||||
|
'handle.hpp',
|
||||||
|
'has_method.hpp',
|
||||||
|
'meson.build',
|
||||||
|
'string_bt.hpp',
|
||||||
|
'StringCRC32.hpp',
|
||||||
|
'vm_fun.hpp',
|
||||||
|
'vm.hpp',
|
||||||
|
'wren_types.hpp',
|
||||||
|
]
|
||||||
|
|
||||||
|
install_data(sources: include_files, install_dir: 'include/wrenpp')
|
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
#include "vm.hpp"
|
#include "vm.hpp"
|
||||||
#include "string_bt.hpp"
|
#include "string_bt.hpp"
|
||||||
|
#if defined(WRENPP_WITH_NAME_GUESSING)
|
||||||
|
# include "guess_class_name.hpp"
|
||||||
|
#endif
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -67,6 +70,11 @@ namespace wren {
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
T* make_foreign_object(VM& vm, const ModuleAndName& mn, Args&&... args);
|
T* make_foreign_object(VM& vm, const ModuleAndName& mn, Args&&... args);
|
||||||
|
|
||||||
|
#if defined(WRENPP_WITH_NAME_GUESSING)
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
T* make_foreign_object(VM& vm, const char* module, Args&&... args);
|
||||||
|
#endif
|
||||||
|
|
||||||
template <auto V>
|
template <auto V>
|
||||||
foreign_method_t make_method_bindable();
|
foreign_method_t make_method_bindable();
|
||||||
|
|
||||||
|
@ -315,6 +323,17 @@ namespace wren {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WRENPP_WITH_NAME_GUESSING)
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
inline T* make_foreign_object(VM& vm, const char* module, Args&&... args) {
|
||||||
|
return make_foreign_object<T>(
|
||||||
|
vm,
|
||||||
|
ModuleAndName{module, guess_class_name<T>()},
|
||||||
|
std::forward<Args>(args)...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <auto V>
|
template <auto V>
|
||||||
inline foreign_method_t make_method_bindable() {
|
inline foreign_method_t make_method_bindable() {
|
||||||
return detail::MakeMethodBindable<V>::make();
|
return detail::MakeMethodBindable<V>::make();
|
||||||
|
|
10
meson.build
10
meson.build
|
@ -1,7 +1,7 @@
|
||||||
project('wrenpp', 'cpp',
|
project('wrenpp', 'cpp',
|
||||||
version: '0.1.2',
|
version: '0.1.2',
|
||||||
meson_version: '>=0.49.2',
|
meson_version: '>=0.49.2',
|
||||||
default_options: ['buildtype=release', 'cpp_std=c++17', 'b_ndebug=if-release'],
|
default_options: ['buildtype=release', 'cpp_std=c++20', 'b_ndebug=if-release']
|
||||||
)
|
)
|
||||||
|
|
||||||
wren_dep = dependency('wren', version: '>=0.2.0',
|
wren_dep = dependency('wren', version: '>=0.2.0',
|
||||||
|
@ -14,7 +14,7 @@ wren_dep = dependency('wren', version: '>=0.2.0',
|
||||||
],
|
],
|
||||||
static: true,
|
static: true,
|
||||||
)
|
)
|
||||||
public_incl = include_directories('include')
|
public_incl = [include_directories('include')]
|
||||||
|
|
||||||
os = host_machine.system()
|
os = host_machine.system()
|
||||||
if os == 'gnu'
|
if os == 'gnu'
|
||||||
|
@ -45,11 +45,13 @@ conf.set('FUNC_POINTER_SIZE', func_ptr_size)
|
||||||
conf.set('WRENPP_NAME', meson.project_name())
|
conf.set('WRENPP_NAME', meson.project_name())
|
||||||
|
|
||||||
project_config_file = configure_file(
|
project_config_file = configure_file(
|
||||||
input: 'src/config.h.in',
|
input: 'src/pvt_config.h.in',
|
||||||
output: 'config.h',
|
output: 'pvt_config.h',
|
||||||
configuration: conf
|
configuration: conf
|
||||||
)
|
)
|
||||||
|
|
||||||
|
subdir('include')
|
||||||
|
|
||||||
wrenpp = library(meson.project_name(),
|
wrenpp = library(meson.project_name(),
|
||||||
project_config_file,
|
project_config_file,
|
||||||
'src/vm.cpp',
|
'src/vm.cpp',
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "dynafunc_maker.hpp"
|
#include "dynafunc_maker.hpp"
|
||||||
#include "config.h"
|
#include "pvt_config.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <unistd.h> //for sysconf()
|
#include <unistd.h> //for sysconf()
|
||||||
|
|
Loading…
Add table
Reference in a new issue