Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions examples/core_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ using namespace boost::openmethod;
class BOOST_OPENMETHOD_NAME(poke);

using poke = method<
BOOST_OPENMETHOD_NAME(poke)(std::ostream&, virtual_ptr<Animal>), void>;
BOOST_OPENMETHOD_NAME(poke),
auto(std::ostream&, virtual_ptr<Animal>)->void>;
// end::method[]

// tag::poke_cat[]
Expand Down Expand Up @@ -68,7 +69,7 @@ auto pet_dog(std::ostream& os, virtual_ptr<Dog> dog) {
}

using pet = method<
BOOST_OPENMETHOD_NAME(pet)(std::ostream&, virtual_ptr<Animal>), void>;
BOOST_OPENMETHOD_NAME(pet), auto(std::ostream&, virtual_ptr<Animal>)->void>;

BOOST_OPENMETHOD_REGISTER(pet::override<pet_cat, pet_dog>);

Expand Down
2 changes: 1 addition & 1 deletion examples/slides.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ using namespace nodes;
use_classes<Node, Number, Plus, Times> use_node_classes;

struct value_id;
using value = method<value_id(virtual_ptr<const Node>), int>;
using value = method<value_id, auto (virtual_ptr<const Node>)->int>;

auto number_value(virtual_ptr<const Number> node) -> int {
return node->val;
Expand Down
56 changes: 31 additions & 25 deletions include/boost/openmethod/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ namespace detail {
template<class Registry, class Class>
constexpr bool is_polymorphic = Registry::rtti::template is_polymorphic<Class>;

using macro_default_registry = BOOST_OPENMETHOD_DEFAULT_REGISTRY;

template<typename...>
struct extract_registry;

Expand Down Expand Up @@ -962,10 +964,11 @@ class method;

template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
class method<Name(Parameters...), ReturnType, Registry>
class method<Name, auto(Parameters...)->ReturnType, Registry>
Copy link

Copilot AI May 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] It would be helpful to update the documentation/comments near the method template specialization to explain the new auto(Parameters...)->ReturnType syntax and its intended usage, to aid future maintainers.

Copilot uses AI. Check for mistakes.
: public detail::method_info {
// Aliases used in implementation only. Everything extracted from template
// arguments is capitalized like the arguments themselves.
using RegistryType = Registry;
using rtti = typename Registry::rtti;
using DeclaredParameters = mp11::mp_list<Parameters...>;
using CallParameters =
Expand Down Expand Up @@ -1107,21 +1110,22 @@ class method<Name(Parameters...), ReturnType, Registry>

template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
method<Name(Parameters...), ReturnType, Registry>
method<Name(Parameters...), ReturnType, Registry>::fn;
method<Name, auto(Parameters...)->ReturnType, Registry>
method<Name, auto(Parameters...)->ReturnType, Registry>::fn;

template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
template<auto>
typename method<Name(Parameters...), ReturnType, Registry>::FunctionPointer
method<Name(Parameters...), ReturnType, Registry>::next;
typename method<
Name, auto(Parameters...)->ReturnType, Registry>::FunctionPointer
method<Name, auto(Parameters...)->ReturnType, Registry>::next;

template<typename T>
constexpr bool is_method = std::is_base_of_v<detail::method_info, T>;

template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
method<Name(Parameters...), ReturnType, Registry>::method() {
method<Name, auto(Parameters...)->ReturnType, Registry>::method() {
method_info::slots_strides_ptr = slots_strides;

using virtual_type_ids = detail::type_id_list<
Expand All @@ -1140,20 +1144,21 @@ method<Name(Parameters...), ReturnType, Registry>::method() {

template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
std::size_t method<
Name(Parameters...), ReturnType, Registry>::slots_strides[2 * Arity - 1];
std::size_t method<Name, auto(Parameters...)->ReturnType, Registry>::
slots_strides[2 * Arity - 1];

template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
method<Name(Parameters...), ReturnType, Registry>::~method() {
method<Name, auto(Parameters...)->ReturnType, Registry>::~method() {
Registry::methods.remove(*this);
}

template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
template<class Error>
auto method<Name(Parameters...), ReturnType, Registry>::check_static_offset(
std::size_t actual, std::size_t expected) const -> void {
auto method<Name, auto(Parameters...)->ReturnType, Registry>::
check_static_offset(std::size_t actual, std::size_t expected) const
-> void {
using namespace detail;
using error_handler =
typename Registry::template policy<policies::error_handler>;
Expand All @@ -1177,7 +1182,7 @@ auto method<Name(Parameters...), ReturnType, Registry>::check_static_offset(
template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
BOOST_FORCEINLINE auto
method<Name(Parameters...), ReturnType, Registry>::operator()(
method<Name, auto(Parameters...)->ReturnType, Registry>::operator()(
detail::remove_virtual<Parameters>... args) const -> ReturnType {
using namespace detail;
auto pf = resolve(parameter_traits<Parameters, Registry>::peek(args)...);
Expand All @@ -1188,10 +1193,10 @@ method<Name(Parameters...), ReturnType, Registry>::operator()(
template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
template<typename... ArgType>
BOOST_FORCEINLINE
typename method<Name(Parameters...), ReturnType, Registry>::FunctionPointer
method<Name(Parameters...), ReturnType, Registry>::resolve(
const ArgType&... args) const {
BOOST_FORCEINLINE typename method<
Name, auto(Parameters...)->ReturnType, Registry>::FunctionPointer
method<Name, auto(Parameters...)->ReturnType, Registry>::resolve(
const ArgType&... args) const {
using namespace detail;

std::uintptr_t pf;
Expand All @@ -1209,7 +1214,8 @@ BOOST_FORCEINLINE
template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
template<typename ArgType>
BOOST_FORCEINLINE auto method<Name(Parameters...), ReturnType, Registry>::vptr(
BOOST_FORCEINLINE auto
method<Name, auto(Parameters...)->ReturnType, Registry>::vptr(
const ArgType& arg) const -> vptr_type {
if constexpr (detail::is_virtual_ptr<ArgType>) {
return arg.vptr();
Expand All @@ -1222,7 +1228,7 @@ template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
template<typename MethodArgList, typename ArgType, typename... MoreArgTypes>
BOOST_FORCEINLINE auto
method<Name(Parameters...), ReturnType, Registry>::resolve_uni(
method<Name, auto(Parameters...)->ReturnType, Registry>::resolve_uni(
const ArgType& arg, const MoreArgTypes&... more_args) const
-> std::uintptr_t {

Expand Down Expand Up @@ -1251,7 +1257,7 @@ template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
template<typename MethodArgList, typename ArgType, typename... MoreArgTypes>
BOOST_FORCEINLINE auto
method<Name(Parameters...), ReturnType, Registry>::resolve_multi_first(
method<Name, auto(Parameters...)->ReturnType, Registry>::resolve_multi_first(
const ArgType& arg, const MoreArgTypes&... more_args) const
-> std::uintptr_t {

Expand Down Expand Up @@ -1292,7 +1298,7 @@ template<
std::size_t VirtualArg, typename MethodArgList, typename ArgType,
typename... MoreArgTypes>
BOOST_FORCEINLINE auto
method<Name(Parameters...), ReturnType, Registry>::resolve_multi_next(
method<Name, auto(Parameters...)->ReturnType, Registry>::resolve_multi_next(
vptr_type dispatch, const ArgType& arg,
const MoreArgTypes&... more_args) const -> std::uintptr_t {

Expand Down Expand Up @@ -1348,9 +1354,9 @@ auto error_type_id(const Class& obj) {

template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
BOOST_NORETURN auto
method<Name(Parameters...), ReturnType, Registry>::not_implemented_handler(
detail::remove_virtual<Parameters>... args) -> ReturnType {
BOOST_NORETURN auto method<Name, auto(Parameters...)->ReturnType, Registry>::
not_implemented_handler(detail::remove_virtual<Parameters>... args)
-> ReturnType {
if constexpr (Registry::template has_policy<policies::error_handler>) {
not_implemented_error error;
error.method = Registry::rtti::template static_type<method>();
Expand Down Expand Up @@ -1383,7 +1389,7 @@ template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
template<
auto Overrider, typename OverriderReturn, typename... OverriderParameters>
auto method<Name(Parameters...), ReturnType, Registry>::
auto method<Name, auto(Parameters...)->ReturnType, Registry>::
thunk<Overrider, OverriderReturn (*)(OverriderParameters...)>::fn(
detail::remove_virtual<Parameters>... arg) -> ReturnType {
using namespace detail;
Expand All @@ -1403,7 +1409,7 @@ auto method<Name(Parameters...), ReturnType, Registry>::
template<
typename Name, typename... Parameters, typename ReturnType, class Registry>
template<auto Function, typename FnReturnType>
method<Name(Parameters...), ReturnType, Registry>::override_impl<
method<Name, auto(Parameters...)->ReturnType, Registry>::override_impl<
Function, FnReturnType>::override_impl(FunctionPointer* p_next) {
using namespace detail;

Expand Down
45 changes: 38 additions & 7 deletions include/boost/openmethod/macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ struct enable_forwarder<
using type = ReturnType;
};

template<class...>
struct va_args;

template<class ReturnType, class Registry>
struct va_args<ReturnType, Registry> {
using return_type = ReturnType;
using registry = Registry;
};

template<class ReturnType>
struct va_args<ReturnType> {
using return_type = ReturnType;
using registry = macro_default_registry;
};

} // namespace boost::openmethod::detail

#define BOOST_OPENMETHOD_GENSYM BOOST_PP_CAT(openmethod_gensym_, __COUNTER__)
Expand All @@ -43,23 +58,39 @@ struct enable_forwarder<
typename ::boost::openmethod::detail::enable_forwarder< \
void, \
::boost::openmethod::method< \
BOOST_OPENMETHOD_NAME(NAME) ARGS, __VA_ARGS__>, \
BOOST_OPENMETHOD_NAME(NAME), \
::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \
ARGS, \
::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>, \
typename ::boost::openmethod::method< \
BOOST_OPENMETHOD_NAME(NAME) ARGS, __VA_ARGS__>, \
BOOST_OPENMETHOD_NAME(NAME), \
::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \
ARGS, \
::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>, \
ForwarderParameters...>::type \
BOOST_OPENMETHOD_GUIDE(NAME)(ForwarderParameters && ... args); \
template<typename... ForwarderParameters> \
inline auto NAME(ForwarderParameters&&... args) -> \
typename ::boost::openmethod::detail::enable_forwarder< \
void, \
::boost::openmethod::method< \
BOOST_OPENMETHOD_NAME(NAME) ARGS, __VA_ARGS__>, \
BOOST_OPENMETHOD_NAME(NAME), \
::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \
ARGS, \
::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>, \
typename ::boost::openmethod::method< \
BOOST_OPENMETHOD_NAME(NAME) ARGS, __VA_ARGS__>::return_type, \
BOOST_OPENMETHOD_NAME(NAME), \
::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \
ARGS, \
::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>:: \
return_type, \
ForwarderParameters...>::type { \
return ::boost::openmethod:: \
method<BOOST_OPENMETHOD_NAME(NAME) ARGS, __VA_ARGS__>::fn( \
std::forward<ForwarderParameters>(args)...); \
return ::boost::openmethod::method< \
BOOST_OPENMETHOD_NAME(NAME), \
::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \
ARGS, \
::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>:: \
fn(std::forward<ForwarderParameters>(args)...); \
}

#define BOOST_OPENMETHOD_DETAIL_LOCATE_METHOD(NAME, ARGS) \
Expand Down
8 changes: 4 additions & 4 deletions test/test_blackbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ BOOST_OPENMETHOD_CLASSES(Animal, Dog, Bulldog);

struct BOOST_OPENMETHOD_NAME(poke);
using poke =
method<BOOST_OPENMETHOD_NAME(poke)(virtual_<Animal&>), std::string>;
method<BOOST_OPENMETHOD_NAME(poke), auto(virtual_<Animal&>)->std::string>;

auto poke_dog(Dog&) -> std::string {
return "bark";
Expand Down Expand Up @@ -637,10 +637,10 @@ void fn(Class&...) {
BOOST_OPENMETHOD_CLASSES(Animal, Dog, Cat, test_registry);

BOOST_AUTO_TEST_CASE(initialize_report) {
using poke = method<poke_(virtual_<Animal&>), void, test_registry>;
using pet = method<pet_(virtual_<Animal&>), void, test_registry>;
using poke = method<poke_, auto(virtual_<Animal&>)->void, test_registry>;
using pet = method<pet_, auto(virtual_<Animal&>)->void, test_registry>;
using meet = method<
meet_(virtual_<Animal&>, virtual_<Animal&>), void, test_registry>;
meet_, auto(virtual_<Animal&>, virtual_<Animal&>)->void, test_registry>;

auto report = initialize<test_registry>().report;
BOOST_TEST(report.not_implemented == 3u);
Expand Down
4 changes: 2 additions & 2 deletions test/test_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,11 @@ struct M;

#define ADD_METHOD(CLASS) \
auto& BOOST_PP_CAT(m_, CLASS) = \
method<CLASS(virtual_<CLASS&>), void, test_registry>::fn;
method<CLASS, auto(virtual_<CLASS&>)->void, test_registry>::fn;

#define ADD_METHOD_N(CLASS, N) \
auto& BOOST_PP_CAT(BOOST_PP_CAT(m_, CLASS), N) = \
method<M<N>(virtual_<CLASS&>), void, test_registry>::fn;
method<M<N>, auto(virtual_<CLASS&>)->void, test_registry>::fn;

BOOST_AUTO_TEST_CASE(test_assign_slots_a_b1_c) {
using test_registry = test_registry_<__COUNTER__>;
Expand Down
3 changes: 2 additions & 1 deletion test/test_member_method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ struct Payroll {
private:
struct BOOST_OPENMETHOD_NAME(pay);
using pay_method = method<
BOOST_OPENMETHOD_NAME(pay)(Payroll*, virtual_<const Role&>), void>;
BOOST_OPENMETHOD_NAME(pay),
auto(Payroll*, virtual_<const Role&>)->void>;

void pay_employee(const Employee&) {
balance -= 2000;
Expand Down
29 changes: 16 additions & 13 deletions test/test_virtual_ptr_dispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(

BOOST_OPENMETHOD_REGISTER(
use_classes<Player, Warrior, Object, Axe, Bear, Registry>);
;
using poke = method<
BOOST_OPENMETHOD_NAME(poke)(virtual_ptr<Player, Registry>), std::string,
Registry>;
BOOST_OPENMETHOD_NAME(poke),
auto(virtual_ptr<Player, Registry>)->std::string, Registry>;
BOOST_OPENMETHOD_REGISTER(
typename poke::template override<
poke_bear<virtual_ptr<Player, Registry>>>);
Expand Down Expand Up @@ -275,17 +274,19 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
use_classes<Player, Warrior, Object, Axe, Bear, Registry>);

using poke = method<
BOOST_OPENMETHOD_NAME(poke)(virtual_ptr<Player, Registry>), std::string,
Registry>;
BOOST_OPENMETHOD_NAME(poke),
auto(virtual_ptr<Player, Registry>)->std::string, Registry>;
BOOST_OPENMETHOD_REGISTER(
typename poke::template override<
poke_bear<virtual_ptr<Player, Registry>>>);

using fight = method<
BOOST_OPENMETHOD_NAME(fight)(
BOOST_OPENMETHOD_NAME(fight),
auto(
virtual_ptr<Player, Registry>, virtual_ptr<Object, Registry>,
virtual_ptr<Player, Registry>),
std::string, Registry>;
virtual_ptr<Player, Registry>)
->std::string,
Registry>;
BOOST_OPENMETHOD_REGISTER(
typename fight::template override<fight_bear<
virtual_ptr<Player, Registry>, virtual_ptr<Object, Registry>,
Expand Down Expand Up @@ -316,19 +317,21 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
use_classes<Player, Warrior, Object, Axe, Bear, Registry>);

using poke = method<
BOOST_OPENMETHOD_NAME(poke)(shared_virtual_ptr<Player, Registry>),
std::string, Registry>;
BOOST_OPENMETHOD_NAME(poke),
auto(shared_virtual_ptr<Player, Registry>)->std::string, Registry>;

BOOST_OPENMETHOD_REGISTER(
typename poke::template override<
poke_bear<shared_virtual_ptr<Player, Registry>>>);

using fight = method<
BOOST_OPENMETHOD_NAME(fight)(
BOOST_OPENMETHOD_NAME(fight),
auto(
shared_virtual_ptr<Player, Registry>,
shared_virtual_ptr<Object, Registry>,
shared_virtual_ptr<Player, Registry>),
std::string, Registry>;
shared_virtual_ptr<Player, Registry>)
->std::string,
Registry>;

BOOST_OPENMETHOD_REGISTER(
typename fight::template override<fight_bear<
Expand Down
2 changes: 1 addition & 1 deletion test/test_virtual_ptr_value_semantics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ template<class Registry>
void init_test() {
BOOST_OPENMETHOD_REGISTER(use_classes<Animal, Cat, Dog, Registry>);
struct id;
(void)&method<id(virtual_ptr<Animal, Registry>), void, Registry>::fn;
(void)&method<id, auto(virtual_ptr<Animal, Registry>)->void, Registry>::fn;
boost::openmethod::initialize<Registry>();
}

Expand Down
Loading