clover: remove util/compat
Acked-by: Francisco Jerez <currojerez@riseup.net> Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
This commit is contained in:
@@ -45,7 +45,6 @@ CPP_SOURCES := \
|
|||||||
util/adaptor.hpp \
|
util/adaptor.hpp \
|
||||||
util/algebra.hpp \
|
util/algebra.hpp \
|
||||||
util/algorithm.hpp \
|
util/algorithm.hpp \
|
||||||
util/compat.hpp \
|
|
||||||
util/factor.hpp \
|
util/factor.hpp \
|
||||||
util/functional.hpp \
|
util/functional.hpp \
|
||||||
util/lazy.hpp \
|
util/lazy.hpp \
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
#include "api/util.hpp"
|
#include "api/util.hpp"
|
||||||
#include "core/program.hpp"
|
#include "core/program.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using namespace clover;
|
using namespace clover;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -94,12 +96,12 @@ clCreateProgramWithBinary(cl_context d_ctx, cl_uint n,
|
|||||||
return { CL_INVALID_VALUE, {} };
|
return { CL_INVALID_VALUE, {} };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
compat::istream::buffer_t bin(p, l);
|
std::stringbuf bin( { (char*)p, l } );
|
||||||
compat::istream s(bin);
|
std::istream s(&bin);
|
||||||
|
|
||||||
return { CL_SUCCESS, module::deserialize(s) };
|
return { CL_SUCCESS, module::deserialize(s) };
|
||||||
|
|
||||||
} catch (compat::istream::error &e) {
|
} catch (std::istream::failure &e) {
|
||||||
return { CL_INVALID_BINARY, {} };
|
return { CL_INVALID_BINARY, {} };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -279,10 +281,10 @@ clGetProgramInfo(cl_program d_prog, cl_program_info param,
|
|||||||
|
|
||||||
case CL_PROGRAM_BINARIES:
|
case CL_PROGRAM_BINARIES:
|
||||||
buf.as_matrix<unsigned char>() = map([&](const device &dev) {
|
buf.as_matrix<unsigned char>() = map([&](const device &dev) {
|
||||||
compat::ostream::buffer_t bin;
|
std::stringbuf bin;
|
||||||
compat::ostream s(bin);
|
std::ostream s(&bin);
|
||||||
prog.binary(dev).serialize(s);
|
prog.binary(dev).serialize(s);
|
||||||
return bin;
|
return bin.str();
|
||||||
},
|
},
|
||||||
prog.devices());
|
prog.devices());
|
||||||
break;
|
break;
|
||||||
|
@@ -23,14 +23,12 @@
|
|||||||
#ifndef CLOVER_CORE_COMPILER_HPP
|
#ifndef CLOVER_CORE_COMPILER_HPP
|
||||||
#define CLOVER_CORE_COMPILER_HPP
|
#define CLOVER_CORE_COMPILER_HPP
|
||||||
|
|
||||||
#include "util/compat.hpp"
|
|
||||||
#include "core/error.hpp"
|
#include "core/error.hpp"
|
||||||
#include "core/module.hpp"
|
#include "core/module.hpp"
|
||||||
#include "pipe/p_defines.h"
|
#include "pipe/p_defines.h"
|
||||||
|
|
||||||
namespace clover {
|
namespace clover {
|
||||||
typedef compat::vector<std::pair<std::string,
|
typedef std::vector<std::pair<std::string, std::string> > header_map;
|
||||||
std::string> > header_map;
|
|
||||||
|
|
||||||
module compile_program_llvm(const std::string &source,
|
module compile_program_llvm(const std::string &source,
|
||||||
const header_map &headers,
|
const header_map &headers,
|
||||||
|
@@ -27,8 +27,6 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "util/compat.hpp"
|
|
||||||
|
|
||||||
namespace clover {
|
namespace clover {
|
||||||
class command_queue;
|
class command_queue;
|
||||||
class context;
|
class context;
|
||||||
|
@@ -192,7 +192,7 @@ kernel::exec_context::bind(intrusive_ptr<command_queue> _q,
|
|||||||
if (st)
|
if (st)
|
||||||
_q->pipe->delete_compute_state(_q->pipe, st);
|
_q->pipe->delete_compute_state(_q->pipe, st);
|
||||||
|
|
||||||
cs.prog = msec.data.begin();
|
cs.prog = &(msec.data[0]);
|
||||||
cs.req_local_mem = mem_local;
|
cs.req_local_mem = mem_local;
|
||||||
cs.req_input_mem = input.size();
|
cs.req_input_mem = input.size();
|
||||||
st = q->pipe->create_compute_state(q->pipe, &cs);
|
st = q->pipe->create_compute_state(q->pipe, &cs);
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "core/module.hpp"
|
#include "core/module.hpp"
|
||||||
|
|
||||||
@@ -33,20 +34,20 @@ namespace {
|
|||||||
/// Serialize the specified object.
|
/// Serialize the specified object.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void
|
void
|
||||||
_proc(compat::ostream &os, const T &x) {
|
_proc(std::ostream &os, const T &x) {
|
||||||
_serializer<T>::proc(os, x);
|
_serializer<T>::proc(os, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize the specified object.
|
/// Deserialize the specified object.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void
|
void
|
||||||
_proc(compat::istream &is, T &x) {
|
_proc(std::istream &is, T &x) {
|
||||||
_serializer<T>::proc(is, x);
|
_serializer<T>::proc(is, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T
|
T
|
||||||
_proc(compat::istream &is) {
|
_proc(std::istream &is) {
|
||||||
T x;
|
T x;
|
||||||
_serializer<T>::proc(is, x);
|
_serializer<T>::proc(is, x);
|
||||||
return x;
|
return x;
|
||||||
@@ -64,12 +65,12 @@ namespace {
|
|||||||
struct _serializer<T, typename std::enable_if<
|
struct _serializer<T, typename std::enable_if<
|
||||||
std::is_scalar<T>::value>::type> {
|
std::is_scalar<T>::value>::type> {
|
||||||
static void
|
static void
|
||||||
proc(compat::ostream &os, const T &x) {
|
proc(std::ostream &os, const T &x) {
|
||||||
os.write(reinterpret_cast<const char *>(&x), sizeof(x));
|
os.write(reinterpret_cast<const char *>(&x), sizeof(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proc(compat::istream &is, T &x) {
|
proc(std::istream &is, T &x) {
|
||||||
is.read(reinterpret_cast<char *>(&x), sizeof(x));
|
is.read(reinterpret_cast<char *>(&x), sizeof(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,11 +82,11 @@ namespace {
|
|||||||
|
|
||||||
/// (De)serialize a vector.
|
/// (De)serialize a vector.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct _serializer<compat::vector<T>,
|
struct _serializer<std::vector<T>,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
!std::is_scalar<T>::value>::type> {
|
!std::is_scalar<T>::value>::type> {
|
||||||
static void
|
static void
|
||||||
proc(compat::ostream &os, const compat::vector<T> &v) {
|
proc(std::ostream &os, const std::vector<T> &v) {
|
||||||
_proc<uint32_t>(os, v.size());
|
_proc<uint32_t>(os, v.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < v.size(); i++)
|
for (size_t i = 0; i < v.size(); i++)
|
||||||
@@ -93,7 +94,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proc(compat::istream &is, compat::vector<T> &v) {
|
proc(std::istream &is, std::vector<T> &v) {
|
||||||
v.resize(_proc<uint32_t>(is));
|
v.resize(_proc<uint32_t>(is));
|
||||||
|
|
||||||
for (size_t i = 0; i < v.size(); i++)
|
for (size_t i = 0; i < v.size(); i++)
|
||||||
@@ -101,7 +102,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proc(module::size_t &sz, const compat::vector<T> &v) {
|
proc(module::size_t &sz, const std::vector<T> &v) {
|
||||||
sz += sizeof(uint32_t);
|
sz += sizeof(uint32_t);
|
||||||
|
|
||||||
for (size_t i = 0; i < v.size(); i++)
|
for (size_t i = 0; i < v.size(); i++)
|
||||||
@@ -110,25 +111,25 @@ namespace {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct _serializer<compat::vector<T>,
|
struct _serializer<std::vector<T>,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
std::is_scalar<T>::value>::type> {
|
std::is_scalar<T>::value>::type> {
|
||||||
static void
|
static void
|
||||||
proc(compat::ostream &os, const compat::vector<T> &v) {
|
proc(std::ostream &os, const std::vector<T> &v) {
|
||||||
_proc<uint32_t>(os, v.size());
|
_proc<uint32_t>(os, v.size());
|
||||||
os.write(reinterpret_cast<const char *>(v.begin()),
|
os.write(reinterpret_cast<const char *>(&v[0]),
|
||||||
v.size() * sizeof(T));
|
v.size() * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proc(compat::istream &is, compat::vector<T> &v) {
|
proc(std::istream &is, std::vector<T> &v) {
|
||||||
v.resize(_proc<uint32_t>(is));
|
v.resize(_proc<uint32_t>(is));
|
||||||
is.read(reinterpret_cast<char *>(v.begin()),
|
is.read(reinterpret_cast<char *>(&v[0]),
|
||||||
v.size() * sizeof(T));
|
v.size() * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proc(module::size_t &sz, const compat::vector<T> &v) {
|
proc(module::size_t &sz, const std::vector<T> &v) {
|
||||||
sz += sizeof(uint32_t) + sizeof(T) * v.size();
|
sz += sizeof(uint32_t) + sizeof(T) * v.size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -137,13 +138,13 @@ namespace {
|
|||||||
template<>
|
template<>
|
||||||
struct _serializer<std::string> {
|
struct _serializer<std::string> {
|
||||||
static void
|
static void
|
||||||
proc(compat::ostream &os, const std::string &s) {
|
proc(std::ostream &os, const std::string &s) {
|
||||||
_proc<uint32_t>(os, s.size());
|
_proc<uint32_t>(os, s.size());
|
||||||
os.write(&s[0], s.size() * sizeof(std::string::value_type));
|
os.write(&s[0], s.size() * sizeof(std::string::value_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proc(compat::istream &is, std::string &s) {
|
proc(std::istream &is, std::string &s) {
|
||||||
s.resize(_proc<uint32_t>(is));
|
s.resize(_proc<uint32_t>(is));
|
||||||
is.read(&s[0], s.size() * sizeof(std::string::value_type));
|
is.read(&s[0], s.size() * sizeof(std::string::value_type));
|
||||||
}
|
}
|
||||||
@@ -209,12 +210,12 @@ namespace {
|
|||||||
|
|
||||||
namespace clover {
|
namespace clover {
|
||||||
void
|
void
|
||||||
module::serialize(compat::ostream &os) const {
|
module::serialize(std::ostream &os) const {
|
||||||
_proc(os, *this);
|
_proc(os, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
module
|
module
|
||||||
module::deserialize(compat::istream &is) {
|
module::deserialize(std::istream &is) {
|
||||||
return _proc<module>(is);
|
return _proc<module>(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,7 +23,8 @@
|
|||||||
#ifndef CLOVER_CORE_MODULE_HPP
|
#ifndef CLOVER_CORE_MODULE_HPP
|
||||||
#define CLOVER_CORE_MODULE_HPP
|
#define CLOVER_CORE_MODULE_HPP
|
||||||
|
|
||||||
#include "util/compat.hpp"
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace clover {
|
namespace clover {
|
||||||
struct module {
|
struct module {
|
||||||
@@ -40,14 +41,14 @@ namespace clover {
|
|||||||
};
|
};
|
||||||
|
|
||||||
section(resource_id id, enum type type, size_t size,
|
section(resource_id id, enum type type, size_t size,
|
||||||
const compat::vector<char> &data) :
|
const std::vector<char> &data) :
|
||||||
id(id), type(type), size(size), data(data) { }
|
id(id), type(type), size(size), data(data) { }
|
||||||
section() : id(0), type(text), size(0), data() { }
|
section() : id(0), type(text), size(0), data() { }
|
||||||
|
|
||||||
resource_id id;
|
resource_id id;
|
||||||
type type;
|
type type;
|
||||||
size_t size;
|
size_t size;
|
||||||
compat::vector<char> data;
|
std::vector<char> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct argument {
|
struct argument {
|
||||||
@@ -101,22 +102,22 @@ namespace clover {
|
|||||||
|
|
||||||
struct symbol {
|
struct symbol {
|
||||||
symbol(const std::string &name, resource_id section,
|
symbol(const std::string &name, resource_id section,
|
||||||
size_t offset, const compat::vector<argument> &args) :
|
size_t offset, const std::vector<argument> &args) :
|
||||||
name(name), section(section), offset(offset), args(args) { }
|
name(name), section(section), offset(offset), args(args) { }
|
||||||
symbol() : name(), section(0), offset(0), args() { }
|
symbol() : name(), section(0), offset(0), args() { }
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
resource_id section;
|
resource_id section;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
compat::vector<argument> args;
|
std::vector<argument> args;
|
||||||
};
|
};
|
||||||
|
|
||||||
void serialize(compat::ostream &os) const;
|
void serialize(std::ostream &os) const;
|
||||||
static module deserialize(compat::istream &is);
|
static module deserialize(std::istream &is);
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
compat::vector<symbol> syms;
|
std::vector<symbol> syms;
|
||||||
compat::vector<section> secs;
|
std::vector<section> secs;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -106,7 +106,7 @@ program::build_log(const device &dev) const {
|
|||||||
return _logs.count(&dev) ? _logs.find(&dev)->second : "";
|
return _logs.count(&dev) ? _logs.find(&dev)->second : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const compat::vector<module::symbol> &
|
const std::vector<module::symbol> &
|
||||||
program::symbols() const {
|
program::symbols() const {
|
||||||
if (_binaries.empty())
|
if (_binaries.empty())
|
||||||
throw error(CL_INVALID_PROGRAM_EXECUTABLE);
|
throw error(CL_INVALID_PROGRAM_EXECUTABLE);
|
||||||
|
@@ -60,7 +60,7 @@ namespace clover {
|
|||||||
std::string build_opts(const device &dev) const;
|
std::string build_opts(const device &dev) const;
|
||||||
std::string build_log(const device &dev) const;
|
std::string build_log(const device &dev) const;
|
||||||
|
|
||||||
const compat::vector<module::symbol> &symbols() const;
|
const std::vector<module::symbol> &symbols() const;
|
||||||
|
|
||||||
unsigned kernel_ref_count() const;
|
unsigned kernel_ref_count() const;
|
||||||
|
|
||||||
|
@@ -340,11 +340,11 @@ namespace {
|
|||||||
PM.run(*mod);
|
PM.run(*mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
compat::vector<module::argument>
|
std::vector<module::argument>
|
||||||
get_kernel_args(const llvm::Module *mod, const std::string &kernel_name,
|
get_kernel_args(const llvm::Module *mod, const std::string &kernel_name,
|
||||||
const clang::LangAS::Map &address_spaces) {
|
const clang::LangAS::Map &address_spaces) {
|
||||||
|
|
||||||
compat::vector<module::argument> args;
|
std::vector<module::argument> args;
|
||||||
llvm::Function *kernel_func = mod->getFunction(kernel_name);
|
llvm::Function *kernel_func = mod->getFunction(kernel_name);
|
||||||
|
|
||||||
llvm::DataLayout TD(mod);
|
llvm::DataLayout TD(mod);
|
||||||
@@ -449,15 +449,16 @@ namespace {
|
|||||||
|
|
||||||
for (unsigned i = 0; i < kernels.size(); ++i) {
|
for (unsigned i = 0; i < kernels.size(); ++i) {
|
||||||
std::string kernel_name = kernels[i]->getName();
|
std::string kernel_name = kernels[i]->getName();
|
||||||
compat::vector<module::argument> args =
|
std::vector<module::argument> args =
|
||||||
get_kernel_args(mod, kernel_name, address_spaces);
|
get_kernel_args(mod, kernel_name, address_spaces);
|
||||||
|
|
||||||
m.syms.push_back(module::symbol(kernel_name, 0, i, args ));
|
m.syms.push_back(module::symbol(kernel_name, 0, i, args ));
|
||||||
}
|
}
|
||||||
|
|
||||||
header.num_bytes = llvm_bitcode.size();
|
header.num_bytes = llvm_bitcode.size();
|
||||||
std::string data;
|
std::vector<char> data;
|
||||||
data.insert(0, (char*)(&header), sizeof(header));
|
data.insert(data.end(), (char*)(&header),
|
||||||
|
(char*)(&header) + sizeof(header));
|
||||||
data.insert(data.end(), llvm_bitcode.begin(),
|
data.insert(data.end(), llvm_bitcode.begin(),
|
||||||
llvm_bitcode.end());
|
llvm_bitcode.end());
|
||||||
m.secs.push_back(module::section(0, module::section::text,
|
m.secs.push_back(module::section(0, module::section::text,
|
||||||
@@ -622,15 +623,16 @@ namespace {
|
|||||||
|
|
||||||
// Store the generated ELF binary in the module's text section.
|
// Store the generated ELF binary in the module's text section.
|
||||||
header.num_bytes = code.size();
|
header.num_bytes = code.size();
|
||||||
std::string data;
|
std::vector<char> data;
|
||||||
data.append((char*)(&header), sizeof(header));
|
data.insert(data.end(), (char*)(&header),
|
||||||
data.append(code.begin(), code.end());
|
(char*)(&header) + sizeof(header));
|
||||||
|
data.insert(data.end(), code.begin(), code.end());
|
||||||
m.secs.push_back(module::section(0, module::section::text,
|
m.secs.push_back(module::section(0, module::section::text,
|
||||||
header.num_bytes, data));
|
header.num_bytes, data));
|
||||||
|
|
||||||
for (std::map<std::string, unsigned>::iterator i = kernel_offsets.begin(),
|
for (std::map<std::string, unsigned>::iterator i = kernel_offsets.begin(),
|
||||||
e = kernel_offsets.end(); i != e; ++i) {
|
e = kernel_offsets.end(); i != e; ++i) {
|
||||||
compat::vector<module::argument> args =
|
std::vector<module::argument> args =
|
||||||
get_kernel_args(mod, i->first, address_spaces);
|
get_kernel_args(mod, i->first, address_spaces);
|
||||||
m.syms.push_back(module::symbol(i->first, 0, i->second, args ));
|
m.syms.push_back(module::symbol(i->first, 0, i->second, args ));
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,7 @@ namespace {
|
|||||||
std::istringstream ts(line);
|
std::istringstream ts(line);
|
||||||
std::string name, tok;
|
std::string name, tok;
|
||||||
module::size_t offset;
|
module::size_t offset;
|
||||||
compat::vector<module::argument> args;
|
std::vector<module::argument> args;
|
||||||
|
|
||||||
if (!(ts >> name))
|
if (!(ts >> name))
|
||||||
continue;
|
continue;
|
||||||
@@ -83,7 +83,8 @@ namespace {
|
|||||||
throw build_error("translate failed");
|
throw build_error("translate failed");
|
||||||
|
|
||||||
unsigned sz = tgsi_num_tokens(prog) * sizeof(tgsi_token);
|
unsigned sz = tgsi_num_tokens(prog) * sizeof(tgsi_token);
|
||||||
m.secs.push_back({ 0, module::section::text, sz, { (char *)prog, sz } });
|
std::vector<char> data( (char *)prog, (char *)prog + sz );
|
||||||
|
m.secs.push_back({ 0, module::section::text, sz, data });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,313 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2012 Francisco Jerez
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
|
||||||
// to deal in the Software without restriction, including without limitation
|
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
// OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef CLOVER_UTIL_COMPAT_HPP
|
|
||||||
#define CLOVER_UTIL_COMPAT_HPP
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <string>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
namespace clover {
|
|
||||||
namespace compat {
|
|
||||||
// XXX - For cases where we can't rely on STL... I.e. the
|
|
||||||
// interface between code compiled as C++98 and C++11
|
|
||||||
// source. Get rid of this as soon as everything can be
|
|
||||||
// compiled as C++11.
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template<typename R, typename S>
|
|
||||||
bool
|
|
||||||
ranges_equal(const R &a, const S &b) {
|
|
||||||
if (a.size() != b.size())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < a.size(); ++i)
|
|
||||||
if (a[i] != b[i])
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class vector {
|
|
||||||
protected:
|
|
||||||
static T *
|
|
||||||
alloc(int n, const T *q, int m) {
|
|
||||||
T *p = reinterpret_cast<T *>(std::malloc(n * sizeof(T)));
|
|
||||||
|
|
||||||
for (int i = 0; i < m; ++i)
|
|
||||||
new(&p[i]) T(q[i]);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
free(int n, T *p) {
|
|
||||||
for (int i = 0; i < n; ++i)
|
|
||||||
p[i].~T();
|
|
||||||
|
|
||||||
std::free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef T *iterator;
|
|
||||||
typedef const T *const_iterator;
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T &reference;
|
|
||||||
typedef const T &const_reference;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
|
|
||||||
vector() : p(NULL), _size(0), _capacity(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
vector(const vector &v) :
|
|
||||||
p(alloc(v._size, v.p, v._size)),
|
|
||||||
_size(v._size), _capacity(v._size) {
|
|
||||||
}
|
|
||||||
|
|
||||||
vector(const_iterator p, size_type n) :
|
|
||||||
p(alloc(n, p, n)), _size(n), _capacity(n) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename C>
|
|
||||||
vector(const C &v) :
|
|
||||||
p(alloc(v.size(), NULL, 0)), _size(0),
|
|
||||||
_capacity(v.size()) {
|
|
||||||
for (typename C::const_iterator it = v.begin(); it != v.end(); ++it)
|
|
||||||
new(&p[_size++]) T(*it);
|
|
||||||
}
|
|
||||||
|
|
||||||
~vector() {
|
|
||||||
free(_size, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
vector &
|
|
||||||
operator=(const vector &v) {
|
|
||||||
free(_size, p);
|
|
||||||
|
|
||||||
p = alloc(v._size, v.p, v._size);
|
|
||||||
_size = v._size;
|
|
||||||
_capacity = v._size;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(const vector &v) const {
|
|
||||||
return detail::ranges_equal(*this, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
reserve(size_type n) {
|
|
||||||
if (_capacity < n) {
|
|
||||||
T *q = alloc(n, p, _size);
|
|
||||||
free(_size, p);
|
|
||||||
|
|
||||||
p = q;
|
|
||||||
_capacity = n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
resize(size_type n, T x = T()) {
|
|
||||||
if (n <= _size) {
|
|
||||||
for (size_type i = n; i < _size; ++i)
|
|
||||||
p[i].~T();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
reserve(n);
|
|
||||||
|
|
||||||
for (size_type i = _size; i < n; ++i)
|
|
||||||
new(&p[i]) T(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
_size = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
push_back(const T &x) {
|
|
||||||
reserve(_size + 1);
|
|
||||||
new(&p[_size]) T(x);
|
|
||||||
++_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type
|
|
||||||
size() const {
|
|
||||||
return _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type
|
|
||||||
capacity() const {
|
|
||||||
return _capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator
|
|
||||||
begin() {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator
|
|
||||||
begin() const {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator
|
|
||||||
end() {
|
|
||||||
return p + _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator
|
|
||||||
end() const {
|
|
||||||
return p + _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference
|
|
||||||
operator[](size_type i) {
|
|
||||||
return p[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reference
|
|
||||||
operator[](size_type i) const {
|
|
||||||
return p[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
iterator p;
|
|
||||||
size_type _size;
|
|
||||||
size_type _capacity;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class vector_ref {
|
|
||||||
public:
|
|
||||||
typedef T *iterator;
|
|
||||||
typedef const T *const_iterator;
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T &reference;
|
|
||||||
typedef const T &const_reference;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
|
|
||||||
vector_ref(iterator p, size_type n) : p(p), n(n) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename C>
|
|
||||||
vector_ref(C &v) : p(&*v.begin()), n(v.size()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(const vector_ref &v) const {
|
|
||||||
return detail::ranges_equal(*this, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type
|
|
||||||
size() const {
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator
|
|
||||||
begin() {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator
|
|
||||||
begin() const {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator
|
|
||||||
end() {
|
|
||||||
return p + n;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator
|
|
||||||
end() const {
|
|
||||||
return p + n;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference
|
|
||||||
operator[](int i) {
|
|
||||||
return p[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reference
|
|
||||||
operator[](int i) const {
|
|
||||||
return p[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
iterator p;
|
|
||||||
size_type n;
|
|
||||||
};
|
|
||||||
|
|
||||||
class istream {
|
|
||||||
public:
|
|
||||||
typedef vector_ref<const unsigned char> buffer_t;
|
|
||||||
|
|
||||||
class error {
|
|
||||||
public:
|
|
||||||
virtual ~error() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
istream(const buffer_t &buf) : buf(buf), offset(0) {}
|
|
||||||
|
|
||||||
void
|
|
||||||
read(char *p, size_t n) {
|
|
||||||
if (offset + n > buf.size())
|
|
||||||
throw error();
|
|
||||||
|
|
||||||
std::memcpy(p, buf.begin() + offset, n);
|
|
||||||
offset += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const buffer_t &buf;
|
|
||||||
size_t offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ostream {
|
|
||||||
public:
|
|
||||||
typedef vector<unsigned char> buffer_t;
|
|
||||||
|
|
||||||
ostream(buffer_t &buf) : buf(buf), offset(buf.size()) {}
|
|
||||||
|
|
||||||
void
|
|
||||||
write(const char *p, size_t n) {
|
|
||||||
buf.resize(offset + n);
|
|
||||||
std::memcpy(buf.begin() + offset, p, n);
|
|
||||||
offset += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
buffer_t &buf;
|
|
||||||
size_t offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
Reference in New Issue
Block a user