C++ Client API Reference for Oracle Coherence
14c (14.1.2.0.0)

F79659-03

coherence/lang/Managed.hpp

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