coherence/lang/cloneable_spec.hpp

00001 /*
00002 * cloneable_spec.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_CLONEABLE_SPEC_HPP
00017 #define COH_CLONEABLE_SPEC_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/class_spec.hpp"
00022 #include "coherence/lang/lang_spec.hpp"
00023 #include "coherence/lang/TypedHandle.hpp"
00024 #include "coherence/lang/TypedHolder.hpp"
00025 
00026 COH_OPEN_NAMESPACE2(coherence,lang)
00027 
00028 class Object;
00029 
00030 /**
00031 * Helper for defining a cloneable managed class.
00032 *
00033 * It addition to the features auto-generated by the class_spec<> helper template
00034 * cloneable_spec<> auto-generates an implemenation of "Object::Handle clone() const"
00035 * which delegates to the defined classes const copy constructor.
00036 *
00037 * A normal cloneable class defintion would be:
00038 * @code
00039 * class Foo
00040 *   : public cloneable_spec<Foo,
00041 *       extends<Bar>,
00042 *       implements<SomeInterface, SomeOtherInterface> >
00043 *   {
00044 *   // add support for auto-generated static create methods
00045 *   friend class factory<Foo>;
00046 *
00047 *   protected:
00048 *       // Constructors are defined as protected, and access via
00049 *       // auto-generated create methods, with matching signatures
00050 *       Foo()
00051 *           : super() ...
00052 *           {
00053 *           }
00054 *
00055 *       // Copy constructor
00056 *       Foo(const Foo& that)
00057 *           : super(that) ...
00058 *           {
00059 *           }
00060 *
00061 *   public:
00062 *       // normal class definition....
00063 *   };
00064 * @endcode
00065 *
00066 * @see extends
00067 * @see implements
00068 *
00069 * @author mf 2008.07.14
00070 */
00071 template<class T, class E = extends<Object>, class I = implements<> >
00072 class COH_EXPORT_SPEC cloneable_spec
00073     : public class_spec<T, E, I>
00074     {
00075     // ----- typedefs -------------------------------------------------------
00076 
00077     public:
00078         /**
00079         * Specification definition
00080         */
00081         typedef cloneable_spec this_spec;
00082 
00083         /**
00084         * Definition T's parent class
00085         */
00086         typedef cloneable_spec super;
00087 
00088     // ----- constructors ---------------------------------------------------
00089 
00090     protected:
00091         /**
00092         * Generate a set of proxy constuctors matching the signatures of the
00093         * parent class's constructors.
00094         *
00095         * NOTE: Compilation errors referencing this line likely indicate that
00096         *       class being defined by this spec makes calls a "super"
00097         *       constructor supplying a set of parameters for which there is
00098         *       no exact match on the parent class.
00099         */
00100         COH_DECLARE_PROXY_CONSTRUCTORS(cloneable_spec);
00101 
00102     public:
00103         /**
00104         * @inheritDoc
00105         */
00106         virtual TypedHandle<Object> clone() const
00107             {
00108             try
00109                 {
00110                 return create(dynamic_cast<const T&>(*this));
00111                 }
00112             catch (...)
00113                 {
00114                 // The above cast should never fail, but in MSVC 2005 it did when
00115                 // this clone implmentation was used for coherence::lang::String.
00116                 // String has manually implemented clone() to get around the
00117                 // issue, but this handler is left in place to catch other
00118                 // occurances. String is a rather special type of class
00119                 // definition as it uses protected inheirtance from Array<char>
00120                 // this may have triggered the compiler issue.
00121                 std::cerr << "Coherence: unexpected error casting from \""
00122                     << typeid(*this).name() << "\" to \"" << typeid(const T).name()
00123                     << "\" type equality == " << (typeid(const T) == typeid(*this))
00124                     << std::endl;
00125                 throw;
00126                 }
00127             }
00128     };
00129 COH_DEFINE_PROXY_CONSTRUCTORS(COH_TEMPLATE_DECLARE3(T, E, I), \
00130         COH_TEMPLATE_DEFINE3(T, E, I), cloneable_spec, \
00131         class_spec COH_TEMPLATE_DEFINE3(T, E, I))
00132 
00133 COH_CLOSE_NAMESPACE2
00134 
00135 #endif // COH_CLONEABLE_SPEC_HPP
Copyright (c) 2000-2008 Oracle. All rights reserved.