blob: 330ebbe8050496293dc07c003b69c17225969096 [file] [log] [blame]
#ifndef PROTON_INTERNAL_OBJECT_HPP
#define PROTON_INTERNAL_OBJECT_HPP
/*
*
* 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 "./config.hpp"
#include "./export.hpp"
#include "./comparable.hpp"
#include <memory>
namespace proton {
template <class T> class thread_safe;
namespace internal {
class pn_ptr_base {
protected:
PN_CPP_EXTERN static void incref(void* p);
PN_CPP_EXTERN static void decref(void* p);
};
template <class T> class pn_ptr : private pn_ptr_base, private comparable<pn_ptr<T> > {
public:
pn_ptr() : ptr_(0) {}
pn_ptr(T* p) : ptr_(p) { incref(ptr_); }
pn_ptr(const pn_ptr& o) : ptr_(o.ptr_) { incref(ptr_); }
#if PN_CPP_HAS_RVALUE_REFERENCES
pn_ptr(pn_ptr&& o) : ptr_(0) { std::swap(ptr_, o.ptr_); }
#endif
~pn_ptr() { decref(ptr_); }
pn_ptr& operator=(pn_ptr o) { std::swap(ptr_, o.ptr_); return *this; }
T* get() const { return ptr_; }
T* release() { T *p = ptr_; ptr_ = 0; return p; }
bool operator!() const { return !ptr_; }
#if PN_CPP_HAS_EXPLICIT_CONVERSIONS
explicit operator bool() const { return !!ptr_; }
#endif
static pn_ptr take_ownership(T* p) { return pn_ptr<T>(p, true); }
private:
T *ptr_;
// Note that it is the presence of the bool in the constructor signature that matters
// to get the "transfer ownership" constructor: The value of the bool isn't checked.
pn_ptr(T* p, bool) : ptr_(p) {}
friend bool operator==(const pn_ptr& a, const pn_ptr& b) { return a.ptr_ == b.ptr_; }
friend bool operator<(const pn_ptr& a, const pn_ptr& b) { return a.ptr_ < b.ptr_; }
};
template <class T> pn_ptr<T> take_ownership(T* p) { return pn_ptr<T>::take_ownership(p); }
/// Base class for proton object types.
template <class T> class object : private comparable<object<T> > {
public:
bool operator!() const { return !object_; }
#if PN_CPP_HAS_EXPLICIT_CONVERSIONS
explicit operator bool() const { return object_; }
#endif
protected:
typedef T pn_type;
object(pn_ptr<T> o) : object_(o) {}
T* pn_object() const { return object_.get(); }
private:
pn_ptr<T> object_;
friend bool operator==(const object& a, const object& b) { return a.object_ == b.object_; }
friend bool operator<(const object& a, const object& b) { return a.object_ < b.object_; }
template <class U> friend class proton::thread_safe;
};
/// Factory class used internally to make wrappers and extract proton objects
template <class T> class factory;
} // internal
} // proton
#endif // PROTON_INTERNAL_OBJECT_HPP