#include <stdint.h>
#include <string>
#include <iostream>
#include <boost/variant.hpp>
using namespace std;
class WorkerMessageBase
{
public:
typedef enum
{
INIT_REQ = 1,
LOGIN_REQ,
CLOSE_REQ,
} MessageType;
WorkerMessageBase();
virtual ~WorkerMessageBase();
inline const MessageType getMessageType(void) const
{
return m_msg_type;
}
protected:
MessageType m_msg_type;
};
WorkerMessageBase::WorkerMessageBase(){}
WorkerMessageBase::~WorkerMessageBase(){}
class InitReq : public WorkerMessageBase
{
public:
InitReq()
{
m_msg_type = InitReq::INIT_REQ;
}
protected:
uint32_t m_current_time;
};
class LoginReq : public WorkerMessageBase
{
public:
LoginReq()
{
m_msg_type = LoginReq::LOGIN_REQ;
}
protected:
bool m_authenticate;
string m_login;
string m_password;
};
class CloseReq : public WorkerMessageBase
{
public:
CloseReq()
{
m_msg_type = CloseReq::CLOSE_REQ;
}
protected:
uint32_t m_timeout;
};
typedef boost::variant<
InitReq,
LoginReq,
CloseReq
> WorkerMessage;
typedef struct
{
uint32_t header;
WorkerMessage msg;
} message_t;
class Extractor : public boost::static_visitor<WorkerMessageBase *>
{
public:
WorkerMessageBase * operator()(InitReq & req) const {return &req;}
WorkerMessageBase * operator()(LoginReq & req) const {return &req;}
WorkerMessageBase * operator()(CloseReq & req) const {return &req;}
};
void handler(Extractor & extractor, message_t *ptr)
{
WorkerMessageBase *msg_p;
msg_p = boost::apply_visitor(extractor, ptr->msg);
cout << "Handler received msg type: " << msg_p->getMessageType() << endl;
}
int main()
{
InitReq init_req;
LoginReq login_req;
CloseReq close_req;
message_t m;
Extractor extractor;
m.msg = init_req;
handler(extractor, &m);
m.msg = login_req;
handler(extractor, &m);
m.msg = close_req;
handler(extractor, &m);
return 0;
}
Sunday, May 13, 2012
Boost::Variant as a union-like container for thread messages
How Boost::Variant can be used to carry messages to a thread:
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment