ergo
ValidPtr.h
Go to the documentation of this file.
00001 /* Ergo, version 3.2, a program for linear scaling electronic structure
00002  * calculations.
00003  * Copyright (C) 2012 Elias Rudberg, Emanuel H. Rubensson, and Pawel Salek.
00004  * 
00005  * This program is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation, either version 3 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  * 
00018  * Primary academic reference:
00019  * Kohn−Sham Density Functional Theory Electronic Structure Calculations 
00020  * with Linearly Scaling Computational Time and Memory Usage,
00021  * Elias Rudberg, Emanuel H. Rubensson, and Pawel Salek,
00022  * J. Chem. Theory Comput. 7, 340 (2011),
00023  * <http://dx.doi.org/10.1021/ct100611z>
00024  * 
00025  * For further information about Ergo, see <http://www.ergoscf.org>.
00026  */
00027 
00036 #ifndef MAT_VALIDPTR
00037 #define MAT_VALIDPTR
00038 namespace mat {
00039 
00040 
00047   template <typename Tobj>
00048     class ValidPtr {
00049   public:
00051     explicit ValidPtr(Tobj * p) 
00052       : ptr(p), inMemory(true), haveDataStructure(false){}
00053     ~ValidPtr() {
00054       delete ptr;
00055     }
00056     
00057       /* Pointer can not be changed only object pointed to. 
00058        * Therefore this is a const operation.
00059        * Note that if Tobj is const it can not be changed of course.
00060        */
00061       Tobj & operator*() const {
00062         if (!inMemory)
00063           throw Failure("ValidPtr::operator*() const: "
00064                         "Attempt to access invalid object. "
00065                         "Object is on file.");
00066         if (!haveDataStructure)
00067           throw Failure("ValidPtr::operator*() const: "
00068                         "Attempt to access invalid object. "
00069                         "Do not have data structure.");
00070         return *ptr;
00071       }
00072 
00073       Tobj * operator->() const {
00074         if (!inMemory)
00075           throw Failure("ValidPtr::operator->() const: "
00076                         "Attempt to access invalid pointer."
00077                         "Object is on file.");
00078         if (!haveDataStructure)
00079           throw Failure("ValidPtr::operator->() const: "
00080                         "Attempt to access invalid pointer. "
00081                         "Do not have data structure.");
00082         return ptr;
00083       }
00084 
00087       const Tobj & getConstRefForCopying() const {
00088         return *ptr;
00089       }
00090 
00091       inline void inMemorySet(bool val) {
00092         inMemory = val;
00093       }
00094       inline bool inMemoryGet() const {
00095         return inMemory;
00096       }
00097       inline void haveDataStructureSet(bool val) {
00098         haveDataStructure = val;
00099       }
00100       inline bool haveDataStructureGet() const {
00101         return haveDataStructure;
00102       }
00103 
00104       static void swap( ValidPtr<Tobj> & ptrA, ValidPtr<Tobj> & ptrB ) {
00105         // For the moment, we do not allow swapping ptrs with objs
00106         // written to file. This could be a feature to add but would
00107         // require swapping filenames.
00108         if ( !ptrA.inMemoryGet() ||  !ptrB.inMemoryGet() ) 
00109           throw "Swap called for objects not in memory";
00110         if ( !ptrA.haveDataStructureGet() ||  !ptrB.haveDataStructureGet() )
00111           throw "Swap called for objects without data structure";
00112         Tobj * tmpPtr = ptrA.ptr;
00113         ptrA.ptr = ptrB.ptr;
00114         ptrB.ptr = tmpPtr;
00115       }
00116   protected:
00117       Tobj * ptr;
00119       bool inMemory; 
00121       bool haveDataStructure; 
00122   private:
00123       ValidPtr<Tobj>(ValidPtr<Tobj> const &) {}
00124       ValidPtr<Tobj>& operator=(ValidPtr<Tobj> const &) {}
00125   };
00126   
00127 }  /* end namespace mat */
00128 #endif