@@ -43,10 +43,16 @@ properties of messages.
43
43
:m,n: An instance of **M**.
44
44
:S: A string type.
45
45
:s,k,v: An instance of **S**.
46
+ :O: The source type.
47
+ :D: The destination type.
48
+ :B: The body type.
49
+ :T: The Tag type.
46
50
47
51
+----------------------------+----------------------+-----------------------------------------+
48
52
| Construct | Result | Description |
49
53
+============================+======================+=========================================+
54
+ | ``typename M::tag`` | T | The nested tag type. |
55
+ +----------------------------+----------------------+-----------------------------------------+
50
56
| ``M()`` | Instance of M | Default constructible. |
51
57
+----------------------------+----------------------+-----------------------------------------+
52
58
| ``M(m)`` | Instance of M | Copy constructible. |
@@ -55,33 +61,34 @@ properties of messages.
55
61
+----------------------------+----------------------+-----------------------------------------+
56
62
| ``swap(m, n);`` | ``void`` | Swappable. |
57
63
+----------------------------+----------------------+-----------------------------------------+
58
- | ``source(m);`` | unspecified | Retrieve the source of ``m``. |
64
+ | ``source(m);`` | Convertible to O | Retrieve the source of ``m``. |
59
65
+----------------------------+----------------------+-----------------------------------------+
60
- | ``destination(m);`` | unspecified | Retrieve the destination of ``m``. |
66
+ | ``destination(m);`` | Convertible to D | Retrieve the destination of ``m``. |
61
67
+----------------------------+----------------------+-----------------------------------------+
62
- | ``headers(m);`` | unspecified | Get the range of headers of ``m``. The |
63
- | | | result should be convertible to ``H`` |
68
+ | ``headers(m);`` | Convertible to H | Retrieve the headers of ``m``. |
64
69
+----------------------------+----------------------+-----------------------------------------+
65
- | ``body(m);`` | unspecified | Retrieve the body of ``m``. |
70
+ | ``body(m);`` | Convertible to B | Retrieve the body of ``m``. |
66
71
+----------------------------+----------------------+-----------------------------------------+
67
72
| ``m << source(s);`` | ``M &`` | Set the source of ``m``. |
68
73
+----------------------------+----------------------+-----------------------------------------+
69
- | ``source(m,s);`` | ``M &`` | Set the source of ``m``. |
70
- +----------------------------+----------------------+-----------------------------------------+
71
74
| ``m << destination(s);`` | ``M &`` | Set the destination of ``m``. |
72
75
+----------------------------+----------------------+-----------------------------------------+
73
- | ``destination(m,s);`` | ``M &`` | Set the destination of ``m``. |
74
- +----------------------------+----------------------+-----------------------------------------+
75
76
| ``m << header(k, v);`` | ``M &`` | Add a header to ``m``. |
76
77
+----------------------------+----------------------+-----------------------------------------+
77
- | ``add_header(m, k, v);`` | ``M &`` | Add a header to ``m``. |
78
- +----------------------------+----------------------+-----------------------------------------+
79
78
| ``m << remove_header(k);`` | ``M &`` | Remove a header from ``m``. |
80
79
+----------------------------+----------------------+-----------------------------------------+
81
- | ``remove_header(m, k);`` | ``M &`` | Remove a header from ``m``. |
82
- +----------------------------+----------------------+-----------------------------------------+
83
80
| ``m << body(s);`` | ``M &`` | Set the body of ``m``. |
84
81
+----------------------------+----------------------+-----------------------------------------+
82
+ | ``source(m,s);`` | ``void`` | Set the source of ``m``. |
83
+ +----------------------------+----------------------+-----------------------------------------+
84
+ | ``destination(m,s);`` | ``void`` | Set the destination of ``m``. |
85
+ +----------------------------+----------------------+-----------------------------------------+
86
+ | ``add_header(m, k, v);`` | ``void`` | Add a header to ``m``. |
87
+ +----------------------------+----------------------+-----------------------------------------+
88
+ | ``remove_header(m, k);`` | ``void`` | Remove a header from ``m``. |
89
+ +----------------------------+----------------------+-----------------------------------------+
90
+ | ``clear_headers(m);`` | ``void`` | Clear the headers of ``m``. |
91
+ +----------------------------+----------------------+-----------------------------------------+
85
92
| ``body(m,s);`` | ``M &`` | Set the body of ``m``. |
86
93
+----------------------------+----------------------+-----------------------------------------+
87
94
@@ -93,6 +100,105 @@ Concept, a message can be implemented as a POD type and have all
93
100
manipulations performed in the directive implementations, as well as
94
101
value transformations done in the accessors.
95
102
103
+ Directives, Modifiers, and Wrappers
104
+ ```````````````````````````````````
105
+
106
+ In the Message Concept definition there are three basic constructs that follow a
107
+ certain pattern. These patterns are Directives_, Modifiers_, and Wrappers_.
108
+
109
+ Directives
110
+ ~~~~~~~~~~
111
+
112
+ A directive is a function object that is applied to a Message. Directives
113
+ encapsulate a set of operations that apply to messages. The general requirement
114
+ for a Directive is that it should apply these operations on a message.
115
+
116
+ A directive may dispatch on the type of the message passed to it at the point of
117
+ the function call. Typically, directives are generated using a factory function
118
+ that returns the correct directive type.
119
+
120
+ For a given directive ``foo_directive`` a generator function called ``foo`` is
121
+ typically implemented:
122
+
123
+ .. code-block:: c++
124
+
125
+ struct foo_directive {
126
+ template <class Message>
127
+ Message & operator()(Message & m) const {
128
+ // do something to m
129
+ return m;
130
+ }
131
+ };
132
+
133
+ foo_directive const foo() {
134
+ return foo_directive();
135
+ }
136
+
137
+ // to apply a directive, we use the << operator
138
+ message m;
139
+ m << foo();
140
+
141
+ Modifiers
142
+ ~~~~~~~~~
143
+
144
+ A modifier is generally defined as a free function that takes a reference to a
145
+ non-const lvalue message as the first parameter, and any number of parameters.
146
+ In the concept definition of the Message Concept, a modifier follows the form:
147
+
148
+ .. code-block:: c++
149
+
150
+ modifier(message, ...)
151
+
152
+ Modifiers are meant to imply modifications on a message, which also allows for
153
+ easier dispatch based on Argument Dependent Lookup (ADL_) on the type of the
154
+ message. Note that Directives_ can be implemented in terms of Modifiers and
155
+ vice versa, although that is not required nor specified.
156
+
157
+ .. _ADL: http://en.wikipedia.org/wiki/Argument-dependent_name_lookup
158
+
159
+ Wrappers
160
+ ~~~~~~~~
161
+
162
+ A Wrapper is basically an implementation detail that ensures that a given
163
+ message, when wrapped, can be converted to the associated part of the message. A
164
+ wrapper has a type that encapsulates the conversion logic from a message to a
165
+ given type.
166
+
167
+ An example of a Wrapper would be ``source_wrapper`` which would be returned by a
168
+ call to the wrapper generator function ``source``. An example implementation of
169
+ the ``source_wrapper`` would look like:
170
+
171
+ .. code-block:: c++
172
+
173
+ template <class Tag, template <class> class Message>
174
+ struct source_wrapper {
175
+ Message<Tag> const & m;
176
+ explicit source_wrapper(Message<Tag> const & m)
177
+ : m(m) {}
178
+ typedef typename source<Tag>::type source_type;
179
+ operator source_type const & () {
180
+ return m.source;
181
+ }
182
+ operator source_type const () {
183
+ return m.source;
184
+ }
185
+ operator source_type () {
186
+ return m.source;
187
+ }
188
+ };
189
+
190
+ template <class Tag, template <class> class Message>
191
+ source_wrapper<Tag, Message> const
192
+ source(Message<Tag> const & message) {
193
+ return source_wrapper<Tag, Message>(message);
194
+ }
195
+
196
+ This pattern is similar to an adapter, but the specific notion of wrapping a
197
+ data type (in this case, an object of a type that models the Message Concept)
198
+ using an intermediary wrapper is what is pertained to by the Wrapper pattern.
199
+ In this case, the Wrapper is ``source_wrapper`` while ``source`` is merely a
200
+ wrapper generator function.
201
+
96
202
``basic_message``
97
203
`````````````````
98
204
0 commit comments