Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3b89b67

Browse files
committed
Removing Boost.Variant from Directives
This commit removes the reliance on Boost.Variant, and turns directivesinto SFINAE aware directives based on the tag of the message. Basically,what we want to happen is for code like the following to fail tocompile: basic_message<default_string> m; std::wstring w; m << source(w);The reason it should fail to compile is because the default_string tagtells basic_message to encapsulate std::string, not std::wstring objectsfor the source. Previously, with the Boost.Variant solution this codewould compile and is therefore a serious bug.
1 parent1ba8079 commit3b89b67

File tree

2 files changed

+37
-123
lines changed

2 files changed

+37
-123
lines changed

‎boost/network/message/directives.hpp‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
#ifndef __NETWORK_MESSAGE_DIRECTIVES_HPP__
88
#define__NETWORK_MESSAGE_DIRECTIVES_HPP__
99

10-
/** Include all the various directive headers.
11-
*/
12-
1310
#include<boost/network/message/directives/detail/string_directive.hpp>
1411
#include<boost/network/message/directives/header.hpp>
1512
#include<boost/network/message/directives/remove_header.hpp>

‎boost/network/message/directives/detail/string_directive.hpp‎

Lines changed: 37 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -10,134 +10,51 @@
1010
#include<boost/variant/variant.hpp>
1111
#include<boost/variant/apply_visitor.hpp>
1212
#include<boost/variant/static_visitor.hpp>
13+
#include<boost/network/support/is_pod.hpp>
14+
#include<boost/utility/enable_if.hpp>
1315
#include<boost/mpl/if.hpp>
1416
#include<boost/mpl/or.hpp>
15-
#include<boost/network/message/directives/detail/string_value.hpp>
1617

17-
namespaceboost {namespacenetwork {namespacedetail {
18-
19-
/** This directive template technically implements a decorator pattern
20-
* which takes a concrete implementation and uses that as a base. This
21-
* particular directive template requires the Base type to just include
22-
* a nested template named `string_visitor` that takes a single template
23-
* class parameter which is supposed to be a Message class/struct.
24-
*
25-
* A typical directive implementation of the visitor will take a reference
26-
* to a message as the constructor parameter and then performs operations
27-
* on that message.
28-
*
29-
* To create your own string directive, you can use the preprocessor macro
30-
* BOOST_NETWORK_STRING_DIRECTIVE which takes three parameters: the name of
31-
* the directive, a name for the variable to use in the directive visitor,
32-
* and the body to be implemented in the visitor. An example directive for
33-
* setting the source of a message would look something like this given the
34-
* BOOST_NETWORK_STRING_DIRECTIVE macro:
35-
*
36-
* BOOST_NETWORK_STRING_DIRECTIVE(source, source_,
37-
* message.source(source_)
38-
* , message.source=source_);
39-
*
40-
*/
41-
template<classBase>
42-
structstring_directive :publicBase {
43-
boost::variant<
44-
string<tags::default_string>::type,
45-
string<tags::default_wstring>::type,
46-
boost::shared_future<string<tags::default_string>::type>,
47-
boost::shared_future<string<tags::default_wstring>::type>
48-
> string_;
49-
50-
explicitstring_directive(string<tags::default_string>::typeconst & input)
51-
: string_(input) {}
52-
explicitstring_directive(string<tags::default_wstring>::typeconst & input)
53-
: string_(input) {}
54-
explicitstring_directive(boost::shared_future<string<tags::default_string>::type>const & input)
55-
: string_(input) {}
56-
explicitstring_directive(boost::shared_future<string<tags::default_wstring>::type>const & input)
57-
: string_(input) {}
58-
59-
string_directive(string_directiveconst & other)
60-
: string_(other.string_) {}
61-
62-
template<classTag,template<class>classMessage>
63-
voidoperator()(Message<Tag>const & message)const {
64-
apply_visitor(typename Base::template string_visitor<Message<Tag> >(message), string_);
65-
}
66-
};
18+
/**
19+
*
20+
* To create your own string directive, you can use the preprocessor macro
21+
* BOOST_NETWORK_STRING_DIRECTIVE which takes three parameters: the name of
22+
* the directive, a name for the variable to use in the directive visitor,
23+
* and the body to be implemented in the visitor. An example directive for
24+
* setting the source of a message would look something like this given the
25+
* BOOST_NETWORK_STRING_DIRECTIVE macro:
26+
*
27+
* BOOST_NETWORK_STRING_DIRECTIVE(source, source_,
28+
* message.source(source_)
29+
* , message.source=source_);
30+
*
31+
*/
6732

33+
#ifndef BOOST_NETWORK_STRING_DIRECTIVE
6834
#defineBOOST_NETWORK_STRING_DIRECTIVE(name, value, body, pod_body) \
69-
structname##_directive_base { \
70-
\
71-
template<classMessage> \
72-
structnormal_visitor : boost::static_visitor<> { \
73-
Messageconst & message; \
74-
explicitnormal_visitor(Messageconst & message) : \
75-
message(message) {} \
76-
voidoperator()( \
77-
typename boost::network::detail::string_value< \
78-
typename Message::tag \
79-
>::typeconst & value \
80-
)const { \
81-
body; \
82-
} \
83-
template<classT>voidoperator()(Tconst &)const { \
84-
} \
85-
}; \
86-
\
87-
template<classMessage> \
88-
structpod_visitor : boost::static_visitor<> { \
89-
Messageconst & message; \
90-
explicitpod_visitor(Messageconst & message) : \
91-
message(message) {} \
92-
voidoperator()( \
93-
typename boost::network::detail::string_value< \
94-
typename Message::tag \
95-
>::typeconst & value \
96-
) { \
97-
pod_body; \
98-
} \
99-
template<classT>voidoperator()(Tconst &)const { \
100-
} \
101-
}; \
102-
\
103-
template<classMessage> \
104-
structstring_visitor : \
105-
mpl::if_< \
106-
is_base_of< \
107-
tags::pod, \
108-
typename Message::tag \
109-
>, \
110-
pod_visitor<Message>, \
111-
normal_visitor<Message> \
112-
>::type \
113-
{ \
114-
typedeftypename mpl::if_< \
115-
is_base_of< \
116-
tags::pod, \
117-
typename Message::tag \
118-
>, \
119-
pod_visitor<Message>, \
120-
normal_visitor<Message> \
121-
>::type base; \
122-
explicitstring_visitor(Messageconst & message): \
123-
base(message) {} \
124-
string_visitor(string_visitorconst & other): \
125-
base(other) {} \
126-
usingbase::operator(); \
127-
}; \
35+
template<classValueType> \
36+
structname##_directive { \
37+
ValueTypeconst & value; \
38+
explicit name##_directive(ValueTypeconst & value_) \
39+
: value(value_) {} \
40+
name##_directive(name##_directiveconst & other) \
41+
: value(other.value) {} \
42+
template<classTag,template<class>classMessage> \
43+
typename enable_if<is_pod<Tag>,void>::type \
44+
operator()(Message<Tag> & message)const { \
45+
pod_body; \
46+
} \
47+
template<classTag,template<class>classMessage> \
48+
typename enable_if<mpl::not_<is_pod<Tag> >,void>::type \
49+
operator()(Message<Tag> & message)const { \
50+
body; \
51+
} \
12852
}; \
12953
\
130-
typedef boost::network::detail::string_directive<name##_directive_base> \
131-
name##_directive; \
132-
template<classT>inline name##_directiveconst \
54+
template<classT>inline name##_directive<T> \
13355
name (Tconst & input) { \
134-
return name##_directive(input); \
56+
return name##_directive<T>(input); \
13557
}
136-
137-
}/* detail*/
138-
139-
}/* network*/
140-
141-
}/* boost*/
58+
#endif/* BOOST_NETWORK_STRING_DIRECTIVE*/
14259

14360
#endif/* BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_DIRECTIVE_HPP_20100915*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp