cgma
dataref.hpp
Go to the documentation of this file.
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines