Skip to content

Commit 358f264

Browse files
committed
a few more macros, and put them all in one header
1 parent 650e4a7 commit 358f264

19 files changed

Lines changed: 201 additions & 105 deletions
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
## BOOST_OPENMETHOD_DECLARE_OVERRIDER
3+
4+
### Synopsis
5+
6+
Defined in <boost/openmethod/macros.hpp>.
7+
8+
```c++
9+
#define BOOST_OPENMETHOD_DECLARE_OVERRIDER(NAME, (PARAMETERS...), RETURN_TYPE)
10+
```
11+
12+
### Description
13+
14+
Declares an overrider for a method.
15+
16+
The method is deduced from a call to a method guide function with the
17+
overrider's arguments.
18+
19+
The macro creates several entities in the current scope.
20+
21+
* A class template that acts as a container for the overriders of the methods
22+
called `NAME`:
23+
24+
```c++
25+
template<typename...> BOOST_OPENMETHOD_OVERRIDERS(NAME);
26+
```
27+
28+
* A specialization of the container template for the overrider:
29+
30+
```c++
31+
struct BOOST_OPENMETHOD_OVERRIDERS(NAME)<RETURN_TYPE(PARAMETERS...)> {
32+
static auto fn(PARAMETERS...) -> RETURN_TYPE;
33+
static auto has_next() -> bool;
34+
template<typename... Args>
35+
static auto next(typename... Args) -> RETURN_TYPE;
36+
};
37+
```
38+
39+
where:
40+
41+
* `fn` is the overrider function.
42+
43+
* `has_next()` returns `true` if a less specialized overrider exists.
44+
45+
* `next(Args... args)` calls the next most specialized overrider via the
46+
pointer stored in the method's `next<fn>` member variable.
47+
48+
`BOOST_OPENMETHOD_DECLARE_OVERRIDER` can be called in a header file, with a
49+
semicolon after the call. It can be called in a header file, but not multiple
50+
times in the same translation unit.
51+
52+
NOTE: `NAME` must be an *identifier*. Qualified names are not allowed.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
## BOOST_OPENMETHOD_DEFINE_OVERRIDER
3+
4+
### Synopsis
5+
6+
Defined in <boost/openmethod/macros.hpp>.
7+
8+
```c++
9+
#define BOOST_OPENMETHOD_DEFINE_OVERRIDER(NAME, (PARAMETERS...), RETURN_TYPE)
10+
```
11+
12+
### Description
13+
14+
Defines the body of an overrider declared with
15+
`BOOST_OPENMETHOD_DECLARE_OVERRIDER`. It should be called in an implementation
16+
file, and followed by a function body.
17+
18+
NOTE: `NAME` must be an *identifier*. Qualified names are not allowed.

doc/BOOST_OPENMETHOD_GUIDE.adoc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
## BOOST_OPENMETHOD_GUIDE
3+
4+
### Synopsis
5+
6+
Defined in <boost/openmethod/macros.hpp>.
7+
8+
```c++
9+
#define BOOST_OPENMETHOD_GUIDE(NAME) /* unspecified */
10+
```
11+
12+
### Description
13+
14+
Expands to the name of the guide function used to match overriders to methods.

doc/BOOST_OPENMETHOD_NAME.adoc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55

66
### Synopsis
77

8-
Defined in <boost/openmethod/macros/name.hpp>.
8+
Defined in <boost/openmethod/macros.hpp>.
99

1010
```c++
11-
#define BOOST_OPENMETHOD_NAME(NAME) boost_openmethod_#NAME
11+
#define BOOST_OPENMETHOD_NAME(NAME) /* unspecified */
1212
```
1313
1414
### Description
1515
16-
Generate a long name from a short name, hopefully avoiding conflicts with
17-
user-defined names.
16+
Generates a long, obfuscated name from a short name. All the other names
17+
generated by macros are based on this name.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
## BOOST_OPENMETHOD_OVERRIDER
3+
4+
### Synopsis
5+
6+
Defined in <boost/openmethod/macros.hpp>.
7+
8+
```c++
9+
#define BOOST_OPENMETHOD_OVERRIDER(NAME, (PARAMETERS...), RETURN_TYPE)
10+
```
11+
12+
### Description
13+
14+
Expands to the specialization of the class template that contains the overrider
15+
for with the given name, parameter list and return type.

doc/BOOST_OPENMETHOD_REGISTER.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
### Synopsis
77

8-
Defined in <boost/openmethod/macros/register.hpp>.
8+
Defined in <boost/openmethod/macros.hpp>.
99

1010
```c++
1111
BOOST_OPENMETHOD_REGISTER(TYPE);

doc/headers.adoc

Lines changed: 0 additions & 37 deletions
This file was deleted.

doc/headers_namespaces.adoc

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ it is "called" only in a non-evaluated context.
2727
* It defines an inline function with the same name and signature as the
2828
method (with the `virtual_` decorators stripped).
2929
30-
Next, let's implement the `Cat` class, in the `felines` namespace:
30+
Next, let's implement the `Cat` class, and a derived class, `Chhetah`, in the
31+
`felines` namespace:
3132

3233
[source,c++]
3334
----
@@ -40,10 +41,10 @@ include::{examplesdir}/headers_namespaces/cat.cpp[]
4041
----
4142

4243
`BOOST_OPENMETHOD_CLASSES` should be placed in an implementation file. It can
43-
also go in a header file, but this wastes space, as multiple copies of the same
44-
class data will be created. It doesn't matter which namespace the macro is
45-
called in. It can take be used with any class name in scope, or with qualified
46-
names.
44+
also go in a header file, but this wastes space, as the same registrar will be
45+
created in every translation unit that includes the header. It doesn't matter
46+
which namespace the macro is called in. It can take be used with any class name
47+
in scope, or with qualified names.
4748

4849
`BOOST_OPENMETHOD_OVERRIDE` uses the guide function declared by
4950
`BOOST_OPENMETHOD` to locate a method that can be called with the same arguments
@@ -63,26 +64,47 @@ struct, it defines the `next` and `has_next` members, and a static function
6364
called `fn`. The block following the macro is the body of the `fn` function.
6465
6566
It follows that `BOOST_OPENMETHOD_OVERRIDE` should be placed in an
66-
implementation file.
67+
implementation file. `BOOST_OPENMETHOD_INLINE_OVERRIDE` works like
68+
`BOOST_OPENMETHOD_OVERRIDE`, but it defines the `fn` function as inline, so it
69+
can be used in a header file.
6770

68-
Let's implement the `Dog` class, in the `canines` namespace:
71+
The overrider for Cats can be accessed in the same translation unit, after it
72+
has been defined, using the `BOOST_OPENMETHOD_OVERRIDER` macro. It expands to
73+
the specialization of the overrider container for the overrider's signature. We
74+
call the static `fn` function to call the overrider.
6975

76+
NOTE: The Cheetah overrider calls the specific overrider for `Cat`, for
77+
illustration purpose. It is usually better to call `next` instead.
78+
79+
Let's implement the `Dog` class, in the `canines` namespace. This time we want
80+
the overrider to be accessible in other translation units. We can declare an
81+
overrider with `BOOST_OPENMETHOD_DECLARE_OVERRIDER`, without actually defining
82+
the static function `fn` just yet.
7083

7184
[source,c++]
7285
----
7386
include::{examplesdir}/headers_namespaces/dog.hpp[]
7487
----
7588

89+
Unlike function declarations, which can occur multiple times in a TU, an
90+
overrider declaration cannot. For example, this is illegal:
91+
92+
```c++
93+
BOOST_OPENMETHOD_DECLARE_OVERRIDER(
94+
poke, (std::ostream&, virtual_ptr<Dog>), void);
95+
96+
BOOST_OPENMETHOD_DECLARE_OVERRIDER(
97+
poke, (std::ostream&, virtual_ptr<Dog>), void);
98+
```
99+
100+
Now we use `BOOST_OPENMETHOD_DEFINE_OVERRIDER` to define the overrider:
101+
76102
[source,c++]
77103
----
78104
include::{examplesdir}/headers_namespaces/dog.cpp[]
79105
----
80106

81-
`BOOST_OPENMETHOD_INLINE_OVERRIDE` works like `BOOST_OPENMETHOD_OVERRIDE`, but
82-
it can be used in a header file, because it defines the `fn` function inline.
83-
84-
85-
Let's look at the main program now. It derived `Bullgod` from `Dog` and provides
107+
Let's look at the main program now. It derived `Bulldog` from `Dog` and provides
86108
an overrider for the new class:
87109

88110
[source,c++]
@@ -154,12 +176,12 @@ BOOST_OPENMETHOD_OVERRIDE(
154176
```
155177

156178
But `BOOST_OPENMETHOD_OVERRIDE` also uses the name to derive the overrider
157-
container's name, using preprocessor token pasting. And the result will be an
158-
invalid declaration.
179+
container's name, using preprocessor token pasting, resulting in an invalid
180+
declaration error.
159181

160-
All we need to do is to make `BOOST_OPENMETHOD_OVERRIDE` "see" the guide
161-
function. Its name is produced by macro `BOOST_OPENMETHOD_GUIDE(NAME)`. Thus we
162-
can use a using-declaration to bring the guide function into the current scope:
182+
We need to do is to make `BOOST_OPENMETHOD_OVERRIDE` "see" the guide function.
183+
Its name is returned by macro `BOOST_OPENMETHOD_GUIDE(NAME)`. We can use a
184+
using-declaration to bring the guide function into the current scope:
163185

164186
```c++
165187
using app_specific_behavior::BOOST_OPENMETHOD_GUIDE(meet);

doc/reference.adoc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ include::overview.adoc[]
99
include::BOOST_OPENMETHOD.adoc[]
1010
include::BOOST_OPENMETHOD_OVERRIDE.adoc[]
1111
include::BOOST_OPENMETHOD_INLINE_OVERRIDE.adoc[]
12+
include::BOOST_OPENMETHOD_DECLARE_OVERRIDER.adoc[]
13+
include::BOOST_OPENMETHOD_DEFINE_OVERRIDER.adoc[]
14+
include::BOOST_OPENMETHOD_OVERRIDER.adoc[]
15+
include::BOOST_OPENMETHOD_NAME.adoc[]
16+
include::BOOST_OPENMETHOD_GUIDE.adoc[]
17+
include::BOOST_OPENMETHOD_OVERRIDERS.adoc[]
1218
include::BOOST_OPENMETHOD_REGISTER.adoc[]
1319
include::BOOST_OPENMETHOD_CLASSES.adoc[]
1420
include::BOOST_OPENMETHOD_DEFAULT_POLICY.adoc[]
15-
include::BOOST_OPENMETHOD_NAME.adoc[]
16-
include::BOOST_OPENMETHOD_OVERRIDERS.adoc[]
17-
include::initialize.adoc[]
1821

22+
include::initialize.adoc[]
1923
include::typedefs.adoc[]
2024
include::method.adoc[]
2125
include::method_override.adoc[]
@@ -24,7 +28,6 @@ include::virtual_traits.adoc[]
2428
include::use_classes.adoc[]
2529
include::virtual_.adoc[]
2630
include::with_vptr.adoc[]
27-
2831
include::abstract_policy.adoc[]
2932
include::domain.adoc[]
3033
include::basic_policy.adoc[]

examples/core_api.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ using namespace boost::openmethod;
2222

2323
// tag::method[]
2424

25-
#include <boost/openmethod/macros/name.hpp>
25+
#include <boost/openmethod/macros.hpp>
2626

2727
class BOOST_OPENMETHOD_NAME(poke);
2828

@@ -39,7 +39,7 @@ static poke::override<poke_cat> override_poke_cat;
3939
// end::poke_cat[]
4040

4141
// tag::poke_dog[]
42-
#include <boost/openmethod/macros/register.hpp>
42+
#include <boost/openmethod/macros.hpp>
4343

4444
auto poke_dog(std::ostream& os, virtual_ptr<Dog> dog) {
4545
os << "bark";

0 commit comments

Comments
 (0)