Gemmi C++ API
Loading...
Searching...
No Matches
fstream.hpp
Go to the documentation of this file.
1// Copyright 2019 Global Phasing Ltd.
2//
3// Ofstream and Ifstream: wrappers around std::ofstream and std::ifstream.
4//
5// They offer two extra features:
6// - on MSVC supports Unicode filenames (the filename is passed in UTF-8),
7// - optionally, filename "-" can be interpreted as stdout or stderr.
8
9#ifndef GEMMI_OFSTREAM_HPP_
10#define GEMMI_OFSTREAM_HPP_
11
12#if defined(_MSC_VER)
13# include "utf.hpp"
14#elif defined(_WIN32) && defined(__has_include)
15// including <filesystem> in MinGW 8 gives error (in bits/fs_path.h:237:47),
16// which was fixed in GCC 9
17# if __has_include(<filesystem>) && !(defined(__MINGW32__) && __GNUC__ < 9)
18# include <filesystem>
19# include "utf.hpp"
20# endif
21#endif
22#include <fstream>
23#include <memory>
24#include "fail.hpp"
25
26namespace gemmi {
27
28template<typename T>
29inline void open_stream_from_utf8_path(T& ptr, const std::string& filename) {
30#if defined(_MSC_VER)
31 std::wstring wfilename = UTF8_to_wchar(filename.c_str());
32 ptr->open(wfilename.c_str());
33#elif defined(_WIN32) && defined(__cpp_lib_filesystem)
34 std::wstring wfilename = UTF8_to_wchar(filename.c_str());
35 ptr->open(std::filesystem::path(wfilename));
36#else
37 ptr->open(filename);
38#endif
39}
40
41// note: move of std::ofstream doesn't work in GCC 4.8.
42
43struct Ofstream {
44 Ofstream(const std::string& filename, std::ostream* dash=nullptr) {
45 if (filename.size() == 1 && filename[0] == '-' && dash) {
46 ptr_ = dash;
47 return;
48 }
49 keeper_.reset(new std::ofstream);
51 if (!*keeper_)
52 sys_fail("Failed to open " + filename + " for writing");
53 ptr_ = keeper_.get();
54 }
55
56 std::ostream* operator->() { return ptr_; }
57 std::ostream& ref() { return *ptr_; }
58
59private:
60 std::unique_ptr<std::ofstream> keeper_;
61 std::ostream* ptr_;
62};
63
64struct Ifstream {
65 Ifstream(const std::string& filename, std::istream* dash=nullptr) {
66 if (filename.size() == 1 && filename[0] == '-' && dash) {
67 ptr_ = dash;
68 return;
69 }
70 keeper_.reset(new std::ifstream);
72 if (!*keeper_)
73 sys_fail("Failed to open " + filename);
74 ptr_ = keeper_.get();
75 }
76
77 std::istream* operator->() { return ptr_; }
78 std::istream& ref() { return *ptr_; }
79
80private:
81 std::unique_ptr<std::ifstream> keeper_;
82 std::istream* ptr_;
83};
84
85
86
87} // namespace gemmi
88#endif
fail(), unreachable() and __declspec/__attribute__ macros
void open_stream_from_utf8_path(T &ptr, const std::string &filename)
Definition fstream.hpp:29
std::wstring UTF8_to_wchar(const char *in)
Definition utf.hpp:12
GEMMI_COLD void sys_fail(const std::string &msg)
Definition fail.hpp:71
Ifstream(const std::string &filename, std::istream *dash=nullptr)
Definition fstream.hpp:65
std::istream & ref()
Definition fstream.hpp:78
std::istream * operator->()
Definition fstream.hpp:77
Ofstream(const std::string &filename, std::ostream *dash=nullptr)
Definition fstream.hpp:44
std::ostream & ref()
Definition fstream.hpp:57
std::ostream * operator->()
Definition fstream.hpp:56
Conversion between UTF-8 and wchar. Used only for file names on Windows.