SUNphi  1.0
File.hpp
Go to the documentation of this file.
1 #ifndef _FILE_HPP
2 #define _FILE_HPP
3 
4 /// \file File.hpp
5 ///
6 /// \brief Access to filesystem
7 
8 #include <filesystem>
9 
10 #include <metaprogramming/UniversalReferences.hpp>
11 #include <debug/MinimalCrash.hpp>
12 
13 namespace SUNphi
14 {
15  /// Mark the stream to be more indented
16 #define SCOPE_INDENT(VAR)
17  /*! Indent current scope */
18  ScopeIndenter NAME2(SCOPE_INDENTER,__LINE__)(VAR)
19 
20  /// Set for current scope
21 #define SET_FOR_CURRENT_SCOPE(NAME,VAR,...)
22  auto NAME3(SET,NAME,__LINE__)=getScopeChangeVar(VAR,__VA_ARGS__)
23 
24  /// Set the precision for current scope
25 #define SCOPE_REAL_PRECISION(STREAM,VAL)
26  SET_FOR_CURRENT_SCOPE(STREAM_REAL_PRECISION,STREAM.realPrecision,VAL)
27 
28  /// Set the format for current scope
29 #define SCOPE_REAL_FORMAT(STREAM,VAL)
30  SET_FOR_CURRENT_SCOPE(STREAM_REAL_FORMAT,STREAM.realFormat,VAL)
31 
32  /// Set general for the current scope
33 #define SCOPE_REAL_FORMAT_GENERAL(STREAM)
34  SET_FOR_CURRENT_SCOPE(STREAM_REAL_FORMAT_GENERAL,STREAM.realFormat,RealFormat::GENERAL)
35 
36  /// Set fixed for the current scope
37 #define SCOPE_REAL_FORMAT_FIXED(STREAM)
38  SET_FOR_CURRENT_SCOPE(STREAM_REAL_FORMAT_FIXED,STREAM.realFormat,RealFormat::FIXED)
39 
40  /// Set engineer for the current scope
41 #define SCOPE_REAL_FORMAT_ENGINEER(STREAM)
42  SET_FOR_CURRENT_SCOPE(STREAM_REAL_FORMAT_ENGINEER,STREAM.realFormat,RealFormat::ENGINEER)
43 
44  /// Set printing always sign at the beginning of a number for current scope
45 #define SCOPE_ALWAYS_PUT_SIGN(STREAM)
46  SET_FOR_CURRENT_SCOPE(STREAM_ALWAYS_PRINT_SIGN,STREAM.alwaysPrintSign,true)
47 
48  /// Set not to print always sign at the beginning of a number for current scope
49 #define SCOPE_NOT_ALWAYS_PUT_SIGN(STREAM)
50  SET_FOR_CURRENT_SCOPE(STREAM_NOT_ALWAYS_PRINT_SIGN,STREAM.alwaysPrintSign,false)
51 
52  /// Set printing or not zero
53 #define SCOPE_ALWAYS_PRINT_ZERO(STREAM)
54  SET_FOR_CURRENT_SCOPE(STREAM_ALWAYS_PRINT_ZERO,STREAM.alwaysPrintZero,true)
55 
56  /// Set printing or not zero
57 #define SCOPE_ALWAYS_PRINT_ZERO(STREAM)
58  SET_FOR_CURRENT_SCOPE(STREAM_ALWAYS_PRINT_ZERO,STREAM.alwaysPrintZero,true)
59 
60  /// Allows all ransk to print for current scope
61 #define SCOPE_ALL_RANKS_CAN_PRINT(STREAM)
62  SET_FOR_CURRENT_SCOPE(STREAM_ALL_RANKS_CAN_PRINT,STREAM.onlyMasterRankPrint,false)
63 
64  /// Returns whether the given path exists
65  inline bool fileExists(const std::filesystem::path& path) ///< Path to open
66  {
67  return
68  std::filesystem::exists(path);
69  }
70 
71  /// Returns the size of a file
72  inline std::uintmax_t fileSize(const std::filesystem::path& path) ///< Path to probe
73  {
74  return
75  std::filesystem::file_size(path);
76  }
77 
78  /// File access, with functionalities to open and close, write/read
79  class File
80  {
81  /// Raw file pointer
83 
84  /// Returned value of last i/o function
85  int rc{0};
86 
87  public:
88 
89  /// Open a file, crashing if impossible
90  void open(const char* path, ///< Path to open
91  const char* mode, ///< Mode used to open
92  const bool crashIfFail=true) ///< Crash or not if failing
93  {
94  // Check not open
95  if(isOpen())
96  MINIMAL_CRASH("Cannot open an already opened file");
97 
98  // Tries to open
99  file=
100  fopen(path,mode);
101 
102  // Check
103  if(file==nullptr and crashIfFail)
104  MINIMAL_CRASH("Unable to open file %s",path);
105  }
106 
107  /// Check if open
108  bool isOpen()
109  const
110  {
111  return
112  file!=nullptr;
113  }
114 
115  /// Close
116  void close()
117  {
118  if(isOpen())
119  {
120  fclose(file);
121 
122  // Set the file to null
123  file=
124  nullptr;
125  }
126  }
127 
128  /// Returns rc
129  int getRc()
130  const
131  {
132  return
133  rc;
134  }
135 
136  /// Precision to print real number
138 
139  /// Flag to determine whether print always or not the sign
140  bool alwaysPrintSign{false};
141 
142  /// Flag to determine whether print always or not the zero
143  bool alwaysPrintZero{false};
144 
145  /// Print mode for double/float
146  enum class RealFormat{GENERAL=0,FIXED=1,ENGINEER=2};
147 
148  /// Format mode for real number
150 
151  /// Prints a char
152  File& operator<<(const char& c) ///< Char to write
153  {
154  // Prints the char
155  rc=
156  fputc(c,file);
157 
158  return
159  *this;
160  }
161 
162  /// Prints an integer
163  File& operator<<(const int32_t& i) ///< Integer to write
164  {
165  rc=
166  fprintf(file,"%d",i);
167 
168  return
169  *this;
170  }
171 
172  /// Prints an unsigned integer
173  File& operator<<(const uint32_t& i) ///< Unsigned integer to write
174  {
175  rc=
176  fprintf(file,"%u",i);
177 
178  return
179  *this;
180  }
181 
182  /// Prints a long integer
183  File& operator<<(const int64_t& l) ///< Long integer to write
184  {
185  rc=
186  fprintf(file,"%ld",l);
187 
188  return
189  *this;
190  }
191 
192  /// Prints a long unsigned integer
193  File& operator<<(const uint64_t& l) ///< Long unsigned integer to write
194  {
195  rc=
196  fprintf(file,"%lu",l);
197 
198  return
199  *this;
200  }
201 
202  /// Prints a double
203  File& operator<<(const double& d)
204  {
205  /// String to print real numbers
206  ///
207  /// The first component is signed or not
208  /// The second component is the format
209  static constexpr char realFormatString[2][2][3][7]=
210  {{{"%.*g","%.*f","%.*e"},
211  {"%0.*g","%0.*f","%0.*e"}},
212  {{"%+.*g","%+.*f","%+.*e"},
213  {"%+0.*g","%+0.*f","%+0.*e"}}};
214 
215  rc=
216  fprintf(file,realFormatString[alwaysPrintSign][alwaysPrintZero][(int)realFormat],realPrecision,d);
217 
218  return
219  *this;
220  }
221 
222  /// Prints a pointer
223  template <typename T> // Type pointed
224  File& operator<<(const T* p) ///< Pointer to be printed
225  {
226  rc=
227  fprintf(file,"%p",p);
228 
229  return
230  *this;
231  }
232 
233  /// Prints after putting a space
234  template <typename T> // Type of the obected to print
235  File& operator*(T&& t) ///< Object to be printed
236  {
237  return
238  *this<<' '<<forw<T>(t);
239  }
240 
241  /// Prints a string
242  File& operator<<(const char* str)
243  {
244  rc=
245  fprintf(file,"%s",(str==nullptr)?"(null)":str);
246 
247  return
248  *this;
249  }
250 
251  /// Prints a c++ string
252  File& operator<<(const std::string& str)
253  {
254  return
255  (*this)<<str.c_str();
256  }
257 
258  /// Print a C-style variadic message
259  template <int MAX_LENGTH=256> // Maximal length to be be printed
260  File& printVariadicMessage(const char* format, ///< Format to print
261  va_list ap) ///< Variadic part
262  {
263  /// Message to be printed
264  char message[MAX_LENGTH];
265 
266  /// Resulting length if the space had been enough
267  rc=
268  vsnprintf(message,MAX_LENGTH,format,ap);
269 
270  /// Check if it was truncated
271  bool truncated=
272  (rc<0 or rc>=MAX_LENGTH);
273 
274  if(truncated)
275  *this<<message<<" (truncated line)";
276  else
277  *this<<message;
278 
279  return
280  *this;
281  }
282 
283  /// Destroy
284  ~File()
285  {
286  // Close if open
287  if(isOpen())
288  this->close();
289  }
290 
291  };
292 }
293 
294 #endif
bool fileExists(const std::filesystem::path &path)
Returns whether the given path exists.
Definition: File.hpp:65
#define MINIMAL_CRASH(...)
Initialize the minimal crasher.
void minimalCrash(const char *path, const int line, const char *funcName, const char *format,...)
Definition: SUNphi.cpp:53
int getRc() const
Returns rc.
Definition: File.hpp:129
~File()
Destroy.
Definition: File.hpp:284
#define NAME2(X, Y)
Merges two tokens using a _.
Definition: Macros.hpp:33
#define NAME3(X, Y, Z)
Merges three tokens with two _.
Definition: Macros.hpp:37
std::uintmax_t fileSize(const std::filesystem::path &path)
Returns the size of a file.
Definition: File.hpp:72
bool isOpen() const
Check if open.
Definition: File.hpp:108
File & operator<<(const uint64_t &l)
Prints a long unsigned integer.
Definition: File.hpp:193
File & printVariadicMessage(const char *format, va_list ap)
Print a C-style variadic message.
Definition: File.hpp:260
void close()
Close.
Definition: File.hpp:116
void open(const char *path, const char *mode, const bool crashIfFail=true)
Open a file, crashing if impossible.
Definition: File.hpp:90
RealFormat
Print mode for double/float.
Definition: File.hpp:146
File & operator*(T &&t)
Prints after putting a space.
Definition: File.hpp:235
#define SET_FOR_CURRENT_SCOPE(NAME, VAR,...)
Set for current scope.
Definition: File.hpp:21