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