可以通过调用vmemalloc类型对象的括号运算符(len, name)分配大小为len,文件名为name的虚拟内存。
返回首地址的迭代器。
无需delete,程序结束后会自动清空文件,但是保留文件名
#include<bits/stdc++.h>
using namespace std;
namespace virtual_memory{
/**
* small functions to be called by filename.
*/
void file_reset(string fname, size_t siz){
ofstream f(fname.c_str(), ios::binary| ios::out | ios::trunc);
char val =0;
for(int i = 0; i < siz; ++i) f.write(&val, 1);
f.close();
}
void file_clear(string fname){
file_reset(fname, 0);
}
/**
* proxy of a file.
* fixed file size.
* if a file was opened, the name won't be change.
* only opened by a file.
* safe write/read
*/
struct proxy_file{
string fname;
fstream f;
size_t fsize;
using pos_type = fstream :: pos_type;
using off_type = fstream :: off_type;
using seekdir = fstream :: seekdir;
proxy_file(){
fsize = 0;
}
proxy_file(string str, size_t siz) : proxy_file(){
open(str, siz);
}
~proxy_file(){
file_clear(fname);
}
void open(string str, size_t siz){
assert(fname.empty() || str == fname);
fname = str;
fsize = siz;
file_reset(str, siz);
f.open(fname, ios :: binary | ios::out | ios::in);
assert(f.good());
}
void write_at(const char* str, size_t siz, off_type pos){
assert(0 <= pos && pos + siz <= fsize);
// cerr << "bef = " << f.tellp() << endl;
f.seekp(pos, ios :: beg);
// cerr << "fat = " << f.tellp() << endl;
f.write(str, siz);
}
void read_at(char * str, size_t siz, off_type pos){
assert(0 <= pos && pos + siz <= fsize);
f.seekg(pos, ios :: beg);
f.read(str, siz);
}
};
/**
* a pointer with a full information to read/write the file.
* with operator +, -, and so on.
* only check whether in the same file. uncheck the range.
*/
struct file_pointer{
proxy_file* file;
proxy_file :: off_type pos;
file_pointer() {
file = nullptr;
pos = 0;
}
file_pointer(proxy_file* file_, proxy_file :: off_type pos_) : file(file_), pos(pos_){}
friend ptrdiff_t operator - (const file_pointer& x, const file_pointer& y){
assert(x.file == y.file);
return x.pos - y.pos;
}
friend file_pointer operator + (file_pointer x, ptrdiff_t len){
x.pos += len;
return x;
}
friend file_pointer operator - (file_pointer x, ptrdiff_t len){
x.pos -= len;
return x;
}
};
/**
* a proxy to the proxy_file
* because random access is very slow, we have to accelerate it by buffer
* safe read/write
* safe bounds
*/
const int FBUF_SIZE = 2;
struct file_buf{
char buf[FBUF_SIZE];
file_pointer first; ptrdiff_t len;
file_buf(){
len = 0;
memset(buf,0, sizeof(buf));
}
~file_buf(){
write_through();
}
bool check_in(file_pointer p){
assert(p.file != nullptr);
return first.file == p.file && first.pos <= p.pos && p.pos < first.pos + len;
}
void write_through(){
if(first.file == nullptr) return;
first.file->write_at(buf, len, first.pos);
}
void read_through(){
if(first.file == nullptr) return;
first.file->read_at(buf, len, first.pos);
}
void init_buf(file_pointer p){
if(check_in(p)) return;
write_through();
assert(p.pos < (p.file->fsize));
first.file = p.file;
first.pos = p.pos - FBUF_SIZE / 2 < 0 ? 0 : p.pos - FBUF_SIZE / 2;
len = min(FBUF_SIZE, int(p.file->fsize - first.pos));
read_through();
}
size_t get_pos(file_pointer p){
init_buf(p);
return p.pos - first.pos;
}
void read(file_pointer p, char& val){
size_t pos = get_pos(p);
val = buf[pos];
}
void write(file_pointer p, char val){
size_t pos = get_pos(p);
buf[pos] = val;
}
};
struct file_view{
file_buf * buf;
file_pointer pos;
file_view(){
buf = nullptr;
}
file_view(file_buf * buf_, file_pointer pos_) : buf(buf_), pos(pos_) {};
void read(char &val){
assert(buf != nullptr);
buf->read(pos, val);
}
void write(char val){
assert(buf != nullptr);
buf->write(pos, val);
}
friend auto operator - (const file_view& x, const file_view& y){
assert(x.buf == y.buf);
return x.pos - y.pos;
}
friend file_view operator + (file_view x, ptrdiff_t len){
x.pos = x.pos + len;
return x;
}
friend file_view operator - (file_view x, ptrdiff_t len){
x.pos = x.pos- len;
return x;
}
};
struct proxy_char{
file_view f;
proxy_char(file_view f_) : f(f_){}
proxy_char& operator = (char val){
f.write(val);
return *this;
}
operator char(){
char val;
f.read(val);
return val;
}
};
struct file_iterator{
file_view f;
file_iterator(file_view f_) : f(f_){}
file_iterator(file_buf * buf_, file_pointer pos_) : file_iterator(file_view(buf_, pos_)) {
}
using iterator_category = random_access_iterator_tag;
using difference_type = ptrdiff_t;
using value_type = char;
using pointer = proxy_char*;
using reference = proxy_char&;
friend auto operator - (const file_iterator& x, const file_iterator& y){
return x.f - y.f;
}
friend file_iterator operator + (file_iterator x, ptrdiff_t len) {
x.f = x.f + len;
return x;
}
friend file_iterator operator - (file_iterator x, ptrdiff_t len) {
x.f = x.f- len;
return x;
}
file_iterator& operator += (ptrdiff_t len){
*this = *this + len;
return *this;
}
file_iterator& operator -= (ptrdiff_t len){
*this = *this - len;
return *this;
}
void operator ++(){
*this = *this + 1;
}
void operator --(){
*this = *this - 1;
}
proxy_char operator *(){
return proxy_char(f);
}
};
struct proxy_file_pool{
map<string, proxy_file> data;
proxy_file* get_file(string name){
assert(data.count(name));
return &data[name];
}
void create_file(string name, size_t siz){
assert(data.count(name) == false);
data[name].open(name, siz);
}
bool check_file(string name){
return data.count(name);
}
void erase_file(string name){
data.erase(name);
}
};
struct vmemalloc{
proxy_file_pool pool;
file_buf buf;
file_iterator operator ()(size_t len, string name){
pool.create_file(name, len);
return file_iterator(&buf, file_pointer(pool.get_file(name), 0));
}
};
}
using virtual_memory :: vmemalloc;
vmemalloc newnode;
const int N = 1e2+1;
auto npri = newnode(N, "1.txt");
int pri[N] = {};
void sieve(int len){
for(int i = 2; i <= len; ++i){
if(*(npri + i) == false) pri[++pri[0]] = i;
for(int j = 1; j <= pri[0] && i * pri[j] <= len; ++j){
*(npri + i * pri[j]) = true;
if(i % pri[j] == 0) break;
}
}
}
int main(){
sieve(100);
for(int i = 1; i <= pri[0]; ++i){
cout << pri[i] <<" ";
}
cout << endl;
return 0;
}
标签:return,name,pos,len,c++,file,buf,虚拟内存
From: https://www.cnblogs.com/cdsidi/p/17090510.html