mirror of
https://github.com/boostorg/openmethod.git
synced 2026-01-19 16:32:12 +00:00
Compare commits
15 Commits
boost-1.90
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f53122eae8 | ||
|
|
41eaec5bef | ||
|
|
5796d3c3ea | ||
|
|
a6337d2f55 | ||
|
|
02cffffe4f | ||
|
|
ef48e48235 | ||
|
|
e0ead3bf71 | ||
|
|
764c0b9237 | ||
|
|
c64960d6c8 | ||
|
|
48e85546ce | ||
|
|
8933eb3b4f | ||
|
|
b8da0a1088 | ||
|
|
4d91aab7fd | ||
|
|
dac3cf7087 | ||
|
|
52fa71306e |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -123,5 +123,5 @@ jobs:
|
||||
path: doc/html
|
||||
|
||||
- name: Deploy to GitHub Pages (jll63)
|
||||
if: matrix.os == 'ubuntu-latest' && github.repository_owner == 'jll63' && github.ref_name == 'feature/doc'
|
||||
if: matrix.os == 'ubuntu-latest' && github.repository_owner == 'jll63'
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -21,11 +21,6 @@ ext:
|
||||
cpp-reference:
|
||||
config: doc/mrdocs.yml
|
||||
cpp-tagfiles:
|
||||
files:
|
||||
- file: ./doc/tagfiles/boost-openmethod-doxygen.tag.xml
|
||||
base_url: 'xref:reference:'
|
||||
- file: ./doc/tagfiles/boost-openmethod-macros-doxygen.tag.xml
|
||||
base_url: 'xref:reference:'
|
||||
using-namespaces:
|
||||
- boost::openmethod
|
||||
- boost::openmethod::policies
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Official repository: https://github.com/boostorg/openmethod
|
||||
# Official REPOSITORY: https://github.com/boostorg/openmethod
|
||||
#
|
||||
|
||||
set -e
|
||||
@@ -22,6 +22,52 @@ fi
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
if [ -z "${BOOST_SRC_DIR:-}" ]; then
|
||||
CANDIDATE=$( cd "$SCRIPT_DIR/../../.." 2>/dev/null && pwd )
|
||||
if [ -n "$CANDIDATE" ]; then
|
||||
BOOST_SRC_DIR_IS_VALID=ON
|
||||
for F in "CMakeLists.txt" "Jamroot" "boost-build.jam" "bootstrap.sh" "libs"; do
|
||||
if [ ! -e "$CANDIDATE/$F" ]; then
|
||||
BOOST_SRC_DIR_IS_VALID=OFF
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$BOOST_SRC_DIR_IS_VALID" = "ON" ]; then
|
||||
export BOOST_SRC_DIR="$CANDIDATE"
|
||||
echo "Using BOOST_SRC_DIR=$BOOST_SRC_DIR"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${BOOST_SRC_DIR:-}" ]; then
|
||||
if [ -n "${CIRCLE_REPOSITORY_URL:-}" ]; then
|
||||
if [[ "$CIRCLE_REPOSITORY_URL" =~ boostorg/boost(\.git)?$ ]]; then
|
||||
LIB="$(basename "$(dirname "$SCRIPT_DIR")")"
|
||||
REPOSITORY="boostorg/${LIB}"
|
||||
else
|
||||
ACCOUNT="${CIRCLE_REPOSITORY_URL#*:}"
|
||||
ACCOUNT="${ACCOUNT%%/*}"
|
||||
LIB=$(basename "$(git rev-parse --show-toplevel)")
|
||||
REPOSITORY="${ACCOUNT}/${LIB}"
|
||||
fi
|
||||
SHA=$(git -C "$BOOST_SRC_DIR/libs" ls-tree HEAD | grep -w openmethod | awk '{print $3}')
|
||||
elif [ -n "${GITHUB_REPOSITORY:-}" ]; then
|
||||
REPOSITORY="${GITHUB_REPOSITORY}"
|
||||
SHA="${GITHUB_SHA}"
|
||||
fi
|
||||
fi
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
if [ -n "${REPOSITORY}" ] && [ -n "${SHA}" ]; then
|
||||
base_url="https://github.com/${REPOSITORY}/blob/${SHA}"
|
||||
echo "Setting base-url to $base_url"
|
||||
cp mrdocs.yml mrdocs.yml.bak
|
||||
perl -i -pe 's{^\s*base-url:.*$}{base-url: '"$base_url/"'}' mrdocs.yml
|
||||
else
|
||||
echo "REPOSITORY or SHA not set; skipping base-url modification"
|
||||
fi
|
||||
|
||||
echo "Building documentation with Antora..."
|
||||
echo "Installing npm dependencies..."
|
||||
npm ci
|
||||
@@ -29,7 +75,7 @@ npm ci
|
||||
echo "Building docs in custom dir..."
|
||||
PATH="$(pwd)/node_modules/.bin:${PATH}"
|
||||
export PATH
|
||||
npx antora --clean --fetch "$PLAYBOOK" --stacktrace --log-level all
|
||||
npx antora --clean --fetch "$PLAYBOOK" --stacktrace # --log-level all
|
||||
|
||||
echo "Fixing links to non-mrdocs URIs..."
|
||||
|
||||
@@ -37,4 +83,15 @@ for f in $(find html -name '*.html'); do
|
||||
perl -i -pe 's{{{(.*?)}}}{<a href="../../../$1.html">$1</a>}g' "$f"
|
||||
done
|
||||
|
||||
if [ -n "${base_url:-}" ]; then
|
||||
if [ -f mrdocs.yml.bak ]; then
|
||||
mv -f mrdocs.yml.bak mrdocs.yml
|
||||
echo "Restored original mrdocs.yml"
|
||||
else
|
||||
echo "mrdocs.yml.bak not found; skipping restore"
|
||||
fi
|
||||
perl -i -pe "s[{{BASE_URL}}][$base_url]g" \
|
||||
html/openmethod/ref_headers.html html/openmethod/BOOST_OPENMETHOD*.html
|
||||
fi
|
||||
|
||||
echo "Done"
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
# Introduction
|
||||
|
||||
Open-methods are similar to virtual functions, but they are not required to be
|
||||
members of a class. By being both free and virtual, they provide a solution to
|
||||
the Expression Problem:
|
||||
|
||||
> Given a set of types, and a set of operations on these types, is it possible
|
||||
to add new operations on the existing types, and new types to the existing
|
||||
operations, without modifying existing code?
|
||||
|
||||
Open-methods also address the banana-gorilla-shared problem:
|
||||
|
||||
> The problem with object-oriented languages is they’ve got all this implicit
|
||||
environment that they carry around with them. You wanted a banana but what you
|
||||
got was a gorilla holding the banana and the entire shared. — Joe Armstrong,
|
||||
creator of Erlang progamming language
|
||||
|
||||
As a bonus, open-methods can take more than one argument into account when
|
||||
selecting the appropriate function to call - aka multiple dispatch. For that
|
||||
reason, open-methods are often called multi-methods, but that term is
|
||||
misleading, as it suggests that the feature is useful only when multiple
|
||||
dispatch is needed. In reality,
|
||||
https://openaccess.wgtn.ac.nz/articles/thesis/Multiple_Dispatch_in_Practice/16959112/1[it
|
||||
has been observed] that, in large systems written in languages that support
|
||||
multi-methods, most methods use single-dispatch. The real benefit is in the
|
||||
solution to the Expression Problem.
|
||||
|
||||
Open-methods were introduced by the Common Lisp Object System, and they are
|
||||
native to many languages: Clojure, Julia, Dylan, TADS, Cecil, Diesel, Nice, etc.
|
||||
Bjarne Stroustrup wanted open-methods in C++ almost from the beginning. In D&E
|
||||
he writes:
|
||||
|
||||
> I repeatedly considered a mechanism for a virtual function call based on more
|
||||
than one object, often called multi-methods. I rejected multi-methods with
|
||||
regret because I liked the idea, but couldn’t find an acceptable form under
|
||||
which to accept it. [...] Multi-methods is one of the interesting what-ifs of
|
||||
C++. Could I have designed and implemented them well enough at the time? Would
|
||||
their applications have been important enough to warrant the effort? What other
|
||||
work might have been left undone to provide the time to design and implement
|
||||
multi-methods? Since about 1985, I have always felt some twinge of regret for
|
||||
not providing multi-methods (Stroustrup, 1994, The Design and Evolution of
|
||||
C{plus}{plus}, 13.8).
|
||||
|
||||
Circa 2007, he and his PhD students Peter Pirkelbauer and Yuriy Solodkyy wrote a
|
||||
series of papers and a prototype implementation based on the EDG compiler.
|
||||
Unfortunately, open-methods never made it into the standard. Stroustrup bemoans,
|
||||
in a more recent paper:
|
||||
|
||||
> In retrospect, I don’t think that the object-oriented notation (e.g., x.f(y))
|
||||
should ever have been introduced. The traditional mathematical notation f(x,y)
|
||||
is sufficient. As a side benefit, the mathematical notation would naturally have
|
||||
given us multi-methods, thereby saving us from the visitor pattern workaround
|
||||
(Stroustrup, 2020, Thriving in a Crowded and ChangingWorld: C++ 2006–2020).
|
||||
|
||||
This library implements the features described in the
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2216.pdf[N2216 paper],
|
||||
with some extensions:
|
||||
|
||||
* a mechanism for calling the next most specialized overrider
|
||||
|
||||
* support for smart pointers
|
||||
|
||||
* customization points for RTTI, error handling, tracing, smart pointers...
|
||||
|
||||
Multiple and virtual inheritance are supported, with the exception of repeated
|
||||
inheritance.
|
||||
@@ -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(
|
||||
|
||||
@@ -41,7 +41,7 @@ int main() {
|
||||
// end::unload[]
|
||||
std::cout << "Before loading the shared library.\n";
|
||||
|
||||
initialize();
|
||||
boost::openmethod::initialize();
|
||||
|
||||
std::cout << "cow meets wolf -> "
|
||||
<< meet(*std::make_unique<Cow>(), *std::make_unique<Wolf>())
|
||||
@@ -60,7 +60,7 @@ int main() {
|
||||
boost::dll::shared_library lib(
|
||||
boost::dll::program_location().parent_path() / LIBRARY_NAME,
|
||||
boost::dll::load_mode::rtld_now);
|
||||
initialize();
|
||||
boost::openmethod::initialize();
|
||||
|
||||
std::cout << "cow meets wolf -> "
|
||||
<< meet(*std::make_unique<Cow>(), *std::make_unique<Wolf>())
|
||||
@@ -83,7 +83,7 @@ int main() {
|
||||
std::cout << "\nAfter unloading the shared library.\n";
|
||||
|
||||
lib.unload();
|
||||
initialize();
|
||||
boost::openmethod::initialize();
|
||||
|
||||
std::cout << "cow meets wolf -> "
|
||||
<< meet(*std::make_unique<Cow>(), *std::make_unique<Wolf>())
|
||||
|
||||
@@ -37,7 +37,7 @@ auto main() -> int {
|
||||
using namespace boost::openmethod::aliases;
|
||||
|
||||
std::cout << "Before loading the shared library.\n";
|
||||
initialize();
|
||||
boost::openmethod::initialize();
|
||||
|
||||
auto gracie = make_unique_virtual<Cow>();
|
||||
auto willy = make_unique_virtual<Wolf>();
|
||||
@@ -53,7 +53,7 @@ auto main() -> int {
|
||||
boost::dll::program_location().parent_path() / LIBRARY_NAME,
|
||||
boost::dll::load_mode::rtld_now);
|
||||
|
||||
initialize();
|
||||
boost::openmethod::initialize();
|
||||
|
||||
std::cout << "cow meets wolf -> " << meet(*gracie, *willy) << "\n"; // run
|
||||
std::cout << "wolf meets cow -> " << meet(*willy, *gracie) << "\n"; // hunt
|
||||
|
||||
@@ -30,7 +30,7 @@ auto make_tiger() -> Animal*;
|
||||
}
|
||||
|
||||
auto main() -> int {
|
||||
initialize();
|
||||
boost::openmethod::initialize();
|
||||
|
||||
std::unique_ptr<Animal> gracie(new Cow());
|
||||
std::unique_ptr<Animal> willy(new Wolf());
|
||||
|
||||
@@ -22,7 +22,7 @@ struct Node {
|
||||
|
||||
struct Variable : Node {
|
||||
Variable(int value) : v(value) {
|
||||
vptr = boost::openmethod::default_registry::static_vptr<Variable>;
|
||||
vptr = registry::static_vptr<Variable>;
|
||||
}
|
||||
|
||||
int v;
|
||||
@@ -30,7 +30,7 @@ struct Variable : Node {
|
||||
|
||||
struct Plus : Node {
|
||||
Plus(const Node& left, const Node& right) : left(left), right(right) {
|
||||
vptr = boost::openmethod::default_registry::static_vptr<Plus>;
|
||||
vptr = registry::static_vptr<Plus>;
|
||||
}
|
||||
|
||||
const Node& left;
|
||||
@@ -39,7 +39,7 @@ struct Plus : Node {
|
||||
|
||||
struct Times : Node {
|
||||
Times(const Node& left, const Node& right) : left(left), right(right) {
|
||||
vptr = boost::openmethod::default_registry::static_vptr<Times>;
|
||||
vptr = registry::static_vptr<Times>;
|
||||
}
|
||||
|
||||
const Node& left;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
* xref:introduction.adoc[Introduction]
|
||||
* xref:basics.adoc[Open-Methods 101]
|
||||
* xref:performance.adoc[Performance]
|
||||
* xref:smart_pointers.adoc[Smart Pointers]
|
||||
* xref:headers.adoc[Headers]
|
||||
* xref:namespaces.adoc[Namespaces]
|
||||
* xref:friendship.adoc[Friendship]
|
||||
* xref:multiple_dispatch.adoc[Multiple Dispatch]
|
||||
* xref:motivation.adoc[Motivation]
|
||||
* Basic Features
|
||||
** xref:basics.adoc[Methods and Overriders]
|
||||
** xref:performance.adoc[Performance]
|
||||
** xref:smart_pointers.adoc[Smart Pointers]
|
||||
** xref:headers.adoc[Header and Implementation Files]
|
||||
** xref:namespaces.adoc[Namespaces]
|
||||
** xref:friends.adoc[Friends]
|
||||
** xref:multiple_dispatch.adoc[Multiple Dispatch]
|
||||
* Advanced Features
|
||||
** xref:core_api.adoc[Core API]
|
||||
** xref:registries_and_policies.adoc[Registries and Policies]
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
= BOOST_OPENMETHOD
|
||||
# BOOST_OPENMETHOD
|
||||
|
||||
### Synopsis
|
||||
## Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD(ID, (PARAMETERS...), RETURN_TYPE [, REGISTRY]);
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
Declares a method, called `ID`, with the given `PARAMETERS` and `RETURN_TYPE`,
|
||||
and adds it to `REGISTRY`.
|
||||
@@ -58,7 +58,7 @@ NOTE: The default value for `REGISTRY` is the value of
|
||||
`BOOST_OPENMETHOD_DEFAULT_REGISTRY` at the point `<boost/openmethod/core.hpp>` is
|
||||
included. Changing the value of this symbol has no effect after that point.
|
||||
|
||||
### Implementation Notes
|
||||
## Implementation Notes
|
||||
|
||||
The macro creates several additional constructs:
|
||||
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
# BOOST_OPENMETHOD_CLASSES
|
||||
|
||||
[#BOOST_OPENMETHOD_CLASSES]
|
||||
## Synopsis
|
||||
|
||||
## BOOST_OPENMETHOD_CLASSES
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_CLASSES(CLASSES...[, REGISTRY]);
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
Registers `CLASSES` in REGISTRY.
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
# BOOST_OPENMETHOD_DECLARE_OVERRIDER
|
||||
|
||||
## BOOST_OPENMETHOD_DECLARE_OVERRIDER
|
||||
## Synopsis
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
#define BOOST_OPENMETHOD_DECLARE_OVERRIDER(NAME, (PARAMETERS...), RETURN_TYPE)
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
Declares an overrider for a method, but does not start its definition. This
|
||||
macro can be used in header files.
|
||||
@@ -33,7 +32,7 @@ Each `virtual_<T>` in the method's parameter list must have a corresponding `U`
|
||||
parameter in the same position in the overrider's parameter list, such that `U`
|
||||
is the same as `T`, or has `T` as an accessible unambiguous base.
|
||||
|
||||
### Implementation Notes
|
||||
## Implementation Notes
|
||||
|
||||
The macro creates additional entities in the current scope.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
= xref:macros.adoc[Macro] BOOST_OPENMETHOD_DEFAULT_REGISTRY
|
||||
# BOOST_OPENMETHOD_DEFAULT_REGISTRY
|
||||
|
||||
Default value for Registry
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
## BOOST_OPENMETHOD_DEFINE_OVERRIDER
|
||||
# BOOST_OPENMETHOD_DEFINE_OVERRIDER
|
||||
|
||||
### Synopsis
|
||||
## Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
#define BOOST_OPENMETHOD_DEFINE_OVERRIDER(ID, (PARAMETERS...), RETURN_TYPE)
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
Defines the body of an overrider declared with
|
||||
xref:BOOST_OPENMETHOD_DECLARE_OVERRIDER.adoc[BOOST_OPENMETHOD_DECLARE_OVERRIDER].
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
|
||||
## BOOST_OPENMETHOD_ENABLE_RUNTIME_CHECKS
|
||||
# BOOST_OPENMETHOD_ENABLE_RUNTIME_CHECKS
|
||||
|
||||
Enables runtime checks in cpp:default_registry[].
|
||||
|
||||
### Synopsis
|
||||
## Synopsis
|
||||
|
||||
May be defined by a program before including
|
||||
`<boost/openmethod/default_registry.hpp>` to enable runtime checks.
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
See cpp:default_registry[] for details.
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
|
||||
[#BOOST_OPENMETHOD_ID]
|
||||
# BOOST_OPENMETHOD_ID
|
||||
|
||||
## BOOST_OPENMETHOD_ID
|
||||
## Synopsis
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
#define BOOST_OPENMETHOD_ID(ID) /* unspecified */
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
Generates a long, obfuscated name from a short name. All the other names
|
||||
generated by macros are based on this name.
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
# BOOST_OPENMETHOD_INLINE_OVERRIDE
|
||||
|
||||
[#BOOST_OPENMETHOD_INLINE_OVERRIDE]
|
||||
## Synopsis
|
||||
|
||||
## BOOST_OPENMETHOD_INLINE_OVERRIDE
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_INLINE_OVERRIDE(ID, (PARAMETERS...), RETURN_TYPE) {
|
||||
@@ -13,7 +10,7 @@ BOOST_OPENMETHOD_INLINE_OVERRIDE(ID, (PARAMETERS...), RETURN_TYPE) {
|
||||
}
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
`BOOST_OPENMETHOD_INLINE_OVERRIDE` performs the same function as
|
||||
xref:BOOST_OPENMETHOD_OVERRIDE.adoc[BOOST_OPENMETHOD_OVERRIDE], except that the
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
|
||||
[#BOOST_OPENMETHOD_OVERRIDE]
|
||||
# BOOST_OPENMETHOD_OVERRIDE
|
||||
|
||||
## BOOST_OPENMETHOD_OVERRIDE
|
||||
## Synopsis
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_OVERRIDE(ID, (PARAMETERS...), RETURN_TYPE) {
|
||||
@@ -13,7 +11,7 @@ BOOST_OPENMETHOD_OVERRIDE(ID, (PARAMETERS...), RETURN_TYPE) {
|
||||
}
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
`BOOST_OPENMETHOD_OVERRIDE` adds an overrider to a method.
|
||||
|
||||
@@ -48,7 +46,7 @@ and terminates the program.
|
||||
|
||||
* `has_next()`: returns `true` if the next most specialized overrider exists.
|
||||
|
||||
### Implementation Notes
|
||||
## Implementation Notes
|
||||
|
||||
The macro creates additional entities in the current scope.
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
## BOOST_OPENMETHOD_OVERRIDER
|
||||
# BOOST_OPENMETHOD_OVERRIDER
|
||||
|
||||
### Synopsis
|
||||
## Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
#define BOOST_OPENMETHOD_OVERRIDER(ID, (PARAMETERS...), RETURN_TYPE)
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
Expands to the specialization of the class template that contains the overrider
|
||||
for with the given name, parameter list and return type.
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
|
||||
## BOOST_OPENMETHOD_OVERRIDERS
|
||||
# BOOST_OPENMETHOD_OVERRIDERS
|
||||
|
||||
### Synopsis
|
||||
## Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
#define BOOST_OPENMETHOD_OVERRIDERS(ID) \
|
||||
BOOST_PP_CAT(BOOST_OPENMETHOD_ID(ID), _overriders)
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
`BOOST_OPENMETHOD_OVERRIDERS` expands to the name of the class template that
|
||||
contains the overriders for all the methods with a given name.
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
|
||||
[#BOOST_OPENMETHOD_REGISTER]
|
||||
# BOOST_OPENMETHOD_REGISTER
|
||||
|
||||
## BOOST_OPENMETHOD_REGISTER
|
||||
## Synopsis
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_REGISTER(TYPE);
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
Creates a registrar for `TYPE`, i.e. a static `TYPE` object with a unique
|
||||
generated name. At static initialization time, the object adds itself to a list:
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
# BOOST_OPENMETHOD_TYPE
|
||||
|
||||
= BOOST_OPENMETHOD_TYPE
|
||||
## Synopsis
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
Defined in link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>].
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_TYPE(ID, (PARAMETERS...), RETURN_TYPE [, REGISTRY]);
|
||||
```
|
||||
|
||||
### Description
|
||||
## Description
|
||||
|
||||
Expands to the core cpp:method[`method`] specialization created by
|
||||
xref:BOOST_OPENMETHOD.adoc[BOOST_OPENMETHOD] called with the same arguments.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
:exampledir: ../example
|
||||
|
||||
## Open-Methods 101
|
||||
[#basics]
|
||||
|
||||
An _open-method_ is a free-standing function that takes one or more _virtual_
|
||||
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.
|
||||
|
||||
@@ -22,7 +22,7 @@ BOOST_OPENMETHOD(
|
||||
postfix, (virtual_ptr<const Node> node, std::ostream& os), void);
|
||||
```
|
||||
|
||||
This method is called `postfix`. It takes one virtual parameter, `node`, and one
|
||||
`postfix` is the method's name. It takes one virtual parameter, `node`, and one
|
||||
non-virtual parameter, `os`. It returns `void`. The macro generates the
|
||||
following function:
|
||||
|
||||
@@ -61,15 +61,15 @@ This one calls `postfix` recursively to print the left and right
|
||||
sub-expressions. Note that we call the method just like an ordinary function.
|
||||
|
||||
`postfix` expects a `virtual_ptr<const Node>`, and we are passing it a _plain_
|
||||
_reference_ to a `Plus` object. This works because `virtual_ptr` has conversion
|
||||
constructors from plain references or pointers to an object, or from other
|
||||
`virtual_ptr`{empty}s to compatible classes.
|
||||
_reference_ to a `Node` object. This works because `virtual_ptr` has conversion
|
||||
constructors from plain references or pointers to objects, or from other
|
||||
`virtual_ptr`{empty}s.
|
||||
|
||||
There are two more things we need to do.
|
||||
|
||||
OpenMethod is a library, not a compiler. It needs to be made aware of all the
|
||||
OpenMethod is a library, not a compiler. It needs to be informed of all the
|
||||
classes that may be used as virtual parameters, and in method calls, and their
|
||||
inheritance relationships. We do this with the
|
||||
inheritance relationships. We provide that information with the
|
||||
xref:BOOST_OPENMETHOD_CLASSES.adoc[BOOST_OPENMETHOD_CLASSES] macro:
|
||||
|
||||
|
||||
@@ -84,8 +84,8 @@ direct base of a class must appear together with it in at least one call to
|
||||
inheritance lattice.
|
||||
|
||||
The constructs used in this example require the classes to be polymorphic, in
|
||||
the standard C++ sense, i.e. have at least one virtual function. The library can
|
||||
also be used with non-polymorphic classes, with some restrictions.
|
||||
the standard C++ sense, i.e. they must have at least one virtual function. The
|
||||
library can also be used with non-polymorphic classes, with some restrictions.
|
||||
|
||||
Finally, we need to call `boost::openmethod::initialize()` before the first call
|
||||
to an open-method. This builds the dispatch tables used during method calls. It
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
:example: ../examples/core_api/1
|
||||
|
||||
## Core API
|
||||
[#core_api]
|
||||
|
||||
OpenMethod provides a macro-free interface: the core API. This is useful in
|
||||
certain situations, for example when combining open-methods and templates.
|
||||
@@ -25,8 +25,8 @@ method, `prefix`, which writes expressions in prefix notation. It would have the
|
||||
same signature. Without the identifier argument, `prefix` and `postfix` would be the
|
||||
same method.
|
||||
|
||||
The exact name of the identifier class does not matter, as long as it is unique enough.
|
||||
The class needs not be defined, only declared.
|
||||
The exact name of the identifier class does not matter. The class needs not be
|
||||
defined, only declared.
|
||||
|
||||
Inventing identifier class names can get tedious, so OpenMethod provides a macro
|
||||
for that: xref:BOOST_OPENMETHOD_ID.adoc[BOOST_OPENMETHOD_ID]. Let's use it:
|
||||
@@ -58,9 +58,12 @@ functions passed as template arguments to the method.
|
||||
include::{example}/core_api.cpp[tag=variable_overrider]
|
||||
----
|
||||
|
||||
Once again we find ourselves inventing a name that will not be used again. In
|
||||
C++26, we will probably have the Python-like `_` for this. In the meantime, we
|
||||
can use a small macro:
|
||||
Once again we find ourselves inventing a name for a single use. In C++26, we
|
||||
will probably have the Python-like `_` for this.
|
||||
|
||||
We can also use a small macro:
|
||||
xref:BOOST_OPENMETHOD_REGISTER.adoc[BOOST_OPENMETHOD_REGISTER]. It takes a
|
||||
class, and instantiates a static object with an obfuscated name:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
@@ -91,7 +94,7 @@ The primary purpose of the core API is to make open-methods inter-operate with
|
||||
templates.
|
||||
|
||||
`Plus` and `Times` are obvious candidates for templatization. They only differ
|
||||
by the operation they perform, and we already have templates fore that in the
|
||||
by the operation they perform, and we already have templates for that in the
|
||||
standard library:
|
||||
|
||||
[source,c++]
|
||||
@@ -118,8 +121,8 @@ include::{example}/core_api.cpp[tag=postfix_binary]
|
||||
----
|
||||
|
||||
Macro xref:BOOST_OPENMETHOD_TYPE.adoc[BOOST_OPENMETHOD_TYPE] takes the same
|
||||
parameters as `BOOST_OPENMETHOD`, and expands to the core method type. That is
|
||||
how we access its nested `overrider` class template:
|
||||
parameters as `BOOST_OPENMETHOD`, and expands to the core cpp:method[method]
|
||||
instance. That is how we access its nested `overrider` class template:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
:example: ../examples/custom_rtti
|
||||
|
||||
## Custom RTTI
|
||||
[#custom_rtti]
|
||||
|
||||
The original motivation for the policy mechanism is to make it possible to
|
||||
interface OpenMethod with custom RTTI systems.
|
||||
@@ -106,25 +106,26 @@ still work.
|
||||
The policy is quite minimal. It does not support virtual inheritance, because it
|
||||
does not provide a `dynamic_cast_ref` function. It would not produce good error
|
||||
or trace messages, because it does not provide a `type_name` function. Instead,
|
||||
it relies on the `type_name` inherited from `rtti::default`. It renders types as
|
||||
adorned integers, e.g. "type_id(2)". All non-"polymorphic" types would be
|
||||
rendered the same way, as "type_id(0)".
|
||||
it relies on the `type_name` inherited from cpp:rtti::defaults[]. It
|
||||
renders types as adorned integers, e.g. "type_id(2)". All non-"polymorphic"
|
||||
types would be rendered the same way, as "type_id(0)".
|
||||
|
||||
`rtti::default` also provides a default implementation for `type_index`, which
|
||||
simply returns its argument.
|
||||
cpp:rtti::defaults[] also provides a default implementation for `type_index`,
|
||||
which simply returns its argument.
|
||||
|
||||
Now we need a policy to get a v-table pointer from an object. Our RTTI system
|
||||
has an interesting property: its type ids are monotonically allocated in a
|
||||
small, dense range. It means that we can use them as straight indexes in a
|
||||
vector. `vptr_vector` is perfect for that. So here is our registry:
|
||||
small, dense range. It means that we can use them as indexes in a vector.
|
||||
`vptr_vector` is perfect for that. So here is our registry:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{example}/1/custom_rtti.cpp[tag=registry]
|
||||
----
|
||||
|
||||
Defining macro `BOOST_OPENMETHOD_DEFAULT_REGISTRY` sets the default registry
|
||||
used by all library components that need one.
|
||||
Defining macro
|
||||
xref:BOOST_OPENMETHOD_DEFAULT_REGISTRY.adoc[BOOST_OPENMETHOD_DEFAULT_REGISTRY]
|
||||
sets the default registry used by all library components that need one.
|
||||
|
||||
Next, we include the main header.
|
||||
Because `BOOST_OPENMETHOD_DEFAULT_REGISTRY` is defined, its value is used
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
|
||||
## Error Handling
|
||||
[#error_handling]
|
||||
|
||||
Errors can occur during `initialize`, or during method dispatch, if the
|
||||
method's registry contains the `runtime_checks` policy. If the registry
|
||||
contains an `error_handler` policy, its `error_handler::error` member
|
||||
function is called with a variant containing an error object, before terminating
|
||||
the program with a call to `abort`. `default_registry` contains such a
|
||||
policy: `default_error_handler`. It wraps the error object in a variant, and
|
||||
calls a handler via a `std::function`. By default, it prints a short description
|
||||
of the error to `stderr`, but this can be changed, for example, to throw an
|
||||
exception:
|
||||
Errors can occur during `initialize`, or during method dispatch, if the method's
|
||||
registry contains the `runtime_checks` policy. If the registry contains an
|
||||
`error_handler` policy, its `error_handler::error` member function is called
|
||||
with an error object, before terminating the program with a call to `abort`.
|
||||
`default_registry` contains such a policy: `default_error_handler`. It wraps the
|
||||
error object in a variant, and calls a handler via a `std::function`,
|
||||
initialized to a function that prints a short description of the error to
|
||||
`stderr`. The function can be changed, for example, to throw an exception:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
@@ -43,11 +42,14 @@ spin
|
||||
|
||||
Stock policy `throw_error_handler` does this for all the error types:
|
||||
|
||||
```c++ namespace boost::openmethod::policies {
|
||||
```c++
|
||||
namespace boost::openmethod::policies {
|
||||
|
||||
struct throw_error_handler : error_handler { template<class Error>
|
||||
[[noreturn]] static auto error(const Error& error) -> void { throw
|
||||
error; }
|
||||
struct throw_error_handler : error_handler {
|
||||
template<class Error>
|
||||
[[noreturn]] static auto error(const Error& error) -> void {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost::openmethod::policies
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
:example: ../examples/rolex
|
||||
|
||||
## Friendship
|
||||
[#friendship]
|
||||
|
||||
Note;; This section uses overrider containers, described in the
|
||||
xref:headers.adoc[Headers] section.
|
||||
|
||||
`friend` is a controversial feature. OpenMethod aims to interact well with
|
||||
all of C++, as much as feasible for a library, and leave the user the choice of
|
||||
using `friend`, or not.
|
||||
`friend` is a controversial feature. OpenMethod aims to interact well with all
|
||||
of C++, as much as feasible for a library, and leaves the choice of using
|
||||
`friend`, or not, to the user.
|
||||
|
||||
Let's consider yet another variation of the `pay` example. This time, we want to
|
||||
update a `balance` variable in a `Payroll` class, when an employee is paid. Thus
|
||||
@@ -1,6 +1,6 @@
|
||||
:example: ../examples/rolex
|
||||
|
||||
## Headers
|
||||
[#Headers]
|
||||
|
||||
Typically, `BOOST_OPENMETHOD` is used in headers, while
|
||||
`BOOST_OPENMETHOD_CLASSES` and `BOOST_OPENMETHOD_OVERRIDE` are used in
|
||||
@@ -8,8 +8,8 @@ implementation files.
|
||||
|
||||
Let's use a payroll application as an example. We have two roles: `Employee` and
|
||||
`Salesman`, and a `pay` method that computes the monthly pay of an employee. We
|
||||
want to override and call `pay` from from multiple translation units, so we put
|
||||
it in a header:
|
||||
want to override and call `pay` from multiple translation units, so we put it in
|
||||
a header:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
:example: ../examples
|
||||
|
||||
[#boost-openmethod]
|
||||
= Boost.OpenMethod
|
||||
|
||||
Boost.OpenMethod implements open-(multi-)methods in C++17 and above.
|
||||
@@ -72,18 +73,18 @@ manager.
|
||||
|
||||
Thanks to the members of the Boost community who posted a formal review:
|
||||
|
||||
* Joaquin M López Muñoz
|
||||
* Andrzej Krzemienski
|
||||
|
||||
* Christian Mazakas
|
||||
|
||||
* Joaquin M López Muñoz
|
||||
|
||||
* Klemens Morgenstern
|
||||
|
||||
* Ruben Perez
|
||||
|
||||
* Yannick Le Goc
|
||||
|
||||
* Klemens Morgenstern
|
||||
|
||||
* Andrzej Krzemienski
|
||||
|
||||
Also thanks to Steven Watanabe for his cogent feedback and advice, and all
|
||||
the people who posted remarks and suggestions.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
## Introduction
|
||||
[#motivation]
|
||||
|
||||
Consider a class hierarchy that represents and evaluates arithmetic
|
||||
expressions:
|
||||
@@ -84,9 +84,12 @@ Julia, Cecil, TADS, and others, have multi-methods.
|
||||
|
||||
But wait! What do multi-methods have to do with our problem? There is no
|
||||
multiple dispatch going on here! The thing is, "multi-methods" is not a very
|
||||
good name. Even in languages that support them, multi-methods tend to use single
|
||||
dispatch only. For that reason, we prefer the term "open-methods", to emphasize
|
||||
the important feature: openness. Multiple dispatch is just a bonus.
|
||||
good name. Even in languages that support them, many "multi-methods" have a
|
||||
single virtual parameter - they are uni-methods
|
||||
footnote:[https://figshare.com/articles/thesis/Multiple_Dispatch_in_Practice/16959112[Multiple
|
||||
dispatch in practice], Radu Muschevici, 2008.]! For that reason, we prefer the
|
||||
term "open-methods", to emphasize the important feature: openness. Multiple
|
||||
dispatch is just a bonus.
|
||||
|
||||
An open-method is like a virtual function, but it exists outside of a class, as
|
||||
a free-standing function. We can create all the open-methods we need, without
|
||||
@@ -1,12 +1,12 @@
|
||||
:example: ../examples
|
||||
|
||||
## Multiple Dispatch
|
||||
[#multiple_dispatch]
|
||||
|
||||
A method can have more than one virtual parameter. This is often called
|
||||
"multi-methods" or "multiple dispatch". All the virtual parameters participate
|
||||
"multi-method" or "multiple dispatch". All the virtual parameters participate
|
||||
equally in overrider selection, following the same rules as those governing
|
||||
overload resolution - except that the selection happens at runtime, and takes
|
||||
into account the argument's dynamic types.
|
||||
into account the arguments dynamic types.
|
||||
|
||||
Multiple dispatch is occasionally useful. When it is needed, it can be difficult
|
||||
to implement correctly and efficiently by hand. For example, given the following
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
:example: ../examples/rolex
|
||||
|
||||
## Namespaces
|
||||
[#namespaces]
|
||||
|
||||
Note;; This section uses overrider containers, described in the
|
||||
xref:headers.adoc[Headers] section.
|
||||
xref:headers.adoc[Headers and Implementation Files] section.
|
||||
|
||||
xref:BOOST_OPENMETHOD.adoc[BOOST_OPENMETHOD] defines a method in the current
|
||||
namespace. xref:BOOST_OPENMETHOD_OVERRIDE.adoc[BOOST_OPENMETHOD_OVERRIDE] works
|
||||
@@ -13,9 +13,9 @@ called with the same arguments as the overrider, possibly located via argument
|
||||
dependant lookup.
|
||||
|
||||
Overrider containers are added to the current namespace. It follows that the
|
||||
same method can have overriders in several different container, in different
|
||||
namespaces. This must be taken into account when calling an overrider
|
||||
explicitly. Let's put Employee and Salesman in their own namespaces:
|
||||
same method can have overriders in multiple containers, in different namespaces.
|
||||
This must be taken into account when calling an overrider explicitly. Let's put
|
||||
Employee and Salesman in their own namespaces:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
## Performance
|
||||
[#performance]
|
||||
|
||||
Open-methods can be as fast as ordinary virtual member functions when
|
||||
compiled with optimization.
|
||||
@@ -67,7 +67,7 @@ than calling the equivalent virtual function, with an empty body and no other
|
||||
arguments. In most real programs, the overhead would be unnoticeable.
|
||||
|
||||
*However*, `call_via_ref` does two things: it constructs a `virtual_ptr<Node>`
|
||||
from a `const Node&`; and then it calls the method.
|
||||
from a `const Node&`, then it calls the method.
|
||||
|
||||
The construction of the `virtual_ptr` is the costly part. It performs a lookup
|
||||
in a perfect hash table, indexed by pointers to `std::type_info`, to find the
|
||||
@@ -96,9 +96,10 @@ jmp rax # TAILCALL
|
||||
`virtual_ptr` arguments are passed through the method call, to the overrider,
|
||||
which can use them to make further method calls.
|
||||
|
||||
A program designed with open-methods in mind should use `virtual_ptr`{empty}s
|
||||
in place of plain pointers or references, as much as possible. Here is the Node
|
||||
example, rewritten to use `virtual_ptr`{empty}s thoughout:
|
||||
Code that incorporates open-methods in its design should use
|
||||
`virtual_ptr`{empty}s in place of plain pointers or references, as much as
|
||||
possible. Here is the Node example, rewritten to use `virtual_ptr`{empty}s
|
||||
thoughout:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
|
||||
@@ -7,21 +7,64 @@
|
||||
|
||||
The following headers are sufficient for most basic uses of the library.
|
||||
|
||||
* xref:#main[`boost/openmethod.hpp`] to define open-methods and overriders using
|
||||
* xref:#openmethod[`<boost/openmethod.hpp>`] to define open-methods and overriders using
|
||||
convenient macros.
|
||||
|
||||
* xref:#initialize[`boost/openmethod/initialize.hpp`] to initialize the library.
|
||||
* xref:#initialize[`<boost/openmethod/initialize.hpp>`] to initialize the library.
|
||||
Typically only included in the translation unit containing `main`.
|
||||
|
||||
The following headers make it possible to use standard smart pointers in virtual
|
||||
parameters:
|
||||
|
||||
* xref:#std_shared_ptr[`boost/openmethod/interop/std_shared_ptr.hpp`] to use
|
||||
* xref:#std_shared_ptr[`<boost/openmethod/interop/std_shared_ptr.hpp>`] to use
|
||||
`std::shared_ptr` in virtual parameters.
|
||||
|
||||
* xref:#std_unique_ptr[`boost/openmethod/interop/std_unique_ptr.hpp`] to use
|
||||
* xref:#std_unique_ptr[`<boost/openmethod/interop/std_unique_ptr.hpp>`] to use
|
||||
`std::unique_ptr` in virtual parameters.
|
||||
|
||||
## High-level Headers
|
||||
|
||||
[#core]
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/core.hpp[<boost/openmethod/core.hpp>]
|
||||
|
||||
Defines the main constructs of the library: methods, overriders and virtual
|
||||
pointers, and mechanisms to implement them. Does not define any public macros
|
||||
apart from `BOOST_OPENMETHOD_DEFAULT_REGISTRY`, if it is not defined already.
|
||||
|
||||
[#macros]
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/macros.hpp[<boost/openmethod/macros.hpp>]
|
||||
|
||||
Defines the public macros of the library, such as `BOOST_OPENMETHOD`,
|
||||
`BOOST_OPENMETHOD_CLASSES`, etc.
|
||||
|
||||
There is little point in including this header directly, as this has the same
|
||||
effect as including `boost/openmethod.hpp`, which is shorter.
|
||||
|
||||
[#openmethod]
|
||||
### link:{{BASE_URL}}/include/boost/openmethod.hpp[<boost/openmethod.hpp>]
|
||||
|
||||
Includes `core.hpp` and `macros.hpp`.
|
||||
|
||||
[#initialize]
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/initialize.hpp[<boost/initialize.hpp>]
|
||||
|
||||
Provides the cpp:initialize[] and cpp:finalize[] functions. This header is
|
||||
typically included in the translation unit containing `main`. Translation units
|
||||
that dynamically load or unload shared libraries may also need to call those
|
||||
functions.
|
||||
|
||||
[#std_shared_ptr]
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/interop/std_shared_ptr.hpp[<boost/openmethod/interop/std_shared_ptr.hpp>]
|
||||
|
||||
Provides a `virtual_traits` specialization that makes it possible to use a
|
||||
`std::shared_ptr` in place of a raw pointer or reference in virtual parameters.
|
||||
|
||||
[#std_unique_ptr]
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/interop/std_unique_ptr.hpp[<boost/openmethod/interop/std_unique_ptr.hpp>]
|
||||
|
||||
Provides a `virtual_traits` specialization that makes it possible to use a
|
||||
`std::unique_ptr` in place of a raw pointer or reference in virtual parameters.
|
||||
|
||||
*The headers below are for advanced use*.
|
||||
|
||||
## Pre-Core Headers
|
||||
@@ -30,82 +73,52 @@ The following headers can be included before `core.hpp` to define custom
|
||||
registries and policies, and override the default registry by defining
|
||||
xref:BOOST_OPENMETHOD_DEFAULT_REGISTRY.adoc[`BOOST_OPENMETHOD_DEFAULT_REGISTRY`].
|
||||
|
||||
### boost/openmethod/preamble.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/preamble.hpp[<boost/openmethod/preamble.hpp>]
|
||||
|
||||
Defines `registry` and stock policy categories. Also defines all types and
|
||||
functions necessary for the definition of `registry`.
|
||||
|
||||
### boost/openmethod/policies/std_rtti.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/policies/std_rtti.hpp[<boost/openmethod/policies/std_rtti.hpp>]
|
||||
|
||||
Provides an implementation of the `rtti` policy using standard RTTI.
|
||||
|
||||
### boost/openmethod/policies/fast_perfect_hash.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/policies/fast_perfect_hash.hpp[<boost/openmethod/policies/fast_perfect_hash.hpp>]
|
||||
|
||||
Provides an implementation of the `hash` policy using a fast perfect hash
|
||||
function.
|
||||
|
||||
### boost/openmethod/policies/vptr_vector.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/policies/vptr_vector.hpp[<boost/openmethod/policies/vptr_vector.hpp>]
|
||||
|
||||
Provides an implementation of the `vptr` policy that stores the v-table pointers
|
||||
in a `std::vector` indexed by type ids, possibly hashed.
|
||||
|
||||
### boost/openmethod/policies/default_error_handler.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/policies/default_error_handler.hpp[<boost/openmethod/policies/default_error_handler.hpp>]
|
||||
|
||||
Provides an implementation of the `error_handler` policy that calls a
|
||||
`std::function<void(openmethod_error)>` when an error is encountered, and before
|
||||
the library aborts the program.
|
||||
|
||||
### boost/openmethod/policies/stderr_output.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/policies/stderr_output.hpp[<boost/openmethod/policies/stderr_output.hpp>]
|
||||
|
||||
Provides an implementation of the `output` policy that writes diagnostics to
|
||||
the C standard error stream (not using iostreams).
|
||||
|
||||
### boost/openmethod/default_registry.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/default_registry.hpp[<boost/openmethod/default_registry.hpp>]
|
||||
|
||||
Defines the default registry, which contains all the stock policies listed
|
||||
above. Includes all the headers listed in the preamble section so far.
|
||||
above. Includes all the headers listed in this section so far.
|
||||
|
||||
### boost/openmethod/policies/static_rtti.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/policies/static_rtti.hpp[<boost/openmethod/policies/static_rtti.hpp>]
|
||||
|
||||
Provides a minimal implementation of the `rtti` policy that does not depend on
|
||||
standard RTTI.
|
||||
|
||||
### boost/openmethod/policies/throw_error_handler.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/policies/throw_error_handler.hpp[<boost/openmethod/policies/throw_error_handler.hpp>]
|
||||
|
||||
Provides an implementation of the `error_handler` policy that throws errors as
|
||||
exceptions.
|
||||
|
||||
### boost/openmethod/policies/vptr_map.hpp
|
||||
### link:{{BASE_URL}}/include/boost/openmethod/policies/vptr_map.hpp[<boost/openmethod/policies/vptr_map.hpp>]
|
||||
|
||||
Provides an implementation of the `vptr` policy that stores the v-table pointers
|
||||
in a map (by default a `std::map`) indexed by type ids.
|
||||
|
||||
## High-level Headers
|
||||
|
||||
### boost/openmethod/core.hpp
|
||||
|
||||
Defines the main constructs of the library: methods, overriders and virtual
|
||||
pointers, and mechanisms to implement them. Does not define any public macros
|
||||
apart from `BOOST_OPENMETHOD_DEFAULT_REGISTRY`, if it is not defined already.
|
||||
|
||||
### boost/openmethod/macros.hpp
|
||||
|
||||
Defines the public macros of the library, such as `BOOST_OPENMETHOD`,
|
||||
`BOOST_OPENMETHOD_CLASSES`, etc.
|
||||
|
||||
There is little point in including this header directly, as this has the same
|
||||
effect as including `boost/openmethod.hpp`, which is shorter.
|
||||
|
||||
### boost/openmethod.hpp
|
||||
|
||||
Includes `core.hpp` and `macros.hpp`.
|
||||
|
||||
### boost/openmethod/interop/std_shared_ptr.hpp
|
||||
|
||||
Provides a `virtual_traits` specialization that make it possible to use a
|
||||
`std::shared_ptr` in place of a raw pointer or reference in virtual parameters.
|
||||
|
||||
### boost/openmethod/interop/std_unique_ptr.hpp
|
||||
|
||||
Provides a `virtual_traits` specialization that make it possible to use a
|
||||
`std::unique_ptr` in place of a raw pointer or reference in virtual parameters.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[#macros]
|
||||
= xref:macros.adoc[Macros]
|
||||
:mrdocs:
|
||||
[#ref_macros]
|
||||
= xref:ref_macros.adoc[Macros]
|
||||
|
||||
The following macros - in particular the first three- are sufficient for most
|
||||
uses of the library.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
## Registries and Policies
|
||||
[#registries_and_policies]
|
||||
|
||||
Methods are scoped in a registry. A method can only reference classes in the
|
||||
same registry. If a class is used as a virtual parameter in methods using
|
||||
@@ -20,9 +20,9 @@ A registry has a collection of _policies_. Each policy belongs to a policy
|
||||
category. A registry may contain at most one policy of each category. Policies
|
||||
control how type information is obtained, how vptrs are acquired, how errors are
|
||||
handled and reported, etc. While the behavior of cpp:initialize[] can be
|
||||
customized via options, policies are primarily involved in in method dispatch.
|
||||
customized via options, policies are primarily involved in method dispatch.
|
||||
|
||||
Policies are placed in the `boost::openmethod::policies` namespace.
|
||||
Policies are placed in the cpp:boost::openmethod::policies[] namespace.
|
||||
|
||||
`default_registry` contains the following policies:
|
||||
|
||||
@@ -40,11 +40,11 @@ Policies are placed in the `boost::openmethod::policies` namespace.
|
||||
|
||||
| type_hash
|
||||
| fast_perfect_hash
|
||||
| hash type id to an index in a vector
|
||||
| hashes type id to an index in a vector
|
||||
|
||||
| error_handler
|
||||
| default_error_handler
|
||||
| handles errors
|
||||
| calls an overridable handler function
|
||||
|
||||
| output
|
||||
| stderr_output
|
||||
@@ -61,7 +61,7 @@ registrations that could not be caught by `initialize`.
|
||||
The library provides another predefined registry: cpp:indirect_registry[]. It is
|
||||
useful when shared libraries are dynamically loaded at runtime, and add methods
|
||||
and overriders across program and shared library boundaries. See the section
|
||||
about shared_libraries.adoc[shared libraries].
|
||||
about xref:shared_libraries.adoc[shared libraries].
|
||||
|
||||
Registries can be created from scratch, using the `registry` template. Here is
|
||||
the definition of `default_registry`, copied from
|
||||
@@ -99,9 +99,9 @@ struct indirect_registry : default_registry::with<policies::indirect_vptr> {};
|
||||
Policies are implemented as unary
|
||||
https://www.boost.org/doc/libs/1_89_0/libs/mp11/doc/html/mp11.html[Boost.MP11
|
||||
quoted metafunctions]. A policy is an ordinary class that contains a nested
|
||||
class template, called `fn` which is instantiated by the registry, passing
|
||||
itself as the template argument. The reason for this mechanism is to allow
|
||||
policies that have static data members to give each registry its own copy.
|
||||
class template `fn`, which is instantiated by the registry, passing itself as
|
||||
the single template argument. The reason for this mechanism is to allow policies
|
||||
to have static data members, which each registry must have its own set of.
|
||||
`vptr_vector`, for example, stores v-table pointers in a `std::vector`. If it is
|
||||
used in two different registries, it needs to use two different vectors, one for
|
||||
each registry.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
:shared: ../examples/shared_libs
|
||||
|
||||
## Shared Libraries
|
||||
[#shared_libraries]
|
||||
|
||||
This section discusses how OpenMethod interoperates with shared libraries on
|
||||
Linux, other POSIX-like platforms, and Windows.
|
||||
@@ -79,7 +79,7 @@ include::{shared}/dynamic_main.cpp[tag=unload]
|
||||
|
||||
### Windows
|
||||
|
||||
If we try the aboveexample on Windows, the result is disappointing:
|
||||
If we try the example on Windows, the result is disappointing:
|
||||
|
||||
```
|
||||
Before loading the shared library.
|
||||
@@ -98,7 +98,7 @@ they add overriders to _their_ copy of the method (the `method::fn` static
|
||||
variable for the given name and signature). They are ignored when the main
|
||||
program calls `initialize`.
|
||||
|
||||
Likewise, `BOOST_OPENMETHOD_CLASSES(Tiger, Carnivore);` in the DLL adds `Tiger`
|
||||
Likewise, `BOOST_OPENMETHOD_CLASSES(Tiger, Carnivore)` in the DLL adds `Tiger`
|
||||
to the DLL's copy of the registry. For the perspective of the program's
|
||||
registry, the class does not exist.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
## Smart Pointers
|
||||
[#smart_pointers]
|
||||
|
||||
If we want maximum performance, we want to use `virtual_ptr`{empty}s in place of
|
||||
ordinary pointers or references. However, we may also want to use smart pointers
|
||||
@@ -20,10 +20,10 @@ v-table pointer.
|
||||
Smart `virtual_ptr`{empty}s automatically convert to their non-smart, "plain"
|
||||
counterparts - e.g. from `virtual_ptr<std::unique_ptr<const Node>>` to
|
||||
`virtual_ptr<const Node>`. Methods and overriders typically use plain
|
||||
`virtual_ptr`{empty}s, although it is not always the case. For example,
|
||||
`virtual_ptr`{empty}s, although it is not always the case footnote:[For example,
|
||||
consider a `transpose` method for matrices. If the matrix is symmetric, the
|
||||
overrider should return its argument. This can be implemented by passing a
|
||||
`virtual_ptr<std::shared_ptr<const Matrix>>` to the method.
|
||||
`virtual_ptr<std::shared_ptr<const Matrix>>` to the method.].
|
||||
|
||||
The reverse conversion, from plain to smart, does not exist, because it would
|
||||
have the potential to accidentally create smart pointers. Likewise, a smart
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
:example: ../examples/virtual_ptr_alt
|
||||
|
||||
[#virtual_ptr_alt]
|
||||
## Alternatives to virtual_ptr
|
||||
|
||||
Virtual arguments can also be passed as plain references, plain pointers, or
|
||||
|
||||
@@ -17,13 +17,13 @@ implementation-defined:
|
||||
- 'boost::openmethod::detail'
|
||||
inaccessible-members: never
|
||||
inaccessible-bases: never
|
||||
# see-below:
|
||||
# - 'boost::urls::format_arg'
|
||||
# implementation-defined:
|
||||
# - 'boost::openmethod::detail::**'
|
||||
exclude-symbols:
|
||||
- 'boost::openmethod::registry::compiler'
|
||||
- 'boost::openmethod::registry::initialize'
|
||||
- 'boost::openmethod::registry::finalize'
|
||||
- 'boost::openmethod::boost_openmethod_bases'
|
||||
- 'boost::openmethod::boost_openmethod_registry'
|
||||
- 'boost::openmethod::registry::compiler'
|
||||
|
||||
sort-members: false
|
||||
# sort-namespace-members-by: location
|
||||
@@ -36,7 +36,7 @@ auto-function-metadata: false
|
||||
|
||||
# Generator
|
||||
generate: adoc
|
||||
base-url: https://www.github.com/boostorg/openmethod/blob/develop/
|
||||
base-url: https://www.github.com/boostorg/openmethod/blob/master/
|
||||
|
||||
# Style
|
||||
verbose: true
|
||||
|
||||
599
doc/package-lock.json
generated
599
doc/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@antora/cli": "3.1.10",
|
||||
"@antora/site-generator": "3.1.10",
|
||||
"antora": "3.1.10"
|
||||
"@antora/cli": "3.1.14",
|
||||
"@antora/site-generator": "3.1.14",
|
||||
"antora": "3.1.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@antora/expand-path-helper": "^2.0.0",
|
||||
"@antora/lunr-extension": "^1.0.0-alpha.8",
|
||||
"@asciidoctor/tabs": "^1.0.0-beta.3",
|
||||
"@cppalliance/antora-cpp-reference-extension": "^0.0.8",
|
||||
"@cppalliance/antora-cpp-tagfiles-extension": "^0.0.5",
|
||||
"@antora/expand-path-helper": "^3.0.0",
|
||||
"@antora/lunr-extension": "^1.0.0-alpha.12",
|
||||
"@asciidoctor/tabs": "^1.0.0-beta.6",
|
||||
"@cppalliance/antora-cpp-reference-extension": "^0.1.0",
|
||||
"@cppalliance/antora-cpp-tagfiles-extension": "^0.1.0",
|
||||
"@cppalliance/asciidoctor-boost-links": "^0.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,907 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<tagfile>
|
||||
<compound kind="namespace">
|
||||
<name>boost::openmethod</name>
|
||||
<filename>boost/openmethod.adoc</filename>
|
||||
<class kind="class">boost::openmethod::shared_virtual_ptr</class>
|
||||
<class kind="class">boost::openmethod::type_id</class>
|
||||
<class kind="class">boost::openmethod::unique_virtual_ptr</class>
|
||||
<class kind="class">boost::openmethod::vptr_type</class>
|
||||
<class kind="class">boost::openmethod::LightweightOutputStream</class>
|
||||
<class kind="class">boost::openmethod::StripVirtualDecorator</class>
|
||||
<class kind="class">boost::openmethod::StripVirtualDecorator</class>
|
||||
<class kind="class">boost::openmethod::VirtualTraits</class>
|
||||
<class kind="class">boost::openmethod::ambiguous_call</class>
|
||||
<class kind="class">boost::openmethod::bad_call</class>
|
||||
<class kind="class">boost::openmethod::default_registry</class>
|
||||
<class kind="class">boost::openmethod::final_error</class>
|
||||
<class kind="class">boost::openmethod::indirect_registry</class>
|
||||
<class kind="class">boost::openmethod::inplace_vptr_base</class>
|
||||
<class kind="class">boost::openmethod::inplace_vptr_derived</class>
|
||||
<class kind="class">boost::openmethod::inplace_vptr_derived</class>
|
||||
<class kind="class">boost::openmethod::inplace_vptr_derived</class>
|
||||
<class kind="class">boost::openmethod::method</class>
|
||||
<class kind="class">boost::openmethod::method</class>
|
||||
<class kind="class">boost::openmethod::missing_base</class>
|
||||
<class kind="class">boost::openmethod::missing_class</class>
|
||||
<class kind="class">boost::openmethod::n2216</class>
|
||||
<class kind="class">boost::openmethod::no_overrider</class>
|
||||
<class kind="class">boost::openmethod::not_initialized</class>
|
||||
<class kind="class">boost::openmethod::odr_violation</class>
|
||||
<class kind="class">boost::openmethod::openmethod_error</class>
|
||||
<class kind="class">boost::openmethod::registry</class>
|
||||
<class kind="class">boost::openmethod::trace</class>
|
||||
<class kind="class">boost::openmethod::use_classes</class>
|
||||
<class kind="class">boost::openmethod::virtual_</class>
|
||||
<class kind="class">boost::openmethod::virtual_ptr</class>
|
||||
<class kind="class">boost::openmethod::virtual_ptr</class>
|
||||
<class kind="class">boost::openmethod::virtual_traits</class>
|
||||
<class kind="class">boost::openmethod::virtual_traits</class>
|
||||
<class kind="class">boost::openmethod::virtual_traits</class>
|
||||
<class kind="class">boost::openmethod::virtual_traits</class>
|
||||
<class kind="class">boost::openmethod::virtual_traits</class>
|
||||
<class kind="class">boost::openmethod::virtual_traits</class>
|
||||
<class kind="class">boost::openmethod::virtual_traits</class>
|
||||
<class kind="class">boost::openmethod::virtual_traits</class>
|
||||
<class kind="class">boost::openmethod::virtual_traits</class>
|
||||
<class kind="class">boost::openmethod::final_virtual_ptr</class>
|
||||
<class kind="class">boost::openmethod::IsPolymorphic</class>
|
||||
<class kind="class">boost::openmethod::IsSmartPtr</class>
|
||||
<class kind="class">boost::openmethod::SameSmartPtr</class>
|
||||
<class kind="class">boost::openmethod::virtual_ptr</class>
|
||||
<class kind="class">boost::openmethod::virtual_ptr</class>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>finalize</name>
|
||||
<anchorfile>boost/openmethod/finalize.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>initialize</name>
|
||||
<anchorfile>boost/openmethod/initialize.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(...Options...&& options)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>make_shared_virtual</name>
|
||||
<anchorfile>boost/openmethod/make_shared_virtual.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(...T...&& args)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>make_unique_virtual</name>
|
||||
<anchorfile>boost/openmethod/make_unique_virtual.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(...T...&& args)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>bool</type>
|
||||
<name>operator==</name>
|
||||
<anchorfile>boost/openmethod/operator_eq.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const virtual_ptr<Left, Registry>& left, const virtual_ptr<Right, Registry>& right)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>bool</type>
|
||||
<name>operator!=</name>
|
||||
<anchorfile>boost/openmethod/operator_not_eq.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const virtual_ptr<Left, Registry>& left, const virtual_ptr<Right, Registry>& right)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="namespace">
|
||||
<name>boost::openmethod::aliases</name>
|
||||
<filename>boost/openmethod/aliases.adoc</filename>
|
||||
<class kind="class">boost::openmethod::aliases::final_virtual_ptr</class>
|
||||
<class kind="class">boost::openmethod::aliases::initialize</class>
|
||||
<class kind="class">boost::openmethod::aliases::inplace_vptr_base</class>
|
||||
<class kind="class">boost::openmethod::aliases::inplace_vptr_derived</class>
|
||||
<class kind="class">boost::openmethod::aliases::make_shared_virtual</class>
|
||||
<class kind="class">boost::openmethod::aliases::make_unique_virtual</class>
|
||||
<class kind="class">boost::openmethod::aliases::shared_virtual_ptr</class>
|
||||
<class kind="class">boost::openmethod::aliases::unique_virtual_ptr</class>
|
||||
<class kind="class">boost::openmethod::aliases::virtual_</class>
|
||||
<class kind="class">boost::openmethod::aliases::virtual_ptr</class>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::final_virtual_ptr</name>
|
||||
<filename>boost/openmethod/aliases/final_virtual_ptr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::initialize</name>
|
||||
<filename>boost/openmethod/aliases/initialize.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::inplace_vptr_base</name>
|
||||
<filename>boost/openmethod/aliases/inplace_vptr_base.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::inplace_vptr_derived</name>
|
||||
<filename>boost/openmethod/aliases/inplace_vptr_derived.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::make_shared_virtual</name>
|
||||
<filename>boost/openmethod/aliases/make_shared_virtual.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::make_unique_virtual</name>
|
||||
<filename>boost/openmethod/aliases/make_unique_virtual.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::shared_virtual_ptr</name>
|
||||
<filename>boost/openmethod/aliases/shared_virtual_ptr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::unique_virtual_ptr</name>
|
||||
<filename>boost/openmethod/aliases/unique_virtual_ptr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::virtual_</name>
|
||||
<filename>boost/openmethod/aliases/virtual_.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::aliases::virtual_ptr</name>
|
||||
<filename>boost/openmethod/aliases/virtual_ptr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="namespace">
|
||||
<name>boost::openmethod::policies</name>
|
||||
<filename>boost/openmethod/policies.adoc</filename>
|
||||
<class kind="class">boost::openmethod::policies::ErrorHandlerFn</class>
|
||||
<class kind="class">boost::openmethod::policies::IdsToVptr</class>
|
||||
<class kind="class">boost::openmethod::policies::OutputFn</class>
|
||||
<class kind="class">boost::openmethod::policies::RttiFn</class>
|
||||
<class kind="class">boost::openmethod::policies::TypeHashFn</class>
|
||||
<class kind="class">boost::openmethod::policies::VptrFn</class>
|
||||
<class kind="class">boost::openmethod::policies::default_error_handler</class>
|
||||
<class kind="class">boost::openmethod::policies::deferred_static_rtti</class>
|
||||
<class kind="class">boost::openmethod::policies::error_handler</class>
|
||||
<class kind="class">boost::openmethod::policies::fast_perfect_hash</class>
|
||||
<class kind="class">boost::openmethod::policies::indirect_vptr</class>
|
||||
<class kind="class">boost::openmethod::policies::output</class>
|
||||
<class kind="class">boost::openmethod::policies::rtti</class>
|
||||
<class kind="class">boost::openmethod::policies::runtime_checks</class>
|
||||
<class kind="class">boost::openmethod::policies::static_rtti</class>
|
||||
<class kind="class">boost::openmethod::policies::std_rtti</class>
|
||||
<class kind="class">boost::openmethod::policies::stderr_output</class>
|
||||
<class kind="class">boost::openmethod::policies::throw_error_handler</class>
|
||||
<class kind="class">boost::openmethod::policies::type_hash</class>
|
||||
<class kind="class">boost::openmethod::policies::vptr</class>
|
||||
<class kind="class">boost::openmethod::policies::vptr_map</class>
|
||||
<class kind="class">boost::openmethod::policies::vptr_vector</class>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::ErrorHandlerFn</name>
|
||||
<filename>boost/openmethod/policies/ErrorHandlerFn.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>error</name>
|
||||
<anchorfile>boost/openmethod/policies/ErrorHandlerFn/error.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const auto& error)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::IdsToVptr</name>
|
||||
<filename>boost/openmethod/policies/IdsToVptr.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>type_id_begin</name>
|
||||
<anchorfile>boost/openmethod/policies/IdsToVptr/type_id_begin.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>type_id_end</name>
|
||||
<anchorfile>boost/openmethod/policies/IdsToVptr/type_id_end.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>const vptr_type&</type>
|
||||
<name>vptr</name>
|
||||
<anchorfile>boost/openmethod/policies/IdsToVptr/vptr.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::OutputFn</name>
|
||||
<filename>boost/openmethod/policies/OutputFn.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::RttiFn</name>
|
||||
<filename>boost/openmethod/policies/RttiFn.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>type_id</type>
|
||||
<name>static_type</name>
|
||||
<anchorfile>boost/openmethod/policies/RttiFn/static_type.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>type_id</type>
|
||||
<name>dynamic_type</name>
|
||||
<anchorfile>boost/openmethod/policies/RttiFn/dynamic_type.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const Class& obj)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>type_name</name>
|
||||
<anchorfile>boost/openmethod/policies/RttiFn/type_name.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(type_id type, Stream& stream)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>type_index</name>
|
||||
<anchorfile>boost/openmethod/policies/RttiFn/type_index.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(type_id type)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>D</type>
|
||||
<name>dynamic_cast_ref</name>
|
||||
<anchorfile>boost/openmethod/policies/RttiFn/dynamic_cast_ref.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(B&& obj)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::TypeHashFn</name>
|
||||
<filename>boost/openmethod/policies/TypeHashFn.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>std::pair<std::size_t, std::size_t></type>
|
||||
<name>initialize</name>
|
||||
<anchorfile>boost/openmethod/policies/TypeHashFn/initialize.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(ForwardIterator first, ForwardIterator last)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>std::size_t</type>
|
||||
<name>hash</name>
|
||||
<anchorfile>boost/openmethod/policies/TypeHashFn/hash.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(type_id type)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>finalize</name>
|
||||
<anchorfile>boost/openmethod/policies/TypeHashFn/finalize.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::VptrFn</name>
|
||||
<filename>boost/openmethod/policies/VptrFn.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>initialize</name>
|
||||
<anchorfile>boost/openmethod/policies/VptrFn/initialize.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(ForwardIterator first, ForwardIterator last, std::tuple<Options...> opts)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>const vptr_type&</type>
|
||||
<name>dynamic_vptr</name>
|
||||
<anchorfile>boost/openmethod/policies/VptrFn/dynamic_vptr.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const Class& arg)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>finalize</name>
|
||||
<anchorfile>boost/openmethod/policies/VptrFn/finalize.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(std::tuple<Options...> opts)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::default_error_handler</name>
|
||||
<filename>boost/openmethod/policies/default_error_handler.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::deferred_static_rtti</name>
|
||||
<filename>boost/openmethod/policies/deferred_static_rtti.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::error_handler</name>
|
||||
<filename>boost/openmethod/policies/error_handler.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::fast_perfect_hash</name>
|
||||
<filename>boost/openmethod/policies/fast_perfect_hash.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::indirect_vptr</name>
|
||||
<filename>boost/openmethod/policies/indirect_vptr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::output</name>
|
||||
<filename>boost/openmethod/policies/output.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::rtti</name>
|
||||
<filename>boost/openmethod/policies/rtti.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::runtime_checks</name>
|
||||
<filename>boost/openmethod/policies/runtime_checks.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::static_rtti</name>
|
||||
<filename>boost/openmethod/policies/static_rtti.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::std_rtti</name>
|
||||
<filename>boost/openmethod/policies/std_rtti.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::stderr_output</name>
|
||||
<filename>boost/openmethod/policies/stderr_output.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::throw_error_handler</name>
|
||||
<filename>boost/openmethod/policies/throw_error_handler.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::type_hash</name>
|
||||
<filename>boost/openmethod/policies/type_hash.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::vptr</name>
|
||||
<filename>boost/openmethod/policies/vptr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::vptr_map</name>
|
||||
<filename>boost/openmethod/policies/vptr_map.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::policies::vptr_vector</name>
|
||||
<filename>boost/openmethod/policies/vptr_vector.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::shared_virtual_ptr</name>
|
||||
<filename>boost/openmethod/shared_virtual_ptr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::type_id</name>
|
||||
<filename>boost/openmethod/type_id.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::unique_virtual_ptr</name>
|
||||
<filename>boost/openmethod/unique_virtual_ptr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::vptr_type</name>
|
||||
<filename>boost/openmethod/vptr_type.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::LightweightOutputStream</name>
|
||||
<filename>boost/openmethod/LightweightOutputStream.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::StripVirtualDecorator</name>
|
||||
<filename>boost/openmethod/StripVirtualDecorator-020.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::StripVirtualDecorator</name>
|
||||
<filename>boost/openmethod/StripVirtualDecorator-028.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::VirtualTraits</name>
|
||||
<filename>boost/openmethod/VirtualTraits.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>const virtual_type&</type>
|
||||
<name>peek</name>
|
||||
<anchorfile>boost/openmethod/VirtualTraits/peek.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(T arg)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>U</type>
|
||||
<name>cast</name>
|
||||
<anchorfile>boost/openmethod/VirtualTraits/cast.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(T arg)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::ambiguous_call</name>
|
||||
<filename>boost/openmethod/ambiguous_call.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>write</name>
|
||||
<anchorfile>boost/openmethod/ambiguous_call/write.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Stream& os)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::bad_call</name>
|
||||
<filename>boost/openmethod/bad_call.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::default_registry</name>
|
||||
<filename>boost/openmethod/default_registry.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::final_error</name>
|
||||
<filename>boost/openmethod/final_error.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>write</name>
|
||||
<anchorfile>boost/openmethod/final_error/write.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Stream& os)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::indirect_registry</name>
|
||||
<filename>boost/openmethod/indirect_registry.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::inplace_vptr_base</name>
|
||||
<filename>boost/openmethod/inplace_vptr_base.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>inplace_vptr_base</name>
|
||||
<anchorfile>boost/openmethod/inplace_vptr_base/2constructor.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>~inplace_vptr_base</name>
|
||||
<anchorfile>boost/openmethod/inplace_vptr_base/2destructor.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::inplace_vptr_derived</name>
|
||||
<filename>boost/openmethod/inplace_vptr_derived-00.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>inplace_vptr_derived</name>
|
||||
<anchorfile>boost/openmethod/inplace_vptr_derived-00/2constructor.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>~inplace_vptr_derived</name>
|
||||
<anchorfile>boost/openmethod/inplace_vptr_derived-00/2destructor.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::inplace_vptr_derived</name>
|
||||
<filename>boost/openmethod/inplace_vptr_derived-058.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>inplace_vptr_derived</name>
|
||||
<anchorfile>boost/openmethod/inplace_vptr_derived-058/2constructor.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>~inplace_vptr_derived</name>
|
||||
<anchorfile>boost/openmethod/inplace_vptr_derived-058/2destructor.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::inplace_vptr_derived</name>
|
||||
<filename>boost/openmethod/inplace_vptr_derived-056.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>inplace_vptr_derived</name>
|
||||
<anchorfile>boost/openmethod/inplace_vptr_derived-056/2constructor.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>~inplace_vptr_derived</name>
|
||||
<anchorfile>boost/openmethod/inplace_vptr_derived-056/2destructor.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::method</name>
|
||||
<filename>boost/openmethod/method-0d8.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::method</name>
|
||||
<filename>boost/openmethod/method-0db.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>ReturnType</type>
|
||||
<name>operator()</name>
|
||||
<anchorfile>boost/openmethod/method-0db/operator_call.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(...StripVirtualDecorator<Parameters>::type args)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>bool</type>
|
||||
<name>has_next</name>
|
||||
<anchorfile>boost/openmethod/method-0db/has_next.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::missing_base</name>
|
||||
<filename>boost/openmethod/missing_base.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>write</name>
|
||||
<anchorfile>boost/openmethod/missing_base/write.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Stream& os)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::missing_class</name>
|
||||
<filename>boost/openmethod/missing_class.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>write</name>
|
||||
<anchorfile>boost/openmethod/missing_class/write.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Stream& os)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::n2216</name>
|
||||
<filename>boost/openmethod/n2216.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::no_overrider</name>
|
||||
<filename>boost/openmethod/no_overrider.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>write</name>
|
||||
<anchorfile>boost/openmethod/no_overrider/write.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Stream& os)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::not_initialized</name>
|
||||
<filename>boost/openmethod/not_initialized.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>write</name>
|
||||
<anchorfile>boost/openmethod/not_initialized/write.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Stream& os)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::odr_violation</name>
|
||||
<filename>boost/openmethod/odr_violation.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>write</name>
|
||||
<anchorfile>boost/openmethod/odr_violation/write.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Stream& stream)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::openmethod_error</name>
|
||||
<filename>boost/openmethod/openmethod_error.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::registry</name>
|
||||
<filename>boost/openmethod/registry-07c.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>require_initialized</name>
|
||||
<anchorfile>boost/openmethod/registry-07c/require_initialized.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>finalize</name>
|
||||
<anchorfile>boost/openmethod/registry-07c/finalize.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(...Options opts)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::trace</name>
|
||||
<filename>boost/openmethod/trace.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>void</type>
|
||||
<name>trace</name>
|
||||
<anchorfile>boost/openmethod/trace/2constructor.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(bool on)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>trace</type>
|
||||
<name>from_env</name>
|
||||
<anchorfile>boost/openmethod/trace/from_env.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::use_classes</name>
|
||||
<filename>boost/openmethod/use_classes.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_</name>
|
||||
<filename>boost/openmethod/virtual_.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_ptr</name>
|
||||
<filename>boost/openmethod/virtual_ptr-0a.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>Class*</type>
|
||||
<name>get</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0a/get.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>operator-></name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0a/operator_ptr.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>element_type&</type>
|
||||
<name>operator*</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0a/operator_star.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>element_type*</type>
|
||||
<name>pointer</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0a/pointer.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>decltype(auto)</type>
|
||||
<name>cast</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0a/cast.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>vptr</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0a/vptr.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>final</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0a/final.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Other&& obj)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_ptr</name>
|
||||
<filename>boost/openmethod/virtual_ptr-0b5.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>element_type*</type>
|
||||
<name>get</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0b5/get.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>element_type*</type>
|
||||
<name>operator-></name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0b5/operator_ptr.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>element_type&</type>
|
||||
<name>operator*</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0b5/operator_star.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>const SmartPtr&</type>
|
||||
<name>pointer</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0b5/pointer.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>vptr</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0b5/vptr.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>()</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>final</name>
|
||||
<anchorfile>boost/openmethod/virtual_ptr-0b5/final.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Other&& obj)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_traits</name>
|
||||
<filename>boost/openmethod/virtual_traits-0be.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_traits</name>
|
||||
<filename>boost/openmethod/virtual_traits-043.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>const Class&</type>
|
||||
<name>peek</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-043/peek.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const std::shared_ptr<Class>& arg)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_traits</name>
|
||||
<filename>boost/openmethod/virtual_traits-0bf.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>const Class&</type>
|
||||
<name>peek</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-0bf/peek.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const std::unique_ptr<Class>& arg)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>cast</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-0bf/cast.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(std::unique_ptr<Class>&& ptr)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_traits</name>
|
||||
<filename>boost/openmethod/virtual_traits-096.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>const virtual_ptr<Class, Registry>&</type>
|
||||
<name>peek</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-096/peek.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const virtual_ptr<Class, Registry>& ptr)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_traits</name>
|
||||
<filename>boost/openmethod/virtual_traits-08.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>const Class&</type>
|
||||
<name>peek</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-08/peek.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const Class& arg)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>Derived</type>
|
||||
<name>cast</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-08/cast.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Class& obj)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_traits</name>
|
||||
<filename>boost/openmethod/virtual_traits-07a.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>const Class&</type>
|
||||
<name>peek</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-07a/peek.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const std::shared_ptr<Class>& arg)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>auto</type>
|
||||
<name>cast</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-07a/cast.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const std::shared_ptr<Class>& obj)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_traits</name>
|
||||
<filename>boost/openmethod/virtual_traits-048.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>const virtual_ptr<Class, Registry>&</type>
|
||||
<name>peek</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-048/peek.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const virtual_ptr<Class, Registry>& ptr)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>decltype(auto)</type>
|
||||
<name>cast</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-048/cast.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const virtual_ptr<Class, Registry>& ptr)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_traits</name>
|
||||
<filename>boost/openmethod/virtual_traits-098.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>const Class&</type>
|
||||
<name>peek</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-098/peek.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const Class& arg)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>Derived</type>
|
||||
<name>cast</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-098/cast.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Class&& obj)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_traits</name>
|
||||
<filename>boost/openmethod/virtual_traits-071.adoc</filename>
|
||||
<member kind="function">
|
||||
<type>const Class&</type>
|
||||
<name>peek</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-071/peek.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(const Class* arg)</arglist>
|
||||
</member>
|
||||
<member kind="function">
|
||||
<type>Derived</type>
|
||||
<name>cast</name>
|
||||
<anchorfile>boost/openmethod/virtual_traits-071/cast.adoc</anchorfile>
|
||||
<anchor/>
|
||||
<arglist>(Class* ptr)</arglist>
|
||||
</member>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::final_virtual_ptr</name>
|
||||
<filename>boost/openmethod/final_virtual_ptr-04.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::IsPolymorphic</name>
|
||||
<filename>boost/openmethod/IsPolymorphic.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::IsSmartPtr</name>
|
||||
<filename>boost/openmethod/IsSmartPtr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::SameSmartPtr</name>
|
||||
<filename>boost/openmethod/SameSmartPtr.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_ptr</name>
|
||||
<filename>boost/openmethod/virtual_ptr-0d.adoc</filename>
|
||||
</compound>
|
||||
<compound kind="class">
|
||||
<name>boost::openmethod::virtual_ptr</name>
|
||||
<filename>boost/openmethod/virtual_ptr-0b6.adoc</filename>
|
||||
</compound>
|
||||
</tagfile>
|
||||
@@ -192,7 +192,10 @@ using virtual_types = boost::mp11::mp_transform<
|
||||
|
||||
BOOST_OPENMETHOD_OPEN_NAMESPACE_DETAIL_UNLESS_MRDOCS
|
||||
|
||||
//! Remove virtual_<> decorator from a type (exposition only).
|
||||
//! Removes the virtual_<> decorator, if present (exposition only).
|
||||
//!
|
||||
//! Provides a nested `type` equal to `T`. The template is specialized for
|
||||
//! `virtual_<T>`.
|
||||
//!
|
||||
//! @tparam T A type.
|
||||
template<typename T>
|
||||
@@ -201,7 +204,11 @@ struct StripVirtualDecorator {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
//! Remove virtual_<> decorator from a type (exposition only).
|
||||
//! Removes the virtual_<> decorator (exposition only).
|
||||
//!
|
||||
//! Provides a nested `type` equal to `T`.
|
||||
//!
|
||||
//! @tparam T A type.
|
||||
template<typename T>
|
||||
struct StripVirtualDecorator<virtual_<T>> {
|
||||
//! Same as `T`.
|
||||
@@ -213,20 +220,20 @@ BOOST_OPENMETHOD_CLOSE_NAMESPACE_DETAIL_UNLESS_MRDOCS
|
||||
// =============================================================================
|
||||
// virtual_traits
|
||||
|
||||
//! Traits for types that can be used as virtual arguments.
|
||||
//! Traits for types used as virtual parameters.
|
||||
//!
|
||||
//! `virtual_traits` must be specialized for each type that can be used as a
|
||||
//! virtual parameters. It enables methods to:
|
||||
//! @li find the type of the object the argument refers to (e.g. `Cat` from
|
||||
//! `Cat&`)
|
||||
//! @li obtain a non-modifiable reference to that object (e.g. a `const Cat&` from
|
||||
//! `Cat&`)
|
||||
//! @li cast the argument to another type (e.g. cast a `Animal&` to a `Cat&`)
|
||||
//!
|
||||
//! @li find the type of the object the argument refers to (e.g. `Node` from
|
||||
//! `Node&`)
|
||||
//! @li obtain a non-modifiable reference to that object (e.g. a `const Node&` from
|
||||
//! `Node&`)
|
||||
//! @li cast the argument to another type (e.g. cast a `Node&` to a `Plus&`)
|
||||
//!
|
||||
//! @par Requirements
|
||||
//! Specializations of `virtual_traits` must implement the members deswcribed to the @ref VirtualTraits
|
||||
//! blueprint.
|
||||
//!
|
||||
//! Specializations of `virtual_traits` must provide the members described to
|
||||
//! the @ref VirtualTraits blueprint.
|
||||
//!
|
||||
//! @tparam T A type referring (in the broad sense) to an instance of a class.
|
||||
//! @tparam Registry A @ref registry.
|
||||
@@ -2067,20 +2074,19 @@ struct validate_method_parameter<
|
||||
//!
|
||||
//! `Registry` is an instantiation of class template @ref registry. Methods may
|
||||
//! use only classes that have been registered in the same registry as virtual
|
||||
//! parameters and arguments. The registry also policies that influence several
|
||||
//! aspects of the dispatch mechanism - for example, how to obtain a v-table
|
||||
//! pointer for an object, how to report errors, whether to perform sanity
|
||||
//! checks, etc.
|
||||
//! parameters and arguments. The registry also contains a set of policies that
|
||||
//! influence several aspects of the dispatch mechanism - for example, how to
|
||||
//! acquire a v-table pointer for an object, how to report errors, whether to
|
||||
//! perform sanity checks, etc.
|
||||
//!
|
||||
//! The default value of `Registry` is the preprocessor symbol
|
||||
//! `BOOST_OPENMETHOD_DEFAULT_REGISTRY`. It can be defined before including the
|
||||
//! `<boost/openmethod/core.hpp>` header to override the default registry.
|
||||
//! Setting this symbol after including `core.hpp` has no effect.
|
||||
//! The default value for `Registry` is @ref default_registry, but it can be
|
||||
//! overridden by defining the preprocessor symbol
|
||||
//! {{BOOST_OPENMETHOD_DEFAULT_REGISTRY}}, *before* including
|
||||
//! `<boost/openmethod/core.hpp>`. Setting the symbol afterwards has no effect.
|
||||
//!
|
||||
//! Specializations of `method` have a single instance: the static member `fn`,
|
||||
//! a function object whose `operator()` is used to call the method and forward
|
||||
//! to the appropriate overrider. It is selected in the same way as overloaded
|
||||
//! function resolution:
|
||||
//! which has an `operator()` that forwards to the appropriate overrider. It is
|
||||
//! selected in the same way as overloaded function resolution:
|
||||
//!
|
||||
//! 1. Form the set of all applicable overriders. An overrider is applicable
|
||||
//! if it can be called with the arguments passed to the method.
|
||||
@@ -2088,8 +2094,8 @@ struct validate_method_parameter<
|
||||
//! 2. If the set is empty, call the error handler (if present in the
|
||||
//! registry), then terminate the program with `abort`.
|
||||
//!
|
||||
//! 3. Remove the overriders that are dominated by other overriders in the
|
||||
//! set. Overrider A dominates overrider B if any of its virtual formal
|
||||
//! 3. Remove the overriders that are dominated by other overriders in the set.
|
||||
//! Overrider A dominates overrider B if at least one of its virtual formal
|
||||
//! parameters is more specialized than B's, and if none of B's virtual
|
||||
//! parameters is more specialized than A's.
|
||||
//!
|
||||
@@ -2806,6 +2812,9 @@ using boost::openmethod::virtual_ptr;
|
||||
//!
|
||||
//! Specializations of @ref virtual_traits must implement the members listed
|
||||
//! here.
|
||||
//!
|
||||
//! @tparam T The type of a virtual parameter of a method.
|
||||
//! @tparam Registry A @ref registry.
|
||||
template<typename T, class Registry>
|
||||
struct VirtualTraits {
|
||||
//! Class to use for dispatch.
|
||||
@@ -2817,6 +2826,11 @@ struct VirtualTraits {
|
||||
//! `virtual_ptr<const Class>`, `std::shared_ptr<Class>`,
|
||||
//! `std::shared_ptr<const Class>`, `virtual_ptr<std::shared_ptr<Class>>`,
|
||||
//! etc.
|
||||
//!
|
||||
//! @par Requirements
|
||||
//!
|
||||
//! `virtual_type` must be an alias to an *unadorned* *class* type, *not*
|
||||
//! cv-qualified.
|
||||
using virtual_type = detail::unspecified;
|
||||
|
||||
//! Returns a reference to the object to use for dispatch.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1544,10 +1544,9 @@ void registry<Policies...>::compiler<Options...>::print(
|
||||
|
||||
//! Initialize a registry.
|
||||
//!
|
||||
//! Initialize the @ref registry passed as an explicit function template
|
||||
//! Initialize the @ref registry passed as an explicit function template
|
||||
//! argument, or @ref default_registry if the registry is not specified. The
|
||||
//! default can be changed by defining
|
||||
//! {{BOOST_OPENMETHOD_DEFAULT_REGISTRY}}.
|
||||
//! default can be changed by defining {{BOOST_OPENMETHOD_DEFAULT_REGISTRY}}.
|
||||
//! Option objects can be passed to change the behavior of the function.
|
||||
//! Currently two options exist:
|
||||
//! @li @ref trace Enable tracing of the initialization process.
|
||||
@@ -1657,13 +1656,22 @@ auto registry<Policies...>::finalize(Options... opts) -> void {
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
//! Finalize the default registry
|
||||
inline auto finalize() -> void {
|
||||
BOOST_OPENMETHOD_DEFAULT_REGISTRY::finalize();
|
||||
}
|
||||
|
||||
namespace aliases {
|
||||
using boost::openmethod::initialize;
|
||||
//! Release resources held by registry.
|
||||
//!
|
||||
//! `finalize` may be called to release any resources allocated by
|
||||
//! @ref registry::initialize.
|
||||
//!
|
||||
//! @note
|
||||
//! A translation unit that contains a call to `finalize` must include the
|
||||
//! `<boost/openmethod/initialize.hpp>` header.
|
||||
//!
|
||||
//! @tparam Registry The registry to finalize.
|
||||
//! @tparam Options... Zero or more option types, deduced from the function
|
||||
//! arguments.
|
||||
//! @param options Zero or more option objects.
|
||||
template<class Registry = BOOST_OPENMETHOD_DEFAULT_REGISTRY, class... Options>
|
||||
inline auto finalize(Options&&... opts) -> void {
|
||||
Registry::finalize(std::forward<Options>(opts)...);
|
||||
}
|
||||
|
||||
} // namespace boost::openmethod
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -376,12 +376,19 @@ struct unspecified {};
|
||||
|
||||
//! Blueprint for a lightweight output stream (exposition only).
|
||||
//!
|
||||
//! Classes used as output streams in policies must provide the free functions
|
||||
//! described on this page.
|
||||
//! Classes used as output streams in policies must provide the operations
|
||||
//! described on this page, either as members or as free functions.
|
||||
struct LightweightOutputStream {
|
||||
//! Writes a null-terminated string to the stream.
|
||||
LightweightOutputStream& operator<<(const char* str);
|
||||
|
||||
//! Writes a string view to the stream.
|
||||
LightweightOutputStream& operator<<(const std::string_view& view);
|
||||
|
||||
//! Writes a pointer value to the stream.
|
||||
LightweightOutputStream& operator<<(const void* value);
|
||||
|
||||
//! Writes a size_t value to the stream.
|
||||
LightweightOutputStream& operator<<(std::size_t value);
|
||||
};
|
||||
|
||||
@@ -662,9 +669,9 @@ struct VptrFn {
|
||||
//!
|
||||
//! @tparam Options... Zero or more option types, deduced from the
|
||||
//! function arguments.
|
||||
//! @param options Zero or more option objects.
|
||||
//! @param options A tuple of option objects.
|
||||
template<class... Options>
|
||||
static auto finalize(std::tuple<Options...> opts) -> void;
|
||||
static auto finalize(const std::tuple<Options...>& options) -> void;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -704,17 +711,12 @@ template<class Registry>
|
||||
struct TypeHashFn {
|
||||
//! Initialize the hash table.
|
||||
//!
|
||||
//! @tparam ForwardIterator An iterator to a range of @ref
|
||||
//! InitializeClass objects.
|
||||
//! @tparam Options... Zero or more option types, deduced from the
|
||||
//! function arguments.
|
||||
//! @param first An iterator to the beginning of the range.
|
||||
//! @param last An iterator to the end of the range.
|
||||
//! @param options Zero or more option objects.
|
||||
//! @tparam Context A class that conforms to the @ref InitializeContext
|
||||
//! blueprint.
|
||||
//! @return A pair containing the minimum and maximum hash values.
|
||||
template<typename ForwardIterator>
|
||||
static auto initialize(ForwardIterator first, ForwardIterator last)
|
||||
-> std::pair<std::size_t, std::size_t>;
|
||||
template<class Context>
|
||||
static auto
|
||||
initialize(const Context& ctx) -> std::pair<std::size_t, std::size_t>;
|
||||
|
||||
//! Hash a `type_id`.
|
||||
//!
|
||||
@@ -726,10 +728,11 @@ struct TypeHashFn {
|
||||
//!
|
||||
//! This function is optional.
|
||||
//!
|
||||
//! @tparam Options... Zero or more option types, deduced from the function
|
||||
//! arguments.
|
||||
//! @param options Zero or more option objects.
|
||||
static auto finalize() -> void;
|
||||
//! @tparam Options... Zero or more option types, deduced from the
|
||||
//! function arguments.
|
||||
//! @param options A tuple of option objects.
|
||||
template<class... Options>
|
||||
static auto finalize(const std::tuple<Options...>& options) -> void;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -933,8 +936,6 @@ class registry : detail::registry_base {
|
||||
|
||||
template<class... Options>
|
||||
struct compiler;
|
||||
// template<class Registry, typename... Options>
|
||||
// friend compiler<Options...> initialize(Options...);
|
||||
|
||||
//! Check that the registry is initialized.
|
||||
//!
|
||||
@@ -946,16 +947,6 @@ class registry : detail::registry_base {
|
||||
//! @li @ref not_initialized: The registry is not initialized.
|
||||
static void require_initialized();
|
||||
|
||||
//! Releases the resources held by the registry.
|
||||
//!
|
||||
//! `finalize` may be called to release any resources allocated by
|
||||
//! @ref registry::initialize.
|
||||
//!
|
||||
//! @note
|
||||
//! A translation unit that contains a call to `finalize` must include the
|
||||
//! `<boost/openmethod/initialize.hpp>` header.
|
||||
//!
|
||||
//! @tparam Options A registry.
|
||||
template<class... Options>
|
||||
static void finalize(Options... opts);
|
||||
|
||||
|
||||
@@ -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,9 +7,9 @@
|
||||
"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": [
|
||||
"Programming"
|
||||
"Emulation", "Programming"
|
||||
],
|
||||
"cxxstd": "17"
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ BOOST_AUTO_TEST_CASE(simple) {
|
||||
if constexpr (std::is_same_v<test_registry::vptr, policies::vptr_vector>) {
|
||||
BOOST_TEST(
|
||||
!detail::vptr_vector_vptrs<test_registry::registry_type>.empty());
|
||||
test_registry::finalize();
|
||||
finalize<test_registry>();
|
||||
static_assert(detail::has_finalize_aux<
|
||||
void, test_registry::policy<policies::vptr>,
|
||||
std::tuple<>>::value);
|
||||
|
||||
@@ -186,11 +186,14 @@ namespace non_polymorphic {
|
||||
struct Animal {}; // polymorphic not required
|
||||
struct Dog : Animal {}; // polymorphic not required
|
||||
BOOST_OPENMETHOD_CLASSES(Animal, Dog);
|
||||
|
||||
// codecov:ignore:start
|
||||
BOOST_OPENMETHOD(poke, (virtual_ptr<Animal>), void);
|
||||
|
||||
void instiantiate_poke(virtual_ptr<Dog> snoopy) {
|
||||
void instantiate_poke(virtual_ptr<Dog> snoopy) {
|
||||
poke(snoopy);
|
||||
}
|
||||
// codecov:ignore:end
|
||||
|
||||
BOOST_AUTO_TEST_CASE(virtual_ptr_examples_non_polymorphic) {
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user