@@ -43,10 +43,16 @@ properties of messages.
4343:m,n: An instance of **M**.
4444:S: A string type.
4545: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.
4650
4751+----------------------------+----------------------+-----------------------------------------+
4852| Construct | Result | Description |
4953+============================+======================+=========================================+
54+ | ``typename M::tag`` | T | The nested tag type. |
55+ +----------------------------+----------------------+-----------------------------------------+
5056| ``M()`` | Instance of M | Default constructible. |
5157+----------------------------+----------------------+-----------------------------------------+
5258| ``M(m)`` | Instance of M | Copy constructible. |
@@ -55,33 +61,34 @@ properties of messages.
5561+----------------------------+----------------------+-----------------------------------------+
5662| ``swap(m, n);`` | ``void`` | Swappable. |
5763+----------------------------+----------------------+-----------------------------------------+
58- | ``source(m);`` |unspecified | Retrieve the source of ``m``. |
64+ | ``source(m);`` |Convertible to O | Retrieve the source of ``m``. |
5965+----------------------------+----------------------+-----------------------------------------+
60- | ``destination(m);`` |unspecified | Retrieve the destination of ``m``. |
66+ | ``destination(m);`` |Convertible to D | Retrieve the destination of ``m``. |
6167+----------------------------+----------------------+-----------------------------------------+
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``. |
6469+----------------------------+----------------------+-----------------------------------------+
65- | ``body(m);`` |unspecified | Retrieve the body of ``m``. |
70+ | ``body(m);`` |Convertible to B | Retrieve the body of ``m``. |
6671+----------------------------+----------------------+-----------------------------------------+
6772| ``m << source(s);`` | ``M &`` | Set the source of ``m``. |
6873+----------------------------+----------------------+-----------------------------------------+
69- | ``source(m,s);`` | ``M &`` | Set the source of ``m``. |
70- +----------------------------+----------------------+-----------------------------------------+
7174| ``m << destination(s);`` | ``M &`` | Set the destination of ``m``. |
7275+----------------------------+----------------------+-----------------------------------------+
73- | ``destination(m,s);`` | ``M &`` | Set the destination of ``m``. |
74- +----------------------------+----------------------+-----------------------------------------+
7576| ``m << header(k, v);`` | ``M &`` | Add a header to ``m``. |
7677+----------------------------+----------------------+-----------------------------------------+
77- | ``add_header(m, k, v);`` | ``M &`` | Add a header to ``m``. |
78- +----------------------------+----------------------+-----------------------------------------+
7978| ``m << remove_header(k);`` | ``M &`` | Remove a header from ``m``. |
8079+----------------------------+----------------------+-----------------------------------------+
81- | ``remove_header(m, k);`` | ``M &`` | Remove a header from ``m``. |
82- +----------------------------+----------------------+-----------------------------------------+
8380| ``m << body(s);`` | ``M &`` | Set the body of ``m``. |
8481+----------------------------+----------------------+-----------------------------------------+
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+ +----------------------------+----------------------+-----------------------------------------+
8592| ``body(m,s);`` | ``M &`` | Set the body of ``m``. |
8693+----------------------------+----------------------+-----------------------------------------+
8794
@@ -93,6 +100,105 @@ Concept, a message can be implemented as a POD type and have all
93100manipulations performed in the directive implementations, as well as
94101value transformations done in the accessors.
95102
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+
96202``basic_message``
97203`````````````````
98204