00001 #ifndef QPID_AMQP_0_10_HOLDER_H
00002 #define QPID_AMQP_0_10_HOLDER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qpid/framing/Blob.h"
00025 #include "apply.h"
00026
00027 namespace qpid {
00028 namespace amqp_0_10 {
00029
00030 using framing::in_place;
00031
00032 template <class Invokable> struct InvokeVisitor {
00033 typedef void result_type;
00034 Invokable& target;
00035 InvokeVisitor(Invokable& i) : target(i) {}
00036
00037 template <class Action>
00038 void operator()(const Action& action) { action.invoke(target); }
00039 };
00040
00041 template <class DerivedHolder, class BaseHeld, size_t Size>
00042 class Holder : public framing::Blob<Size, BaseHeld> {
00043 typedef framing::Blob<Size, BaseHeld> Base;
00044
00045 public:
00046
00047 Holder() {}
00048 template <class T> explicit Holder(const T& value) : Base(value) {}
00049
00050 using Base::operator=;
00051 Holder& operator=(const BaseHeld& rhs);
00052
00053 uint8_t getCode() const { return this->get()->getCode(); }
00054 uint8_t getClassCode() const { return this->get()->getClassCode(); }
00055
00056 template <class Invokable> void invoke(Invokable& i) const {
00057 InvokeVisitor<Invokable> v(i);
00058 apply(v, *this->get());
00059 }
00060
00061 template <class S> void encode(S& s) const {
00062 s(getClassCode())(getCode());
00063 }
00064
00065 template <class S> void decode(S& s) {
00066 uint8_t code, classCode;
00067 s(classCode)(code);
00068 static_cast<DerivedHolder*>(this)->set(classCode, code);
00069 }
00070
00071 template <class S> void serialize(S& s) {
00072 s.split(*this);
00073 qpid::amqp_0_10::apply(s, *this->get());
00074 }
00075
00076 template <class T> T* getIf() {
00077 return (getClassCode()==T::CLASS_CODE && getCode()==T::CODE) ? static_cast<T*>(this->get()) : 0;
00078 }
00079
00080 template <class T> const T* getIf() const {
00081 return (getClassCode()==T::CLASS_CODE && getCode()==T::CODE) ? static_cast<T*>(this->get()) : 0;
00082 }
00083
00084 private:
00085 struct Assign : public ApplyFunctor<void> {
00086 Holder& holder;
00087 Assign(Holder& x) : holder(x) {}
00088 template <class T> void operator()(const T& rhs) { holder=rhs; }
00089 };
00090 };
00091
00092 template <class D, class B, size_t S>
00093 Holder<D,B,S>& Holder<D,B,S>::operator=(const B& rhs) {
00094 Assign assign(*this);
00095 qpid::amqp_0_10::apply(assign, rhs);
00096 return *this;
00097 }
00098
00099
00100
00101 }}
00102
00103 #endif