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 "string_bt.hpp"
|
||||
#if defined(WRENPP_WITH_NAME_GUESSING)
|
||||
# include "guess_class_name.hpp"
|
||||
#endif
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
@ -67,6 +70,11 @@ namespace wren {
|
|||
template <typename T, typename... 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>
|
||||
foreign_method_t make_method_bindable();
|
||||
|
||||
|
@ -315,6 +323,17 @@ namespace wren {
|
|||
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>
|
||||
inline foreign_method_t make_method_bindable() {
|
||||
return detail::MakeMethodBindable<V>::make();
|
||||
|
|
10
meson.build
10
meson.build
|
@ -1,7 +1,7 @@
|
|||
project('wrenpp', 'cpp',
|
||||
version: '0.1.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',
|
||||
|
@ -14,7 +14,7 @@ wren_dep = dependency('wren', version: '>=0.2.0',
|
|||
],
|
||||
static: true,
|
||||
)
|
||||
public_incl = include_directories('include')
|
||||
public_incl = [include_directories('include')]
|
||||
|
||||
os = host_machine.system()
|
||||
if os == 'gnu'
|
||||
|
@ -45,11 +45,13 @@ conf.set('FUNC_POINTER_SIZE', func_ptr_size)
|
|||
conf.set('WRENPP_NAME', meson.project_name())
|
||||
|
||||
project_config_file = configure_file(
|
||||
input: 'src/config.h.in',
|
||||
output: 'config.h',
|
||||
input: 'src/pvt_config.h.in',
|
||||
output: 'pvt_config.h',
|
||||
configuration: conf
|
||||
)
|
||||
|
||||
subdir('include')
|
||||
|
||||
wrenpp = library(meson.project_name(),
|
||||
project_config_file,
|
||||
'src/vm.cpp',
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#endif
|
||||
|
||||
#include "dynafunc_maker.hpp"
|
||||
#include "config.h"
|
||||
#include "pvt_config.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <unistd.h> //for sysconf()
|
||||
|
|
Loading…
Reference in a new issue