Oracle Coherence for C++ API
Release 3.6.0.0

E15728-01

coherence/lang/Managed.hpp

00001 /*
00002 * Managed.hpp
00003 *
00004 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
00005 *
00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
00007 * affiliates.
00008 *
00009 * This software is the confidential and proprietary information of Oracle
00010 * Corporation. You shall not disclose such confidential and proprietary
00011 * information and shall use it only in accordance with the terms of the
00012 * license agreement you entered into with Oracle.
00013 *
00014 * This notice may not be removed or altered.
00015 */
00016 #ifndef COH_MANAGED_HPP
00017 #define COH_MANAGED_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/Object.hpp"
00022 
00023 #include <cstddef>
00024 #include <ostream>
00025 #include <functional>
00026 
00027 COH_OPEN_NAMESPACE2(coherence,lang)
00028 
00029 
00030 /**
00031 * Managed is an adaptor class which transforms a pre-existing class into a
00032 * Coherence managed Object.
00033 *
00034 * The resulting object will be usable both as the supplied data type and as a
00035 * Coherence managed object. As a managed object it is suitable for storage in
00036 * Coherence caches.
00037 *
00038 * The managed object must be created using its associated static create
00039 * methods, which support either default construction, or copy construction
00040 * from the custom type. The managed object's life-cycle is dictated by reference
00041 * counting, and it may not be manually deleted.
00042 *
00043 * To be compatible with the Managed template the following set of functions
00044 * must be defined for the supplied type:
00045 * <ul>
00046 *   <li>zero parameter constructor (public or protected):
00047 *       <code>CustomType::CustomType()</code></li>
00048 *   <li>copy constructor (public or protected):
00049 *       <code>CustomType::CustomType(const CustomType&)</code></li>
00050 *   <li>equality comparison operator:
00051 *       <code>bool operator==(const CustomType&, const CustomType&)</code>
00052 *   <li>ostream output function:
00053 *       <code>std::ostream& operator<<(std::ostream&, const CustomType&)</code></li>
00054 *   <li>hash function:
00055 *       <code>size_t hash_value(const CustomType&)</code></li>
00056 * </ul>
00057 *
00058 * A example of a conforming class would be:
00059 * @code
00060 * class Address
00061 *   {
00062 *   public:
00063 *     Address(const std::string& sCity, const std::String& sState, int nZip)
00064 *       : m_sCity(sCity), m_sState(sState), m_nZip(nZip) {}
00065 *
00066 *     Address(const Address& that)
00067 *       : m_sCity(that.m_sCity), m_sState(that.m_sState), m_nZip(that.m_nZip) {}
00068 *
00069 *   protected:
00070 *     Address()
00071 *       : m_nZip(0) {}
00072 *
00073 *   public:
00074 *     std::string  getCity()  const {return m_sCity;}
00075 *     std::string  getState() const {return m_sState;}
00076 *     int          getZip()   const {return m_nZip;}
00077 *
00078 *   private:
00079 *     const std::string m_sCity;
00080 *     const std::string m_sState;
00081 *     const int         m_nZip;
00082 *   };
00083 *
00084 * bool operator==(const Address& addra, const Address& addrb)
00085 *   {
00086 *   return addra.getZip()   == addrb.getZip() &&
00087 *          addra.getState() == addrb.getState() &&
00088 *          addra.getCity()  == addrb.getCity();
00089 *   }
00090 *
00091 * std::ostream& operator<<(std::ostream& out, const Address& addr)
00092 *   {
00093 *   out << addr.getCity() << ", " << addr.getState() << "  " << addr.getZip();
00094 *   return out;
00095 *   }
00096 *
00097 * size_t hash_value(const Address& addr)
00098 *   {
00099 *   return (size_t) addr.getZip();
00100 *   }
00101 * @endcode
00102 *
00103 * Serialization support may be added by specializing the following free-functions:
00104 * <ul>
00105 *   <li>serializer:
00106 *       <code>void serialize<CustomType>(coherence::io::pof::PofWriter::Handle, const CustomType&)</code></li>
00107 *   <li>deserializer:
00108 *       <code>CustomType deserialize<CustomType>(coherence::io::pof::PofReader::Handle)</code></li>
00109 * </ul>
00110 *
00111 * The serialization functions do not need to be defined within the source file
00112 * of the original data type. They only need to be linked into the application,
00113 * and registered with the SystemPofContext via the COH_REGISTER_MANAGED_CLASS
00114 * macro.
00115 *
00116 * @code
00117 * #include "coherence/io/pof/SystemPofContext.hpp"
00118 *
00119 * #include "Address.hpp"
00120 *
00121 * using namespace coherence::io::pof;
00122 *
00123 * COH_REGISTER_MANAGED_CLASS(1234, Address);
00124 *
00125 * template<> void serialize<Address>(PofWriter::Handle hOut, const Address& addr)
00126 *   {
00127 *   hOut->writeString(0, addr.getCity());
00128 *   hOut->writeString(1, addr.getState());
00129 *   hOut->writeInt32 (2, addr.getZip());
00130 *   }
00131 *
00132 * template<> Address deserialize<Address>(PofReader::Handle hIn)
00133 *   {
00134 *   std::string sCity  = hIn->readString(0);
00135 *   std::string sState = hIn->readString(1);
00136 *   int         nZip   = hIn->readInt32 (2);
00137 *
00138 *   return Address(sCity, sState, nZip);
00139 *   }
00140 * @endcode
00141 *
00142 * An example usage of the resulting managed type would be:
00143 * @code
00144 * // construct the non-managed version as usual
00145 * Address office("Redwood Shores", "CA", 94065);
00146 *
00147 * // the managed version can be initialized from the non-managed version
00148 * // the result is a new object, which does not reference the original
00149 * Managed<Address>::View vOffice = Managed<Address>::create(office);
00150 * String::View           vKey    = "Oracle";
00151 *
00152 * // the managed version is suitable for use with caches
00153 * hCache->put(vKey, vAddr);
00154 * vOffice = cast<Managed<Address>::View>(hCache->get(vKey));
00155 *
00156 * // the non-managed class's public methods/fields remain accessible
00157 * assert(vOffice->getCity()  == office.getCity());
00158 * assert(vOffice->getState() == office.getState());
00159 * assert(vOffice->getZip()   == office.getZip());
00160 *
00161 * // conversion back to the non-managed type may be performed using the
00162 * // non-managed class's copy constructor.
00163 * Address officeOut = *vOffice;
00164 * @endcode
00165 *
00166 * @see coherence::io::pof::PofReader
00167 * @see coherence::io::pof::PofWriter
00168 * @see coherence::io::pof::SystemPofContext
00169 *
00170 * @author mf  2007.07.05
00171 */
00172 template<class T>
00173 class Managed
00174     : public cloneable_spec<Managed<T> >,
00175       public T
00176     {
00177     friend class factory<Managed<T> >;
00178 
00179     // ----- typedefs -------------------------------------------------------
00180 
00181     public:
00182         /**
00183         * The boxed class type.
00184         */
00185         typedef T BoxedType;
00186 
00187 
00188     // ----- constructors ---------------------------------------------------
00189 
00190     protected:
00191         /**
00192         * Create a new Managed<T> instance with the default initial T value.
00193         *
00194         * @return the new Managed<T>
00195         */
00196         Managed()
00197             : T()
00198             {
00199             // NOTE: a build error here indicates a zero-parameter constructor
00200             // has not been defined for T
00201             }
00202 
00203         /**
00204         * Create a new Managed<T> instance.
00205         *
00206         * @param t  the initial value for the templated type
00207         */
00208         Managed(const T& t)
00209             : T(t)
00210             {
00211             // NOTE: a build error here indicates a copy constructor has not
00212             // been defined for T
00213             }
00214 
00215         /**
00216         * Copy constructor.
00217         */
00218         Managed(const Managed<T>& that)
00219             : cloneable_spec<Managed<T> >(that), T(that)
00220             {
00221             // NOTE: a build error here indicates a copy constructor has not
00222             // been defined for T
00223             }
00224 
00225         /**
00226         * @internal
00227         */
00228         virtual ~Managed()
00229             {
00230             }
00231 
00232 
00233     // ----- Managed interface ----------------------------------------------
00234 
00235     protected:
00236         /**
00237         * Return the reference to the managed T object.
00238         *
00239         * @return the managed object
00240         */
00241         virtual T& getManagedObject()
00242             {
00243             return *this;
00244             }
00245 
00246         /**
00247         * Return the constant reference to managed T object.
00248         *
00249         * @return the managed object
00250         */
00251         virtual const T& getManagedObject() const
00252             {
00253             return *this;
00254             }
00255 
00256 
00257     // ----- Object interface -----------------------------------------------
00258 
00259     public:
00260         /**
00261         * {@inheritDoc}
00262         *
00263         * @param v  the object to compare against
00264         *
00265         * This method delegates to the custom types equality operator.
00266         */
00267         virtual bool equals(Object::View v) const
00268             {
00269             // NOTE: a build error here indicates that the following function
00270             // has not been defined for T:
00271             //   bool operator==(const T&, const T&)
00272             return this == v ||
00273                 (instanceof<typename cloneable_spec<Managed<T> >::View>(v) &&
00274                     getManagedObject() ==
00275                         cast<typename cloneable_spec<Managed<T> >::View>(v)
00276                             ->getManagedObject());
00277             }
00278 
00279         /**
00280         * {@inheritDoc}
00281         *
00282         * @param out  the stream to write to
00283         *
00284         * This method delegates to the custom types stream operator. (operator<<)
00285         */
00286         virtual void toStream(std::ostream& out) const
00287             {
00288             // NOTE: a build error here indicates that the following function
00289             // has not been defined for T:
00290             //   std::ostream& operator<<(std::ostream&, const T&)
00291             out << getManagedObject();
00292             }
00293 
00294         /**
00295         * {@inheritDoc}
00296         *
00297         * This method delegates to the global hash function specialized
00298         * for the custom type.
00299         */
00300         virtual size32_t hashCode() const
00301             {
00302             // NOTE: a build error here indicates that the following function
00303             // has not been defined for T:
00304             //   size_t hash_value(const T&)
00305             return size32_t(hash_value(*this));
00306             }
00307     };
00308 
00309 
00310 // ----- non-member operators and functions ---------------------------------
00311 
00312 /**
00313 * Output a human-readable description of the specified Managed<T> to the given
00314 * stream.
00315 *
00316 * @param out  the stream used to output the description
00317 * @param aT   the Managed<T> to describe
00318 *
00319 * @return the supplied stream
00320 */
00321 template<class T> std::ostream& operator<<(std::ostream& out, const Managed<T>& aT)
00322     {
00323     return coherence::lang::operator<<(out, (const Object&) aT);
00324     }
00325 
00326 COH_CLOSE_NAMESPACE2
00327 
00328 #endif // COH_MANAGED_HPP
Copyright © 2000, 2010, Oracle and/or its affiliates. All rights reserved.