File: classes.adoc

package info (click to toggle)
boost1.88 1.88.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 576,932 kB
  • sloc: cpp: 4,149,234; xml: 136,789; ansic: 35,092; python: 33,910; asm: 5,698; sh: 4,604; ada: 1,681; makefile: 1,633; pascal: 1,139; perl: 1,124; sql: 640; yacc: 478; ruby: 271; java: 77; lisp: 24; csh: 6
file content (189 lines) | stat: -rw-r--r-- 5,312 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
////
Copyright 2020, 2021 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////

[#classes]
# Describing Class Types
:idprefix: classes_

## Class Types with Public Members

If you have a `struct`

```
struct X
{
    int m1;
    int m2;
};
```

use the `BOOST_DESCRIBE_STRUCT` macro to describe it:

```
BOOST_DESCRIBE_STRUCT(X, (), (m1, m2))
```

`BOOST_DESCRIBE_STRUCT` is defined in `<boost/describe/class.hpp>` and should
be placed in the same namespace as the `struct`.

It takes three arguments: the `struct` name, a list of base classes
(empty in our example), and a list of (public) members by name (this includes
both data members and member functions.)

Since `BOOST_DESCRIBE_STRUCT` is placed outside the type, it's non-intrisive,
does not require access to the definition, and can therefore be used to describe
third-party types or types defined in system headers.

## Class Types with Protected or Private Members

To describe a class type, use the `BOOST_DESCRIBE_CLASS` macro instead, placing
it _inside the class_. This gives the macro access to the protected and private
members, but is intrusive and requires access to the definition.

```
class Y: private X
{
public:

    int m3;

protected:

    int m4;

private:

    int m5;

public:

    int f() const;

private:

    BOOST_DESCRIBE_CLASS(Y, (X), (m3, f), (m4), (m5))
};
```

It takes three member lists, for the public, protected, and private members.

## Retrieving Class Properties

Once a type `T` is annotated, its properties can be retrieved via
`describe_bases<T, M>` and `describe_members<T, M>` (`M` is a bitmask of
modifiers such as `mod_public | mod_static | mod_function`).

These primitives are defined in namespace `boost::describe`, in the headers
`<boost/describe/bases.hpp>` and `<boost/describe/members.hpp>`, respectively.

`describe_bases` takes the following possible modifiers: `mod_public`,
`mod_protected`, `mod_private`, or a bitwise-or combination of them. The
presence of `mod_public` includes the public bases in the result, its absence
excludes them. The other two modifiers work similarly.

`describe_members` takes a bitwise-or combination of the following possible
modifiers: `mod_public`, `mod_protected`, `mod_private`, `mod_static`,
`mod_function`, `mod_any_member`, `mod_inherited`, `mod_hidden`.

The access modifiers work the same as with `describe_bases`.

(For types annotated with `BOOST_DESCRIBE_STRUCT`, the protected and private
member lists will be empty.)

When `mod_static` is present, the static members are returned, otherwise
the nonstatic members are returned.

When `mod_function` is present, the member functions are returned, otherwise
the data members are returned.

When `mod_any_member` is present, `mod_static` and `mod_function` are ignored
and all members are returned regardless of kind.

When `mod_inherited` is present, members of base classes are also returned.

When `mod_hidden` is present, hidden inherited members are included. A member
of a base class is hidden when a derived class has a member of the same name.

For the above class `Y`, `describe_bases<Y, mod_any_access>` will return a
type list `L<D1>` containing a single base descriptor `D1` describing `X`:

```
struct D1
{
    using type = X;
    static constexpr unsigned modifiers = mod_private;
};
```

`describe_members<Y, mod_private>` will return a type list `L<D2>` containing
the descriptor of the data member `Y::m5`:

```
struct D2
{
    static constexpr int Y::* pointer = &Y::m5;
    static constexpr char const * name = "m5";
    static constexpr unsigned modifiers = mod_private;
};
```

For an example of how to use the base and data member descriptors, see
<<example_print_function>>.

For an example of how to use member function descriptors, see
<<example_json_rpc>>.

## Overloaded Member Functions

To describe an overloaded member function, you will need to resort to
a more complicated syntax, as simply listing its name (say, `f`) will make
the library attempt to form a member pointer with `&X::f`, which would fail
because it's not clear to which `f` this expression refers.

To disambiguate, precede the function name with the type of the function, in
parentheses, as shown in the following example:

```
struct X
{
    int f();
    int f() const;
    void f( int x );
};

BOOST_DESCRIBE_STRUCT(X, (), (
    (int ()) f,
    (int () const) f,
    (void (int)) f
))
```

The type of the function is the same as its declaration, without the name.

Be sure to retain the space between the parenthesized function type and its name,
because omitting it will compile happily on GCC and Clang but will lead to
inscrutable errors on MSVC due to its nonstandard preprocessor.

Pay attention to the proper placement of the parentheses, because a mistake there
will also lead to hard to decipher compiler errors, on all compilers.

The same technique also works with `BOOST_DESCRIBE_CLASS`, and with static member
functions:

```
class Y
{
public:

    static void f( int x );
    static void f( int x, int y );

    BOOST_DESCRIBE_CLASS(Y, (), ((void (int)) f, (void (int, int)) f), (), ())
};
```

The case where a member function and a static member function have the same name
and the same function type is currently not supported.