| #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 |