Skip to content

Commit 5dd55f2

Browse files
committed
doc: mostly virtual_, some minor changes elsewhere
1 parent 838dc1d commit 5dd55f2

File tree

13 files changed

+624
-220
lines changed

13 files changed

+624
-220
lines changed

doc/modules/ROOT/examples/CMakeLists.txt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ message(STATUS "Building examples")
77

88
if (CMAKE_BUILD_TYPE STREQUAL "Release")
99
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
10-
add_compile_options(-save-temps -masm=intel)
10+
add_compile_options(-save-temps=obj -masm=intel)
1111
endif()
1212
endif()
1313

@@ -38,16 +38,24 @@ function(add_step_by_step dir)
3838
foreach (subdir ${subdirs})
3939
string(REGEX REPLACE ".*/" "" subex ${subdir})
4040
file(GLOB cpp_files "${subdir}/*.cpp")
41-
add_executable("${dir}_${subex}" ${cpp_files})
42-
target_link_libraries("${dir}_${subex}" PUBLIC Boost::openmethod)
41+
set(target "${dir}_${subex}")
42+
add_executable(${target} ${cpp_files})
43+
target_link_libraries(${target} PUBLIC Boost::openmethod)
44+
set(output_dir "${CMAKE_BINARY_DIR}/${subdir}")
45+
set_target_properties(${target} PROPERTIES
46+
RUNTIME_OUTPUT_DIRECTORY "${output_dir}"
47+
LIBRARY_OUTPUT_DIRECTORY "${output_dir}"
48+
ARCHIVE_OUTPUT_DIRECTORY "${output_dir}"
49+
)
4350
if(${add_test})
44-
add_test(NAME "${dir}_${subex}" COMMAND "${dir}_${subex}")
51+
add_test(NAME "${target}" COMMAND "${target}")
4552
endif()
46-
add_dependencies(tests "${dir}_${subex}")
53+
add_dependencies(tests "${target}")
4754
endforeach()
4855
endfunction()
4956

5057
add_step_by_step(core_api)
58+
add_step_by_step(virtual_ptr_alt)
5159
add_step_by_step(rolex)
5260
add_step_by_step(ambiguities OFF)
5361

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) 2018-2025 Jean-Louis Leroy
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// See accompanying file LICENSE_1_0.txt
4+
// or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#include <iostream>
7+
8+
// tag::content[]
9+
struct Node {
10+
virtual int value() const = 0;
11+
};
12+
13+
struct Variable : Node {
14+
Variable(int value) : v(value) {}
15+
int value() const override { return v; }
16+
int v;
17+
};
18+
19+
struct Plus : Node {
20+
Plus(const Node& left, const Node& right) : left(left), right(right) {}
21+
int value() const override { return left.value() + right.value(); }
22+
const Node& left; const Node& right;
23+
};
24+
25+
struct Times : Node {
26+
Times(const Node& left, const Node& right) : left(left), right(right) {}
27+
int value() const override { return left.value() * right.value(); }
28+
const Node& left; const Node& right;
29+
};
30+
31+
// tag::content[]
32+
#include <boost/openmethod.hpp>
33+
#include <boost/openmethod/initialize.hpp>
34+
35+
using boost::openmethod::virtual_;
36+
37+
BOOST_OPENMETHOD(postfix, (virtual_<const Node&> node, std::ostream& os), void);
38+
39+
BOOST_OPENMETHOD_OVERRIDE(
40+
postfix, (const Variable& var, std::ostream& os), void) {
41+
os << var.v;
42+
}
43+
44+
BOOST_OPENMETHOD_OVERRIDE(
45+
postfix, (const Plus& plus, std::ostream& os), void) {
46+
postfix(plus.left, os);
47+
os << ' ';
48+
postfix(plus.right, os);
49+
os << " +";
50+
}
51+
52+
BOOST_OPENMETHOD_OVERRIDE(
53+
postfix, (const Times& times, std::ostream& os), void) {
54+
postfix(times.left, os);
55+
os << ' ';
56+
postfix(times.right, os);
57+
os << " *";
58+
}
59+
60+
BOOST_OPENMETHOD_CLASSES(Node, Variable, Plus, Times);
61+
62+
auto main() -> int {
63+
boost::openmethod::initialize();
64+
Variable a{2}, b{3}, c{4};
65+
Plus d{a, b};
66+
Times e{d, c};
67+
postfix(e, std::cout);
68+
std::cout << " = " << e.value() << "\n"; // 2 3 + 4 * = 20
69+
}
70+
// end::content[]
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright (c) 2018-2025 Jean-Louis Leroy
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// See accompanying file LICENSE_1_0.txt
4+
// or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#include <iostream>
7+
#include <boost/openmethod.hpp>
8+
9+
// tag::content[]
10+
struct Node {
11+
boost::openmethod::vptr_type vptr;
12+
using registry = boost::openmethod::default_registry; // short alias
13+
14+
friend auto boost_openmethod_vptr(const Node& node, registry*) {
15+
return node.vptr;
16+
}
17+
18+
Node() {
19+
vptr = registry::static_vptr<Node>;
20+
}
21+
};
22+
23+
struct Variable : Node {
24+
Variable(int value) : v(value) {
25+
vptr = boost::openmethod::default_registry::static_vptr<Variable>;
26+
}
27+
28+
int v;
29+
};
30+
31+
struct Plus : Node {
32+
Plus(const Node& left, const Node& right) : left(left), right(right) {
33+
vptr = boost::openmethod::default_registry::static_vptr<Plus>;
34+
}
35+
36+
const Node& left;
37+
const Node& right;
38+
};
39+
40+
struct Times : Node {
41+
Times(const Node& left, const Node& right) : left(left), right(right) {
42+
vptr = boost::openmethod::default_registry::static_vptr<Times>;
43+
}
44+
45+
const Node& left;
46+
const Node& right;
47+
};
48+
49+
#include <boost/openmethod/initialize.hpp>
50+
51+
using boost::openmethod::virtual_;
52+
53+
BOOST_OPENMETHOD(value, (virtual_<const Node&> node), int);
54+
55+
BOOST_OPENMETHOD_OVERRIDE(value, (const Variable& var), int) {
56+
return var.v;
57+
}
58+
59+
BOOST_OPENMETHOD_OVERRIDE(value, (const Plus& plus), int) {
60+
return value(plus.left) + value(plus.right);
61+
}
62+
63+
BOOST_OPENMETHOD_OVERRIDE(value, (const Times& times), int) {
64+
return value(times.left) * value(times.right);
65+
}
66+
67+
BOOST_OPENMETHOD_CLASSES(Node, Variable, Plus, Times);
68+
69+
auto main() -> int {
70+
boost::openmethod::initialize();
71+
Variable a{2}, b{3}, c{4};
72+
Plus d{a, b};
73+
Times e{d, c};
74+
std::cout << value(e) << "\n"; // 20
75+
}
76+
// end::content[]
77+
78+
// tag::call_value[]
79+
int call_value(const Node& node) {
80+
return value(node);
81+
}
82+
// end::call_value[]
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) 2018-2025 Jean-Louis Leroy
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// See accompanying file LICENSE_1_0.txt
4+
// or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#include <iostream>
7+
#include <boost/openmethod.hpp>
8+
#include <boost/openmethod/inplace_vptr.hpp>
9+
10+
// tag::content[]
11+
struct Node : boost::openmethod::inplace_vptr_base<Node> {
12+
};
13+
14+
struct Variable : Node, boost::openmethod::inplace_vptr_derived<Variable, Node> {
15+
Variable(int value) : v(value) {}
16+
17+
int v;
18+
};
19+
20+
struct Plus : Node, boost::openmethod::inplace_vptr_derived<Plus, Node> {
21+
Plus(const Node& left, const Node& right) : left(left), right(right) {}
22+
23+
const Node& left;
24+
const Node& right;
25+
};
26+
27+
struct Times : Node, boost::openmethod::inplace_vptr_derived<Times, Node> {
28+
Times(const Node& left, const Node& right) : left(left), right(right) {}
29+
30+
const Node& left;
31+
const Node& right;
32+
};
33+
// end::content[]
34+
35+
#include <boost/openmethod/initialize.hpp>
36+
37+
using boost::openmethod::virtual_;
38+
39+
BOOST_OPENMETHOD(value, (virtual_<const Node&> node), int);
40+
41+
BOOST_OPENMETHOD_OVERRIDE(value, (const Variable& var), int) {
42+
return var.v;
43+
}
44+
45+
BOOST_OPENMETHOD_OVERRIDE(value, (const Plus& plus), int) {
46+
return value(plus.left) + value(plus.right);
47+
}
48+
49+
BOOST_OPENMETHOD_OVERRIDE(value, (const Times& times), int) {
50+
return value(times.left) * value(times.right);
51+
}
52+
53+
auto main() -> int {
54+
boost::openmethod::initialize();
55+
Variable a{2}, b{3}, c{4};
56+
Plus d{a, b};
57+
Times e{d, c};
58+
std::cout << value(e) << "\n"; // 20
59+
}
60+
61+
// tag::call_value[]
62+
int call_value(const Node& node) {
63+
return value(node);
64+
}
65+
// end::call_value[]

doc/modules/ROOT/nav.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
* xref:multiple_dispatch.adoc[Multiple Dispatch]
99
* Advanced Features
1010
** xref:core_api.adoc[Core API]
11+
** xref:registries_and_policies.adoc[Registries and Policies]
1112
** xref:virtual_ptr_alt.adoc[Virtual Pointer Alternatives]
12-
** xref:policies.adoc[Registries and Policies]
1313
** xref:error_handling.adoc[Error Handling]
1414
** xref:custom_rtti.adoc[Custom RTTI]
1515
** xref:shared_libraries.adoc[Shared Libraries]

doc/modules/ROOT/pages/basics.adoc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ BOOST_OPENMETHOD_OVERRIDE(postfix, (virtual_ptr<const Variable> var, std::ostrea
4242
}
4343
```
4444
45-
The overrider must have virtual parameters in the same position as in the
46-
method, and they must point to an object of the same class as in the method, or
47-
a class derived from it. The other parameters must have the same types as in the
48-
method.
45+
The overrider must have virtual parameters in the same positions as in the
46+
method. The classes in the method's virtual parameters must be accessible,
47+
non-ambiguous bases of the classes in the overrider. Note that this rules out
48+
repeated inheritance. Apart from this restriction, multiple and virtual
49+
inheritance are supported.
50+
51+
The non-virtual parameters must have exactly the same types as in the method.
4952
5053
Let's look at another overrider:
5154

doc/modules/ROOT/pages/core_api.adoc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ The class needs not be defined, only declared.
3131
Inventing identifier class names can get tedious, so OpenMethod provides a macro
3232
for that: xref:BOOST_OPENMETHOD_ID.adoc[BOOST_OPENMETHOD_ID]. Let's use it:
3333

34-
3534
[source,c++]
3635
----
3736
include::{example}/core_api.cpp[tag=method]

doc/modules/ROOT/pages/performance.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ A method call compiles to:
8989

9090
[source,asm]
9191
----
92-
mov rax, qword ptr [rip + fn+88]
92+
mov rax, qword ptr [rip + postfix::fn+88]
9393
mov rax, qword ptr [rdi + 8*rax]
9494
jmp rax # TAILCALL
9595
----
File renamed without changes.

doc/modules/ROOT/pages/shared_libraries.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ across modules.
114114

115115
`initialize` rebuilds the v-tables in the registry. This invalidates all the
116116
`virtual_ptr`{empty}'s, and also the v-table pointers stored in objects by
117-
cpp:inplace_vptr[], related to that registry. This is seldom an issue, as most
118-
programs that dynamically load shared libraries do so at the very beginning of
119-
their execution.
117+
cpp:inplace_vptr_base[], related to that registry. This is seldom an issue, as
118+
most programs that dynamically load shared libraries do so at the very beginning
119+
of their execution.
120120
121121
Otherwise, indirect v-table pointers must be used. This is achieved by using a
122122
registry that contains the cpp:indirect_vptr[] policy.

0 commit comments

Comments
 (0)