7 Commits

Author SHA1 Message Date
Jean-Louis Leroy
f53122eae8 cmake: fix dlopen example 2025-12-22 23:16:02 -05:00
copilot-swe-agent[bot]
41eaec5bef Fix duplicate "because" typo in basics.adoc
Co-authored-by: jll63 <5083077+jll63@users.noreply.github.com>
2025-12-19 00:31:36 -05:00
Jean-Louis Leroy
5796d3c3ea add semicolons after BOOST_OPENMETHOD_CLASSES in examples 2025-12-18 17:04:17 -05:00
Jean-Louis Leroy
a6337d2f55 remove extra semicolons 2025-12-17 20:12:53 -05:00
Jean-Louis Leroy
02cffffe4f libraries.json: update description 2025-12-17 09:28:07 -05:00
Jean-Louis Leroy
ef48e48235 cmake: fix test and examples options 2025-12-14 14:08:04 -05:00
Jean-Louis Leroy
e0ead3bf71 doc: fix redirection page 2025-12-14 13:24:23 -05:00
18 changed files with 79 additions and 49 deletions

View File

@@ -37,10 +37,35 @@ set(__ignore__ ${CMAKE_C_COMPILER})
# Options
#
#-------------------------------------------------
option(BOOST_OPENMETHOD_BUILD_TESTS "Build boost::openmethod tests even if BUILD_TESTING is OFF" OFF)
option(BOOST_OPENMETHOD_BUILD_EXAMPLES "Build boost::openmethod examples" ${BOOST_OPENMETHOD_IS_ROOT})
option(BOOST_OPENMETHOD_MRDOCS_BUILD "Build the target for MrDocs: see mrdocs.yml" OFF)
option(BOOST_OPENMETHOD_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF)
option(
BOOST_OPENMETHOD_BUILD_TESTS
"Build boost::openmethod tests even if BUILD_TESTING is OFF"
${BOOST_OPENMETHOD_IS_ROOT})
if (BUILD_TESTING)
set(BOOST_OPENMETHOD_BUILD_TESTS ON)
endif ()
option(
BOOST_OPENMETHOD_BUILD_EXAMPLES
"Build boost::openmethod examples"
${BOOST_OPENMETHOD_IS_ROOT})
option(
BOOST_OPENMETHOD_MRDOCS_BUILD
"Build the target for MrDocs: see mrdocs.yml"
OFF)
option(
BOOST_OPENMETHOD_WARNINGS_AS_ERRORS
"Treat warnings as errors"
OFF)
if (BOOST_OPENMETHOD_BUILD_EXAMPLES AND NOT BOOST_OPENMETHOD_BUILD_TESTS)
message(
WARNING
"BOOST_OPENMETHOD_BUILD_EXAMPLES requires BOOST_OPENMETHOD_BUILD_TESTS. Examples will not be built.")
set(BOOST_OPENMETHOD_BUILD_EXAMPLES OFF)
endif()
# Check if environment variable BOOST_SRC_DIR is set
if (NOT DEFINED BOOST_SRC_DIR AND DEFINED ENV{BOOST_SRC_DIR})
@@ -77,9 +102,9 @@ endforeach ()
if (NOT BOOST_OPENMETHOD_MRDOCS_BUILD)
if (BUILD_TESTING OR BOOST_OPENMETHOD_BUILD_TESTS)
set(BOOST_OPENMETHOD_UNIT_TEST_LIBRARIES test)
endif()
if (BOOST_OPENMETHOD_BUILD_EXAMPLES)
set(BOOST_OPENMETHOD_EXAMPLE_LIBRARIES dll)
if (BOOST_OPENMETHOD_BUILD_EXAMPLES)
set(BOOST_OPENMETHOD_EXAMPLE_LIBRARIES dll)
endif()
endif()
endif()
# Complete dependency list
@@ -175,20 +200,15 @@ endif()
# Tests
#
#-------------------------------------------------
if (BUILD_TESTING OR BOOST_OPENMETHOD_BUILD_TESTS)
if (BOOST_OPENMETHOD_BUILD_TESTS)
enable_testing()
add_subdirectory(test)
if (BOOST_OPENMETHOD_IS_ROOT)
add_custom_target(all_with_tests ALL DEPENDS tests)
endif()
endif ()
#-------------------------------------------------
#
# Examples
#
#-------------------------------------------------
if (BOOST_OPENMETHOD_BUILD_EXAMPLES)
enable_testing()
add_subdirectory(doc/modules/ROOT/examples)
# Examples
if (BOOST_OPENMETHOD_BUILD_EXAMPLES)
add_subdirectory(doc/modules/ROOT/examples)
endif ()
endif ()

View File

@@ -14,5 +14,5 @@ BOOST_OPENMETHOD_OVERRIDE(
return 5000.0;
}
BOOST_OPENMETHOD_CLASSES(Employee)
BOOST_OPENMETHOD_CLASSES(Employee);
// end::content[]

View File

@@ -14,6 +14,6 @@ BOOST_OPENMETHOD_OVERRIDE(
return next(emp) + emp->sales * 0.05; // base + commission
}
BOOST_OPENMETHOD_CLASSES(Employee, Salesman)
BOOST_OPENMETHOD_CLASSES(Employee, Salesman);
// end::content[]

View File

@@ -12,5 +12,5 @@ BOOST_OPENMETHOD_DEFINE_OVERRIDER(
return 5000.0;
}
BOOST_OPENMETHOD_CLASSES(Employee)
BOOST_OPENMETHOD_CLASSES(Employee);
// end::content[]

View File

@@ -16,4 +16,4 @@ BOOST_OPENMETHOD_OVERRIDE(
}
// end::content[]
BOOST_OPENMETHOD_CLASSES(Employee, Salesman)
BOOST_OPENMETHOD_CLASSES(Employee, Salesman);

View File

@@ -7,5 +7,5 @@
#include "roles.hpp"
#include <boost/openmethod.hpp>
BOOST_OPENMETHOD_CLASSES(Employee)
BOOST_OPENMETHOD_CLASSES(Employee);
// end::content[]

View File

@@ -16,4 +16,4 @@ BOOST_OPENMETHOD_OVERRIDE(
}
// end::content[]
BOOST_OPENMETHOD_CLASSES(Employee, Salesman)
BOOST_OPENMETHOD_CLASSES(Employee, Salesman);

View File

@@ -7,5 +7,5 @@
#include "roles.hpp"
#include <boost/openmethod.hpp>
BOOST_OPENMETHOD_CLASSES(employees::Employee)
BOOST_OPENMETHOD_CLASSES(employees::Employee);
// end::content[]

View File

@@ -17,7 +17,7 @@ BOOST_OPENMETHOD_OVERRIDE(
emp->sales * 0.05; // base + commission
}
BOOST_OPENMETHOD_CLASSES(employees::Employee, Salesman)
BOOST_OPENMETHOD_CLASSES(employees::Employee, Salesman);
} // namespace sales
// end::content[]

View File

@@ -71,7 +71,7 @@ BOOST_OPENMETHOD_OVERRIDE(
}
// ...and let's not forget to register the classes
BOOST_OPENMETHOD_CLASSES(Employee, Salesman)
BOOST_OPENMETHOD_CLASSES(Employee, Salesman);
// end::overriders[]
// tag::main[]

View File

@@ -66,7 +66,7 @@ BOOST_OPENMETHOD_OVERRIDE(
}
// ...and let's not forget to register the classes
BOOST_OPENMETHOD_CLASSES(Employee, Salesman)
BOOST_OPENMETHOD_CLASSES(Employee, Salesman);
// end::overriders[]
// tag::main[]

View File

@@ -12,7 +12,10 @@ add_compile_definitions(BOOST_OPENMETHOD_ENABLE_RUNTIME_CHECKS)
add_library(boost_openmethod-shared SHARED extensions.cpp)
target_link_libraries(boost_openmethod-shared Boost::openmethod)
set_target_properties(boost_openmethod-shared PROPERTIES ENABLE_EXPORTS ON)
set_target_properties(boost_openmethod-shared PROPERTIES
ENABLE_EXPORTS ON
OUTPUT_NAME shared
)
add_executable(boost_openmethod-static static_main.cpp)
target_link_libraries(boost_openmethod-static Boost::openmethod Boost::dll boost_openmethod-shared)
@@ -36,7 +39,10 @@ add_library(boost_openmethod-indirect_shared SHARED indirect_extensions.cpp)
target_compile_definitions(
boost_openmethod-indirect_shared PUBLIC BOOST_OPENMETHOD_DEFAULT_REGISTRY=indirect_registry)
target_link_libraries(boost_openmethod-indirect_shared PRIVATE Boost::openmethod Boost::dll)
set_target_properties(boost_openmethod-indirect_shared PROPERTIES ENABLE_EXPORTS ON)
set_target_properties(boost_openmethod-indirect_shared PROPERTIES
ENABLE_EXPORTS ON
OUTPUT_NAME indirect_shared
)
add_executable(boost_openmethod-indirect indirect_main.cpp)
target_compile_definitions(

View File

@@ -6,7 +6,7 @@ An _open-method_ is a free-standing function that has one or more _virtual_
_parameters_. When it is called, it forwards to an _overrider_ selected from a
set by examining the dynamic types of the virtual parameters.
If this sounds like a virtual function, that's because because an open-method
If this sounds like a virtual function, that's because an open-method
with one virtual parameter is equivalent to a virtual function - with one big
difference: it exists outside of classes.

View File

@@ -127,10 +127,11 @@ class static_list {
friend auto operator==(const iterator& a, const iterator& b) -> bool {
return a.ptr == b.ptr;
};
}
friend auto operator!=(const iterator& a, const iterator& b) -> bool {
return a.ptr != b.ptr;
};
}
private:
T* ptr;
@@ -179,11 +180,12 @@ class static_list {
friend auto
operator==(const const_iterator& a, const const_iterator& b) -> bool {
return a.ptr == b.ptr;
};
}
friend auto
operator!=(const const_iterator& a, const const_iterator& b) -> bool {
return a.ptr != b.ptr;
};
}
private:
T* ptr;

View File

@@ -62,8 +62,6 @@ struct va_args<ReturnType> {
::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>
#define BOOST_OPENMETHOD(NAME, ARGS, ...) \
template<typename...> \
struct BOOST_OPENMETHOD_OVERRIDERS(NAME); \
struct BOOST_OPENMETHOD_ID(NAME); \
template<typename... ForwarderParameters> \
typename ::boost::openmethod::detail::enable_forwarder< \
@@ -72,14 +70,16 @@ struct va_args<ReturnType> {
ForwarderParameters...>::type \
BOOST_OPENMETHOD_GUIDE(NAME)(ForwarderParameters && ... args); \
template<typename... ForwarderParameters> \
inline auto NAME(ForwarderParameters&&... args) -> \
typename ::boost::openmethod::detail::enable_forwarder< \
inline auto NAME(ForwarderParameters&&... args) \
->typename ::boost::openmethod::detail::enable_forwarder< \
void, BOOST_OPENMETHOD_TYPE(NAME, ARGS, __VA_ARGS__), \
::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type, \
ForwarderParameters...>::type { \
return BOOST_OPENMETHOD_TYPE(NAME, ARGS, __VA_ARGS__)::fn( \
std::forward<ForwarderParameters>(args)...); \
}
} \
template<typename...> \
struct BOOST_OPENMETHOD_OVERRIDERS(NAME)
#define BOOST_OPENMETHOD_DETAIL_LOCATE_METHOD(NAME, ARGS) \
template<typename T> \
@@ -88,7 +88,7 @@ struct va_args<ReturnType> {
struct boost_openmethod_detail_locate_method_aux<void(A...)> { \
using type = \
decltype(BOOST_OPENMETHOD_GUIDE(NAME)(std::declval<A>()...)); \
};
}
#define BOOST_OPENMETHOD_DECLARE_OVERRIDER(NAME, ARGS, ...) \
template<typename...> \
@@ -102,13 +102,15 @@ struct va_args<ReturnType> {
static auto next(Args&&... args) -> decltype(auto); \
}; \
inline auto BOOST_OPENMETHOD_OVERRIDERS( \
NAME)<__VA_ARGS__ ARGS>::has_next() -> bool { \
NAME)<__VA_ARGS__ ARGS>::has_next() \
->bool { \
return boost_openmethod_detail_locate_method_aux< \
void ARGS>::type::has_next<fn>(); \
} \
template<typename... Args> \
inline auto BOOST_OPENMETHOD_OVERRIDERS(NAME)<__VA_ARGS__ ARGS>::next( \
Args&&... args) -> decltype(auto) { \
Args&&... args) \
->decltype(auto) { \
return boost_openmethod_detail_locate_method_aux< \
void ARGS>::type::next<fn>(std::forward<Args>(args)...); \
}
@@ -123,7 +125,7 @@ struct va_args<ReturnType> {
#define BOOST_OPENMETHOD_DEFINE_OVERRIDER(NAME, ARGS, ...) \
BOOST_OPENMETHOD_DETAIL_REGISTER_OVERRIDER(NAME, ARGS, __VA_ARGS__) \
auto BOOST_OPENMETHOD_OVERRIDER(NAME, ARGS, __VA_ARGS__)::fn ARGS \
-> boost::mp11::mp_back<boost::mp11::mp_list<__VA_ARGS__>>
->boost::mp11::mp_back<boost::mp11::mp_list<__VA_ARGS__>>
#define BOOST_OPENMETHOD_OVERRIDE(NAME, ARGS, ...) \
BOOST_OPENMETHOD_DECLARE_OVERRIDER(NAME, ARGS, __VA_ARGS__) \
@@ -133,9 +135,9 @@ struct va_args<ReturnType> {
BOOST_OPENMETHOD_DECLARE_OVERRIDER(NAME, ARGS, __VA_ARGS__) \
BOOST_OPENMETHOD_DETAIL_REGISTER_OVERRIDER(NAME, ARGS, __VA_ARGS__) \
inline auto BOOST_OPENMETHOD_OVERRIDER(NAME, ARGS, __VA_ARGS__)::fn ARGS \
-> boost::mp11::mp_back<boost::mp11::mp_list<__VA_ARGS__>>
->boost::mp11::mp_back<boost::mp11::mp_list<__VA_ARGS__>>
#define BOOST_OPENMETHOD_CLASSES(...) \
BOOST_OPENMETHOD_REGISTER(::boost::openmethod::use_classes<__VA_ARGS__>);
BOOST_OPENMETHOD_REGISTER(::boost::openmethod::use_classes<__VA_ARGS__>)
#endif

View File

@@ -183,7 +183,7 @@ struct vptr_vector : vptr {
} else {
detail::vptr_vector_vptrs<Registry>.clear();
}
};
}
};
};

View File

@@ -7,10 +7,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
<meta http-equiv="refresh" content="0; URL=doc/html/openmethod/index.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="doc/html/index.html">doc/html/index.html</a>
<a href="doc/html/openmethod/index.html">doc/html/openmethod/index.html</a>
</body>
</html>

View File

@@ -7,7 +7,7 @@
"maintainers": [
"Jean-Louis Leroy"
],
"description": "Open-methods for C++17 and above.",
"description": "Open-methods are free-standing functions that work like virtual functions: they select the best overrider from a set, depending on the dynamic type of their arguments. This makes it possible to add polymorphic operations to existing classes, without modifying them. They make patterns like Visitor unnecessary.",
"category": [
"Emulation", "Programming"
],