Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 #include "UtilityFunctions.hh" 27 28 #include <cstdio> 29 #include <memory> 30 31 #ifdef WIN32 32 # include <direct.h> 33 #else 34 # include <unistd.h> 35 #endif 36 37 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 38 39 namespace utility 40 { 41 std::vector<G4String>& Split(const G4String& str, char delim, std::vector<G4String>& elems) 42 { 43 std::stringstream ss(str); 44 std::string item; 45 while (std::getline(ss, item, delim)) { 46 if (!item.empty()) elems.push_back((G4String)item); 47 } 48 return elems; 49 } 50 51 std::vector<G4String> Split(const G4String& str, char delim) 52 { 53 std::vector<G4String> elems; 54 Split(str, delim, elems); 55 return elems; 56 } 57 58 // return element ii 59 G4String Get_seperated_element(const G4String& str, char delim, G4int ii) 60 { 61 G4int delims = 0; 62 G4String ss; 63 for (char c : str) { 64 if (delims > ii) { 65 return ss; 66 } 67 if (c == delim) { 68 delims++; 69 } 70 else if (delims == ii) { 71 ss += c; 72 } 73 } 74 return ss; 75 } 76 77 // return first four strings 78 std::array<G4String, 4> Get_four_elements(const G4String& str, char delim) 79 { 80 G4int delims = 0; 81 std::array<G4String, 4> arr; 82 for (char c : str) { 83 if (delims >= 4) return arr; 84 if (c == delim) 85 delims++; 86 else 87 arr.at(delims) += c; 88 } 89 return arr; 90 } 91 92 G4bool Path_exists(const G4String& fname) 93 { 94 G4bool bool_val = false; 95 if (FILE* file = std::fopen(fname, "r")) { 96 fclose(file); 97 bool_val = true; 98 } 99 return bool_val; 100 } 101 102 // Memory safe multi-platform getcwd 103 // http://stackoverflow.com/questions/2869594/ 104 G4String Getcwd() 105 { 106 const size_t chunkSize = 255; 107 const int maxChunks = 10240; // 2550 KiBs of current path is plenty 108 109 char stackBuffer[chunkSize]; // Stack buffer for the "normal" case 110 if (::getcwd(stackBuffer, sizeof(stackBuffer)) != nullptr) return stackBuffer; 111 if (errno != ERANGE) { 112 // It's not ERANGE, so we don't know how to handle it 113 throw std::runtime_error("Cannot determine the current path."); 114 // Of course you may choose a different error reporting method 115 } 116 // Ok, the stack buffer isn't long enough; fallback to heap allocation 117 for (int chunks = 2; chunks < maxChunks; chunks++) { 118 // With boost use scoped_ptr; in C++0x, use unique_ptr 119 // If you want to be less C++ but more efficient 120 // you may want to use realloc 121 std::unique_ptr<char[]> cwd(new char[chunkSize * chunks]); 122 if (::getcwd(cwd.get(), chunkSize * chunks) != nullptr) return cwd.get(); 123 if (errno != ERANGE) { 124 // It's not ERANGE, so we don't know how to handle it 125 throw std::runtime_error("Cannot determine the current path."); 126 // Of course you may choose a different error reporting method 127 } 128 } 129 throw std::runtime_error( 130 "Cannot determine the current path; the path is " 131 "apparently unreasonably long"); 132 } 133 134 G4double Min(const G4ThreeVector& v) 135 { 136 return std::min(std::min(v.x(), v.y()), v.z()); 137 } 138 } // namespace utility 139 140 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 141