1 /* Ergo, version 3.8, a program for linear scaling electronic structure 2 * calculations. 3 * Copyright (C) 2019 Elias Rudberg, Emanuel H. Rubensson, Pawel Salek, 4 * and Anastasia Kruchinina. 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * Primary academic reference: 20 * Ergo: An open-source program for linear-scaling electronic structure 21 * calculations, 22 * Elias Rudberg, Emanuel H. Rubensson, Pawel Salek, and Anastasia 23 * Kruchinina, 24 * SoftwareX 7, 107 (2018), 25 * <http://dx.doi.org/10.1016/j.softx.2018.03.005> 26 * 27 * For further information about Ergo, see <http://www.ergoscf.org>. 28 */ 29 30 /** @file ValidPtr.h Smart pointer class to control access to object. 31 * 32 * Copyright(c) Emanuel Rubensson 2006 33 * 34 * @author Emanuel Rubensson @a responsible @a author 35 * @date November 2006 36 * 37 */ 38 #ifndef MAT_VALIDPTR 39 #define MAT_VALIDPTR 40 namespace mat { 41 42 43 /** Smart pointer class to control access to object 44 * 45 * Primary use: 46 * Control access to objects that may be written to file. 47 * 48 */ 49 template <typename Tobj> 50 class ValidPtr { 51 public: 52 /** Copy ordinary pointer constructor */ ValidPtr(Tobj * p)53 explicit ValidPtr(Tobj * p) 54 : ptr(p), inMemory(true), haveDataStructure(false){} ~ValidPtr()55 ~ValidPtr() { 56 delete ptr; 57 } 58 59 /* Pointer can not be changed only object pointed to. 60 * Therefore this is a const operation. 61 * Note that if Tobj is const it can not be changed of course. 62 */ 63 Tobj & operator*() const { 64 if (!inMemory) 65 throw Failure("ValidPtr::operator*() const: " 66 "Attempt to access invalid object. " 67 "Object is on file."); 68 if (!haveDataStructure) 69 throw Failure("ValidPtr::operator*() const: " 70 "Attempt to access invalid object. " 71 "Do not have data structure."); 72 return *ptr; 73 } 74 75 Tobj * operator->() const { 76 if (!inMemory) 77 throw Failure("ValidPtr::operator->() const: " 78 "Attempt to access invalid pointer." 79 "Object is on file."); 80 if (!haveDataStructure) 81 throw Failure("ValidPtr::operator->() const: " 82 "Attempt to access invalid pointer. " 83 "Do not have data structure."); 84 return ptr; 85 } 86 87 /** getConstRefForCopying() is provided to make it possible to 88 copy the object also when it is written to file. */ getConstRefForCopying()89 const Tobj & getConstRefForCopying() const { 90 return *ptr; 91 } 92 inMemorySet(bool val)93 inline void inMemorySet(bool val) { 94 inMemory = val; 95 } inMemoryGet()96 inline bool inMemoryGet() const { 97 return inMemory; 98 } haveDataStructureSet(bool val)99 inline void haveDataStructureSet(bool val) { 100 haveDataStructure = val; 101 } haveDataStructureGet()102 inline bool haveDataStructureGet() const { 103 return haveDataStructure; 104 } 105 swap(ValidPtr<Tobj> & ptrA,ValidPtr<Tobj> & ptrB)106 static void swap( ValidPtr<Tobj> & ptrA, ValidPtr<Tobj> & ptrB ) { 107 // For the moment, we do not allow swapping ptrs with objs 108 // written to file. This could be a feature to add but would 109 // require swapping filenames. 110 if ( !ptrA.inMemoryGet() || !ptrB.inMemoryGet() ) 111 throw "Swap called for objects not in memory"; 112 if ( !ptrA.haveDataStructureGet() || !ptrB.haveDataStructureGet() ) 113 throw "Swap called for objects without data structure"; 114 Tobj * tmpPtr = ptrA.ptr; 115 ptrA.ptr = ptrB.ptr; 116 ptrB.ptr = tmpPtr; 117 } 118 protected: 119 Tobj * ptr; 120 /** Access to ptr forbidden if inMemory is false */ 121 bool inMemory; 122 /** Access to ptr forbidden if haveDataStructure is false */ 123 bool haveDataStructure; 124 private: 125 ValidPtr<Tobj>(ValidPtr<Tobj> const &) {} 126 ValidPtr<Tobj>& operator=(ValidPtr<Tobj> const &) {} 127 }; 128 129 } /* end namespace mat */ 130 #endif 131