cgma
|
00001 #ifndef MCNP2CAD_DATA_REF_H 00002 #define MCNP2CAD_DATA_REF_H 00003 00004 // additional implemenentations of this class are defined in MCNPInput.cpp 00005 00006 template <class T> class DataRef{ 00007 00008 public: 00009 virtual ~DataRef(){} 00010 00011 virtual bool hasData() const { return true; } 00012 virtual const T& getData() const = 0; 00013 virtual DataRef<T>* clone() = 0; 00014 00015 }; 00016 00017 /* Note about covariant return types: 00018 * DataRef<T> requires a clone() class that (polymorphically) copies the object; this allows any 00019 * DataRef object to be copied without reference to its implementing type. This can be thought of 00020 * as a virtual constructor (see parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8) 00021 * 00022 * Note that on some older compilers, it may be necessary to change the return type of the clone() 00023 * method to be DataRef<T> for all classes. 00024 */ 00025 00026 00027 // a simple container around a given kind of data 00028 template <class T> 00029 class ImmediateRef : public DataRef<T>{ 00030 00031 protected: 00032 T data; 00033 00034 public: 00035 ImmediateRef( const T& p ) : 00036 data(p) 00037 {} 00038 00039 virtual const T& getData() const { 00040 return data; 00041 } 00042 00043 // ImmediateRefs can have their data amended 00044 T& getData(){ return data; } 00045 00046 virtual ImmediateRef<T>* clone() { 00047 return new ImmediateRef<T>( *this ); 00048 } 00049 00050 }; 00051 00052 // a reference by pointer: use cautiously, as it assumes its data is always valid 00053 template <class T> 00054 class PointerRef : public DataRef<T>{ 00055 00056 protected: 00057 const T* data; 00058 00059 public: 00060 PointerRef( const T* p ) : 00061 data(p) 00062 {} 00063 00064 virtual const T& getData() const { 00065 return *data; 00066 } 00067 00068 virtual PointerRef<T>* clone() { 00069 return new PointerRef<T>( *this ); 00070 } 00071 00072 }; 00073 00074 #include <stdexcept> 00075 00076 // a class that has no data, and throws an exception if getData() is called. 00077 template <class T> 00078 class NullRef : public DataRef<T>{ 00079 00080 public: 00081 NullRef() : 00082 DataRef<T>() 00083 {} 00084 00085 virtual bool hasData() const { return false; } 00086 00087 virtual const T& getData() const { 00088 throw std::runtime_error("Attempting to pull data from a null reference!"); 00089 } 00090 00091 virtual NullRef<T> * clone(){ 00092 return new NullRef<T>(*this); 00093 } 00094 00095 }; 00096 00097 00098 00099 00100 #endif /* MCNP2CAD_DATA_REF_H */