-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathio_helper.h
101 lines (86 loc) · 2.87 KB
/
io_helper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#ifndef IO_HELPER_H
#define IO_HELPER_H
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <string>
#include <utility>
#include "file_utility.h"
template<class SaveFunc, class ...Args>
void save_binary_file(const std::string&file_name, const SaveFunc&save, Args&&...args){
std::ofstream out(file_name, std::ios::binary);
if(!out)
throw std::runtime_error("Could not open "+file_name+" for binary writing");
save(out, std::forward<Args>(args)...);
}
template<class SaveFunc, class ...Args>
void save_text_file(const std::string&file_name, const SaveFunc&save, Args&&...args){
if(file_name == "-"){
save(std::cout, std::forward<Args>(args)...);
std::cout << std::flush;
} else if(file_name == "-null"){
} else {
std::ofstream out(file_name);
if(!out)
throw std::runtime_error("Could not open "+file_name+" for text writing");
save(out, std::forward<Args>(args)...);
}
}
template<class LoadFunc>
auto load_binary_file(const std::string&file_name, const LoadFunc&load)->decltype(load(std::cin, 0)){
std::ifstream in(file_name, std::ios::binary);
if(!in)
throw std::runtime_error("Could not load "+file_name+" for binary reading");
in.seekg (0, in.end);
long long size = in.tellg();
in.seekg (0, in.beg);
return load(in, size);
}
template<class LoadFunc>
auto load_uncached_text_file(const std::string&file_name, const LoadFunc&load)->decltype(load(std::cin)){
if(file_name == "-"){
return load(std::cin);
} else {
std::ifstream in(file_name);
if(!in)
throw std::runtime_error("Could not load "+file_name+" for text reading");
return load(in);
}
}
template<class UncachedLoadFunc, class CachedLoadFunc, class CacheSaveFunc>
auto load_cached_text_file(
const std::string&file_name,
const std::string&format_name,
const UncachedLoadFunc&uncached_load,
const CachedLoadFunc&cached_load,
const CacheSaveFunc&cache_save
)->decltype(uncached_load(std::cin)){
if(file_name == "-"){
return uncached_load(std::cin);
} else {
std::string cache_file_name = concat_file_path_and_file_name(
get_temp_directory_path(),
"flow_cutter_cached_"+format_name+ "_" + uniquely_hash_file_name(make_absolute_file_name(file_name))
);
if(file_exists(cache_file_name))
if(file_last_modified(file_name) < file_last_modified(cache_file_name)){
std::ifstream in(cache_file_name, std::ios::binary);
if(!in)
throw std::runtime_error("Could not open binary cache file "+cache_file_name+" of "+file_name+" for reading");
in.seekg (0, in.end);
long long size = in.tellg();
in.seekg (0, in.beg);
return cached_load(in, size);
}
std::ifstream in(file_name);
if(!in)
throw std::runtime_error("Could not open text file "+file_name+" for reading");
auto data = uncached_load(in);
in.close();
std::ofstream out(cache_file_name, std::ios::binary);
if(out)
cache_save(out, data);
return std::move(data);
}
}
#endif