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# if __has_include(<filesystem>)
16# include <filesystem>
17# include "utf.hpp"
18# endif
19#endif
20#include <fstream>
21#include <memory>
22#include "fail.hpp"
23
24namespace gemmi {
25
26template<typename T>
27inline void open_stream_from_utf8_path(T& ptr, const std::string& filename) {
28#if defined(_MSC_VER)
29 std::wstring wfilename = UTF8_to_wchar(filename.c_str());
30 ptr->open(wfilename.c_str());
31#elif defined(_WIN32) && defined(__cpp_lib_filesystem)
32 std::wstring wfilename = UTF8_to_wchar(filename.c_str());
33 ptr->open(std::filesystem::path(wfilename));
34#else
35 ptr->open(filename);
36#endif
37}
38
39// note: move of std::ofstream doesn't work in GCC 4.8.
40
41struct Ofstream {
42 Ofstream(const std::string& filename, std::ostream* dash=nullptr) {
43 if (filename.size() == 1 && filename[0] == '-' && dash) {
44 ptr_ = dash;
45 return;
46 }
47 keeper_.reset(new std::ofstream);
49 if (!*keeper_)
50 sys_fail("Failed to open " + filename + " for writing");
51 ptr_ = keeper_.get();
52 }
53
54 std::ostream* operator->() { return ptr_; }
55 std::ostream& ref() { return *ptr_; }
56
57private:
58 std::unique_ptr<std::ofstream> keeper_;
59 std::ostream* ptr_;
60};
61
62struct Ifstream {
63 Ifstream(const std::string& filename, std::istream* dash=nullptr) {
64 if (filename.size() == 1 && filename[0] == '-' && dash) {
65 ptr_ = dash;
66 return;
67 }
68 keeper_.reset(new std::ifstream);
70 if (!*keeper_)
71 sys_fail("Failed to open " + filename);
72 ptr_ = keeper_.get();
73 }
74
75 std::istream* operator->() { return ptr_; }
76 std::istream& ref() { return *ptr_; }
77
78private:
79 std::unique_ptr<std::ifstream> keeper_;
80 std::istream* ptr_;
81};
82
83
84
85} // namespace gemmi
86#endif
void open_stream_from_utf8_path(T &ptr, const std::string &filename)
Definition fstream.hpp:27
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:63
std::istream & ref()
Definition fstream.hpp:76
std::istream * operator->()
Definition fstream.hpp:75
Ofstream(const std::string &filename, std::ostream *dash=nullptr)
Definition fstream.hpp:42
std::ostream & ref()
Definition fstream.hpp:55
std::ostream * operator->()
Definition fstream.hpp:54