blob: 8712db6c8667338011adca165437305395ff3cf4 [file] [log] [blame]
#ifndef QPID_AMQP_0_10_HOLDER_H
#define QPID_AMQP_0_10_HOLDER_H
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#include "qpid/framing/Blob.h"
#include "apply.h"
namespace qpid {
namespace amqp_0_10 {
using framing::in_place;
template <class Invokable> struct InvokeVisitor {
typedef void result_type;
Invokable& target;
InvokeVisitor(Invokable& i) : target(i) {}
template <class Action>
void operator()(const Action& action) { action.invoke(target); }
};
template <class DerivedHolder, class BaseHeld, size_t Size>
class Holder : public framing::Blob<Size, BaseHeld> {
typedef framing::Blob<Size, BaseHeld> Base;
public:
Holder() {}
template <class T> explicit Holder(const T& value) : Base(value) {}
using Base::operator=;
Holder& operator=(const BaseHeld& rhs);
uint8_t getCode() const { return this->get()->getCode(); }
uint8_t getClassCode() const { return this->get()->getClassCode(); }
template <class Invokable> void invoke(Invokable& i) const {
InvokeVisitor<Invokable> v(i);
apply(v, *this->get());
}
template <class S> void encode(S& s) const {
s(getClassCode())(getCode());
}
template <class S> void decode(S& s) {
uint8_t code, classCode;
s(classCode)(code);
static_cast<DerivedHolder*>(this)->set(classCode, code);
}
template <class S> void serialize(S& s) {
s.split(*this);
qpid::amqp_0_10::apply(s, *this->get());
}
template <class T> T* getIf() {
return (getClassCode()==T::CLASS_CODE && getCode()==T::CODE) ? static_cast<T*>(this->get()) : 0;
}
template <class T> const T* getIf() const {
return (getClassCode()==T::CLASS_CODE && getCode()==T::CODE) ? static_cast<T*>(this->get()) : 0;
}
private:
struct Assign : public ApplyFunctor<void> {
Holder& holder;
Assign(Holder& x) : holder(x) {}
template <class T> void operator()(const T& rhs) { holder=rhs; }
};
};
template <class D, class B, size_t S>
Holder<D,B,S>& Holder<D,B,S>::operator=(const B& rhs) {
Assign assign(*this);
qpid::amqp_0_10::apply(assign, rhs);
return *this;
}
}} // namespace qpid::amqp_0_10
#endif /*!QPID_AMQP_0_10_HOLDER_H*/