coherence/lang/BoxHandle.hpp

00001 /*
00002 * BoxHandle.hpp
00003 *
00004 * Copyright 2001-2008 by Oracle. 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_BOX_HANDLE_HPP
00017 #define COH_BOX_HANDLE_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/TypedHandle.hpp"
00022 
00023 COH_OPEN_NAMESPACE2(coherence,lang)
00024 
00025 
00026 /**
00027 * A TypedHandle implementation which supports auto-boxing.
00028 *
00029 * To support boxing a managed class defines an inner-type named "BoxedType",
00030 * and includes a public static "create" method which takes that type. The
00031 * BoxedType defines the type which the BoxHandle can use to create a managed
00032 * object from. Alternatively the BoxHandle declaration can identify the
00033 * "BoxedType" via a secondary template parameter.
00034 *
00035 * Managed classes which wish to be auto-boxing may use this handle type
00036 * when defining their Handle and View definitions. See String as an
00037 * example.
00038 *
00039 * When used with integral types a natural ambiguity is introduced when
00040 * setting or comparing a BoxHandle to NULL, as it also an integral type. In
00041 * such cases one may the is_null(h) and clear_handle(h) helper functions to
00042 * ensure the correct behavior.
00043 *
00044 * BoxHandle can be configured as strict, or non-strict. In strict mode
00045 * (the default), derefencing a NULL BoxHandle will result in a
00046 * NullPointerException. In non-strict mode, dereferencing a BoxHandle will
00047 * result in the BoxedType's default value being returned.
00048 *
00049 * @author mf  2007.07.05
00050 */
00051 template<class T, class B = typename T::BoxedType, bool fStrict = true>
00052 class BoxHandle
00053     : public TypedHandle<T>
00054     {
00055     // ----- typedefs -------------------------------------------------------
00056 
00057     typedef B BoxedType;
00058 
00059 
00060     // ----- constructors ---------------------------------------------------
00061 
00062     public:
00063         /**
00064         * Create an empty BoxHandle.
00065         */
00066         BoxHandle()
00067                 : TypedHandle<T>()
00068             {
00069             }
00070 
00071         /**
00072         * Create a new BoxHandle from the supplied BoxedType
00073         */
00074         BoxHandle(const B& b)
00075                 : TypedHandle<T>()
00076             {
00077             TypedHandle<T>::set(get_pointer(T::create(b)));
00078             }
00079 
00080         /**
00081         * Create a new BoxHandle from the TypedHandle with a type conversion.
00082         */
00083         template<class O> BoxHandle(const TypedHandle<O>& h)
00084                 : TypedHandle<T>()
00085             {
00086             TypedHandle<T>::set(get_pointer(h));
00087             }
00088 
00089         /**
00090         * Create a new BoxHandle from the TypedHandle with a type conversion.
00091         */
00092         template<class O> BoxHandle(TypedHandle<O>& h)
00093                 : TypedHandle<T>()
00094             {
00095             TypedHandle<T>::set(get_pointer(h));
00096             }
00097 
00098         /**
00099         * Create a new BoxHandle from the raw pointer.
00100         */
00101         BoxHandle(T* o)
00102                 : TypedHandle<T>()
00103             {
00104             TypedHandle<T>::set(o);
00105             }
00106 
00107         /**
00108         * The copy constructor.
00109         */
00110         BoxHandle(const BoxHandle& h)
00111                 : TypedHandle<T>(h)
00112             {
00113             TypedHandle<T>::set(h.get());
00114             }
00115 
00116         /**
00117         * The destructor.
00118         */
00119         ~BoxHandle()
00120             {
00121             }
00122 
00123     // ----- operators ------------------------------------------------------
00124 
00125     public:
00126         /**
00127         * The "boxing" operator.
00128         */
00129         BoxHandle& operator=(const BoxedType& b)
00130             {
00131             TypedHandle<T>::set(get_pointer(T::create(b)));
00132             return *this;
00133             }
00134 
00135         /**
00136         * The "unboxing" operator.
00137         *
00138         * @return a copy of the referenced Object
00139         */
00140         operator BoxedType() const
00141             {
00142             const T* pT = TypedHandle<T>::get();
00143             if (NULL == pT)
00144                 {
00145                 if (fStrict)
00146                     {
00147                     coh_throw_npe(typeid(T));
00148                     }
00149                 return BoxedType();
00150                 }
00151             return (BoxedType) *pT;
00152             }
00153 
00154         /**
00155         * The equality operator.
00156         */
00157         template<class O>
00158         bool operator==(const TypedHandle<O>& v) const
00159             {
00160             return (const Object*) get_pointer(*this) ==
00161                    (const Object*) get_pointer(v);
00162             }
00163 
00164         /**
00165         * The equality operator.
00166         */
00167         bool operator==(const Object* cpo) const
00168             {
00169             return ((const Object*) get_pointer(*this)) ==
00170                    ((const Object*) cpo);
00171             }
00172 
00173         /**
00174         * The equality operator.
00175         */
00176         bool operator==(const BoxedType& b) const
00177             {
00178             const T* pT = TypedHandle<T>::get();
00179             return NULL == pT ? BoxedType() == b : ((BoxedType) *pT) == b;
00180             }
00181 
00182         /**
00183         * The inequality operator.
00184         */
00185         template<class O>
00186         bool operator!=(const TypedHandle<O>& h) const
00187             {
00188             return !operator==(h);
00189             }
00190 
00191          /**
00192          * The inequality operator.
00193          */
00194          bool operator!=(const Object* cpo) const
00195              {
00196              return !operator==(cpo);
00197              }
00198 
00199         /**
00200         * The inequality operator.
00201         */
00202         bool operator!=(const BoxedType& b) const
00203             {
00204             return !operator==(b);
00205             }
00206     };
00207 
00208 COH_CLOSE_NAMESPACE2
00209 
00210 #endif // COH_BOX_HANDLE_HPP
Copyright (c) 2000-2008 Oracle. All rights reserved.