summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/broker/PrivateImplRef.h
diff options
context:
space:
mode:
authorKim van der Riet <kpvdr@apache.org>2012-07-16 13:54:11 +0000
committerKim van der Riet <kpvdr@apache.org>2012-07-16 13:54:11 +0000
commita804510d81ade0594a75b5c9b8765cafcc233245 (patch)
tree8c6be643564b6d8c88619d17de7150c98a314781 /cpp/src/qpid/broker/PrivateImplRef.h
parent1ab07197127e990da2c765ea0ffa5fd8ca47b7b6 (diff)
downloadqpid-python-a804510d81ade0594a75b5c9b8765cafcc233245.tar.gz
QPID-3858: Refactor to tidy up several class design issues
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1362039 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/broker/PrivateImplRef.h')
-rw-r--r--cpp/src/qpid/broker/PrivateImplRef.h105
1 files changed, 105 insertions, 0 deletions
diff --git a/cpp/src/qpid/broker/PrivateImplRef.h b/cpp/src/qpid/broker/PrivateImplRef.h
new file mode 100644
index 0000000000..5932ab882b
--- /dev/null
+++ b/cpp/src/qpid/broker/PrivateImplRef.h
@@ -0,0 +1,105 @@
+#ifndef QPID_BROKER_PRIVATEIMPLREF_H
+#define QPID_BROKER_PRIVATEIMPLREF_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.
+ *
+ */
+
+/*
+ * NOTE: This is a copy of qpid::messaging::PrivateImplRef
+ *
+ * This (together with Handle.h) has been placed here so
+ * as not to introduce unnecessary dependencies on qpid::messaging
+ * for users of the Handle template in the qpid::broker namespace.
+ *
+ * Any fixes made here should also be made to qpid/messaging/PrivateImplRef.h
+ *
+ * TODO: Find (if possible) a way to eliminate two copies of the same code.
+ */
+
+#include <boost/intrusive_ptr.hpp>
+#include "qpid/RefCounted.h"
+
+namespace qpid {
+namespace broker {
+
+/**
+ * Helper class to implement a class with a private, reference counted
+ * implementation and reference semantics.
+ *
+ * Such classes are used in the public API to hide implementation, they
+ * should. Example of use:
+ *
+ * === Foo.h
+ *
+ * template <class T> class PrivateImplRef;
+ * class FooImpl;
+ *
+ * Foo : public Handle<FooImpl> {
+ * public:
+ * Foo(FooImpl* = 0);
+ * Foo(const Foo&);
+ * ~Foo();
+ * Foo& operator=(const Foo&);
+ *
+ * int fooDo(); // and other Foo functions...
+ *
+ * private:
+ * typedef FooImpl Impl;
+ * Impl* impl;
+ * friend class PrivateImplRef<Foo>;
+ *
+ * === Foo.cpp
+ *
+ * typedef PrivateImplRef<Foo> PI;
+ * Foo::Foo(FooImpl* p) { PI::ctor(*this, p); }
+ * Foo::Foo(const Foo& c) : Handle<FooImpl>() { PI::copy(*this, c); }
+ * Foo::~Foo() { PI::dtor(*this); }
+ * Foo& Foo::operator=(const Foo& c) { return PI::assign(*this, c); }
+ *
+ * int foo::fooDo() { return impl->fooDo(); }
+ *
+ */
+template <class T> class PrivateImplRef {
+ public:
+ typedef typename T::Impl Impl;
+ typedef boost::intrusive_ptr<Impl> intrusive_ptr;
+
+ /** Get the implementation pointer from a handle */
+ static intrusive_ptr get(const T& t) { return intrusive_ptr(t.impl); }
+
+ /** Set the implementation pointer in a handle */
+ static void set(T& t, const intrusive_ptr& p) {
+ if (t.impl == p) return;
+ if (t.impl) boost::intrusive_ptr_release(t.impl);
+ t.impl = p.get();
+ if (t.impl) boost::intrusive_ptr_add_ref(t.impl);
+ }
+
+ // Helper functions to implement the ctor, dtor, copy, assign
+ static void ctor(T& t, Impl* p) { t.impl = p; if (p) boost::intrusive_ptr_add_ref(p); }
+ static void copy(T& t, const T& x) { if (&t == &x) return; t.impl = 0; assign(t, x); }
+ static void dtor(T& t) { if(t.impl) boost::intrusive_ptr_release(t.impl); }
+ static T& assign(T& t, const T& x) { set(t, get(x)); return t;}
+};
+
+}} // namespace qpid::broker
+
+#endif /*!QPID_BROKER_PRIVATEIMPLREF_H*/