Oracle Coherence for C++ API
Release 3.6.1.0
E18813-01

- Main Page
- Namespaces
- Classes
- Files

# 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     // ----- memory management ----------------------------------------------
    00310
    00311     protected:
    00312         /**
    00313         * @internal
    00314         *
    00315         * Explicitly delegate to Coherence Object to remove ambiguity
    00316         * for managed classes which inherit some other new().
    00317         */
    00318         static void* operator new(size_t cb)
    00319             {
    00320             return Object::operator new(cb);
    00321             }
    00322
    00323         /**
    00324         * @internal
    00325         *
    00326         * Explicitly delegate to Coherence Object to remove ambiguity
    00327         * for managed classes which inherit some other delete().
    00328         */
    00329         static void operator delete(void* po)
    00330             {
    00331             Object::operator delete(po);
    00332             }
    00333     };
    00334
    00335
    00336 // ----- non-member operators and functions ---------------------------------
    00337
    00338 /**
    00339 * Output a human-readable description of the specified Managed<T> to the given
    00340 * stream.
    00341 *
    00342 * @param out  the stream used to output the description
    00343 * @param aT   the Managed<T> to describe
    00344 *
    00345 * @return the supplied stream
    00346 */
    00347 template<class T> std::ostream& operator<<(std::ostream& out, const Managed<T>& aT)
    00348     {
    00349     return coherence::lang::operator<<(out, (const Object&) aT);
    00350     }
    00351
    00352 COH_CLOSE_NAMESPACE2
    00353
    00354 #endif // COH_MANAGED_HPP

Copyright © 2000, 2010, Oracle and/or its affiliates. All rights reserved.