mirror of
https://github.com/boostorg/openmethod.git
synced 2026-01-19 16:32:12 +00:00
Compare commits
7 Commits
boost-1.90
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f53122eae8 | ||
|
|
41eaec5bef | ||
|
|
5796d3c3ea | ||
|
|
a6337d2f55 | ||
|
|
02cffffe4f | ||
|
|
ef48e48235 | ||
|
|
e0ead3bf71 |
@@ -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 ()
|
||||
|
||||
@@ -14,5 +14,5 @@ BOOST_OPENMETHOD_OVERRIDE(
|
||||
return 5000.0;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee)
|
||||
BOOST_OPENMETHOD_CLASSES(Employee);
|
||||
// end::content[]
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -12,5 +12,5 @@ BOOST_OPENMETHOD_DEFINE_OVERRIDER(
|
||||
return 5000.0;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee)
|
||||
BOOST_OPENMETHOD_CLASSES(Employee);
|
||||
// end::content[]
|
||||
|
||||
@@ -16,4 +16,4 @@ BOOST_OPENMETHOD_OVERRIDE(
|
||||
}
|
||||
// end::content[]
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee, Salesman)
|
||||
BOOST_OPENMETHOD_CLASSES(Employee, Salesman);
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
#include "roles.hpp"
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee)
|
||||
BOOST_OPENMETHOD_CLASSES(Employee);
|
||||
// end::content[]
|
||||
|
||||
@@ -16,4 +16,4 @@ BOOST_OPENMETHOD_OVERRIDE(
|
||||
}
|
||||
// end::content[]
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee, Salesman)
|
||||
BOOST_OPENMETHOD_CLASSES(Employee, Salesman);
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
#include "roles.hpp"
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(employees::Employee)
|
||||
BOOST_OPENMETHOD_CLASSES(employees::Employee);
|
||||
// end::content[]
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -183,7 +183,7 @@ struct vptr_vector : vptr {
|
||||
} else {
|
||||
detail::vptr_vector_vptrs<Registry>.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user