Oracle® Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.2.1.4.0)

E90870-01

coherence/lang/Managed.hpp

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