diff --git a/include/meson.build b/include/meson.build new file mode 100644 index 0000000..5902c96 --- /dev/null +++ b/include/meson.build @@ -0,0 +1 @@ +subdir('wrenpp') diff --git a/include/wrenpp/guess_class_name.hpp b/include/wrenpp/guess_class_name.hpp new file mode 100644 index 0000000..e97f8ca --- /dev/null +++ b/include/wrenpp/guess_class_name.hpp @@ -0,0 +1,63 @@ +#include "string_bt.hpp" +#include +#include + +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 + 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 retval{std::make_index_sequence{}, fname + from}; + return retval; + //#elif defined(_MSC_VER) + //void __cdecl guess_class_name(void) + //__FUNCSIG__ +#else +# error "Unsupported compiler" +#endif + } + + template ().size()> + static constinit dhandy::bt::string g_class_names = {guess_class_name_impl()}; + } //namespace detail + + template + const char* guess_class_name() { + return detail::g_class_names.data; + } +} //namespace wren diff --git a/include/wrenpp/meson.build b/include/wrenpp/meson.build new file mode 100644 index 0000000..9009833 --- /dev/null +++ b/include/wrenpp/meson.build @@ -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') diff --git a/include/wrenpp/vm_fun.hpp b/include/wrenpp/vm_fun.hpp index cc2b908..b208c5f 100644 --- a/include/wrenpp/vm_fun.hpp +++ b/include/wrenpp/vm_fun.hpp @@ -19,6 +19,9 @@ #include "vm.hpp" #include "string_bt.hpp" +#if defined(WRENPP_WITH_NAME_GUESSING) +# include "guess_class_name.hpp" +#endif #include #include #include @@ -67,6 +70,11 @@ namespace wren { template T* make_foreign_object(VM& vm, const ModuleAndName& mn, Args&&... args); +#if defined(WRENPP_WITH_NAME_GUESSING) + template + T* make_foreign_object(VM& vm, const char* module, Args&&... args); +#endif + template foreign_method_t make_method_bindable(); @@ -315,6 +323,17 @@ namespace wren { return obj; } +#if defined(WRENPP_WITH_NAME_GUESSING) + template + inline T* make_foreign_object(VM& vm, const char* module, Args&&... args) { + return make_foreign_object( + vm, + ModuleAndName{module, guess_class_name()}, + std::forward(args)... + ); + } +#endif + template inline foreign_method_t make_method_bindable() { return detail::MakeMethodBindable::make(); diff --git a/meson.build b/meson.build index e9cf2a8..5ee357a 100644 --- a/meson.build +++ b/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', diff --git a/src/dynafunc_maker.cpp b/src/dynafunc_maker.cpp index ab9cb0a..3d19bec 100644 --- a/src/dynafunc_maker.cpp +++ b/src/dynafunc_maker.cpp @@ -21,7 +21,7 @@ #endif #include "dynafunc_maker.hpp" -#include "config.h" +#include "pvt_config.h" #include #include #include //for sysconf() diff --git a/src/config.h.in b/src/pvt_config.h.in similarity index 100% rename from src/config.h.in rename to src/pvt_config.h.in