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