Oracle Coherence for C++ API
Release 3.6.0.0

E15728-01

coherence/lang/Immutable.hpp

00001 /*
00002 * Immutable.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_IMMUTABLE_HPP
00017 #define COH_IMMUTABLE_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/IllegalArgumentException.hpp"
00022 #include "coherence/lang/Object.hpp"
00023 #include "coherence/lang/TypedHandle.hpp"
00024 
00025 #include <sstream>
00026 
00027 COH_OPEN_NAMESPACE2(coherence,lang)
00028 
00029 
00030 /**
00031 * A Handle implementation which upon assignment ensures that it will
00032 * reference an immutable Object. If the passed Object is immutable
00033 * (as defined by Object::isImmutable()) then the handle simply holds a const
00034 * pointer to the Object. If the passed Object is not immutable, then a clone
00035 * attempt is made, and held via a const pointer.  If the supplied Object is
00036 * not immutable and not cloneable then assignment will fail with a
00037 * CloneNotSupport exception.
00038 *
00039 * @author mf  2007.07.05
00040 */
00041 template<class T>
00042 class Immutable
00043     : public TypedHandle<const T>
00044     {
00045     // ----- constructors ---------------------------------------------------
00046 
00047     public:
00048         /**
00049         * Construct a @c NULL handle.
00050         */
00051         Immutable()
00052             : TypedHandle<const T>()
00053             {
00054             }
00055 
00056         /**
00057         * Construct an Immutable handle to the given Object.
00058         *
00059         * @param po the pointer to the Object to reference
00060         */
00061         Immutable(const T* po)
00062             : TypedHandle<const T>(NULL)
00063             {
00064             set(po, NULL);
00065             }
00066 
00067         /**
00068         * Construct an Immutable handle from another Handle
00069         *
00070         * @param that another handle
00071         */
00072         template<class O> Immutable<T>(const TypedHandle<O>& that)
00073             : TypedHandle<const T>(that)
00074             {
00075             }
00076 
00077         /**
00078         * Construct an Immutable handle from another Handle
00079         *
00080         * @param that  another handle
00081         */
00082         Immutable<T>(const Immutable<T>& that)
00083             : TypedHandle<const T>(that)
00084             {
00085             }
00086 
00087     // ----- helper methods -------------------------------------------------
00088 
00089     protected:
00090         /**
00091         * Set this handle to point to immutable version of the given object,
00092         * or unset the handle.
00093         *
00094         * If the given pointer points to the immutable object, then this
00095         * handle will point it. If the given pointer points to the mutable
00096         * object, then this handle will point to the clone of that object.
00097         * If the given pointer is NULL, then this handle will point to no
00098         * object.
00099         *
00100         * @param cpo    pointer to the target object
00101         * @param pThat  pointer to the source ChainedHandleElement
00102         */
00103         Immutable<T>& set(const T* cpo, const ChainedHandleElement* pThat)
00104             {
00105             if (cpo == NULL || cpo->isImmutable())
00106                 {
00107                 if (pThat != NULL)
00108                     {
00109                     TypedHandle<const T>::set(cpo, *pThat);
00110                     }
00111                 else
00112                     {
00113                     TypedHandle<const T>::operator=(cpo);
00114                     }
00115                 }
00116             else
00117                 {
00118                 Object::View vClone;
00119                     {
00120                     // With the Sun compiler the temporary handle created
00121                     // here will live for the duration of the surrounding
00122                     // scope, we must pop the scope to ensure that the
00123                     // temporary handle is destroyed/detached, so the
00124                     // immutability check can pass
00125                     vClone = cpo->clone();
00126                     }
00127                 if (NULL == vClone || !vClone->isImmutable())
00128                     {
00129                     COH_THROW_STREAM(IllegalArgumentException,
00130                         "Object of type '" << typeid(*cpo).name() <<
00131                         "' cannot be made immutable through cloning.");
00132                     }
00133                 TypedHandle<const T>::operator=(cast<typename T::View>(vClone));
00134                 }
00135             return *this;
00136             }
00137     };
00138 
00139 /**
00140 * Return an immutable version of the supplied Object. If the supplied view
00141 * does not refer to an immutable Object, then a clone of the original Object
00142 * is returned.
00143 *
00144 * @param v  view to the Object to return an immutable copy of
00145 *
00146 * @return a view to an immutable version of the supplied Object, or the
00147 *         supplied Object if it was already immutable
00148 */
00149 template<class T> typename T::View immutable_view(const typename T::View& v)
00150     {
00151     return Immutable<T>(v);
00152     }
00153 
00154 COH_CLOSE_NAMESPACE2
00155 
00156 #endif // COH_IMMUTABLE_HPP
Copyright © 2000, 2010, Oracle and/or its affiliates. All rights reserved.