update to new style everywhere

master
Daniel Kolesa 2017-02-16 20:39:05 +01:00
parent 68c19a80fb
commit 8e40841219
17 changed files with 413 additions and 710 deletions

View File

@ -13,7 +13,7 @@ struct Foo {
/* implementing formatting for custom objects - external function */ /* implementing formatting for custom objects - external function */
template<typename R> template<typename R>
void to_format(Foo const &, R &writer, FormatSpec const &fs) { void to_format(Foo const &, R &writer, format_spec const &fs) {
switch (fs.spec()) { switch (fs.spec()) {
case 'i': case 'i':
writer.put_string("Foo1"); writer.put_string("Foo1");
@ -27,7 +27,7 @@ void to_format(Foo const &, R &writer, FormatSpec const &fs) {
struct Bar { struct Bar {
/* implementing formatting for custom objects - method */ /* implementing formatting for custom objects - method */
template<typename R> template<typename R>
void to_format(R &writer, FormatSpec const &fs) const { void to_format(R &writer, format_spec const &fs) const {
switch (fs.spec()) { switch (fs.spec()) {
case 'i': case 'i':
writer.put_string("Bar1"); writer.put_string("Bar1");

View File

@ -5,10 +5,10 @@
using namespace ostd; using namespace ostd;
void list_dirs(string_range path, int off = 0) { void list_dirs(string_range path, int off = 0) {
DirectoryStream ds{path}; directory_stream ds{path};
/* iterate all items in directory */ /* iterate all items in directory */
for (auto v: iter(ds)) { for (auto v: iter(ds)) {
if (v.type() != FileType::directory) { if (v.type() != file_type::DIRECTORY) {
continue; continue;
} }
for_each(range(off), [](int) { write(' '); }); for_each(range(off), [](int) { write(' '); });

View File

@ -4,17 +4,17 @@
using namespace ostd; using namespace ostd;
struct SignalTest { struct signal_test {
/* const on the class means that a const reference to the event /* const on the class means that a const reference to the event
* can actually emit (in that case, the reference passed to each * can actually emit (in that case, the reference passed to each
* callback will always be const to make sure nothing changes) * callback will always be const to make sure nothing changes)
*/ */
Signal<SignalTest const, int, string_range> on_simple = this; signal<signal_test const, int, string_range> on_simple = this;
Signal<SignalTest , float > on_param = this; signal<signal_test , float > on_param = this;
SignalTest(): p_param(3.14f) { signal_test(): p_param(3.14f) {
/* we can connect methods */ /* we can connect methods */
on_simple.connect(&SignalTest::simple_method); on_simple.connect(&signal_test::simple_method);
writeln("constructed signal test"); writeln("constructed signal test");
} }
@ -41,7 +41,7 @@ private:
int main() { int main() {
writeln("=== program start ==="); writeln("=== program start ===");
SignalTest st; signal_test st;
int test = 42; int test = 42;
@ -49,7 +49,7 @@ int main() {
* this callback can access "test" easily and it will still work * this callback can access "test" easily and it will still work
*/ */
auto idx = st.on_simple.connect([&]( auto idx = st.on_simple.connect([&](
SignalTest const &, int v, string_range str signal_test const &, int v, string_range str
) { ) {
writefln("and lambda test: %d, %s (%d)", v, str, test); writefln("and lambda test: %d, %s (%d)", v, str, test);
}); });
@ -67,8 +67,8 @@ int main() {
writeln("--- set value ---"); writeln("--- set value ---");
st.set_param(6.28f); st.set_param(6.28f);
/* the reference to SignalTest here is mutable */ /* the reference to signal_test here is mutable */
st.on_param.connect([](SignalTest &self, float oldval) { st.on_param.connect([](signal_test &self, float oldval) {
writeln("value changed..."); writeln("value changed...");
writefln( writefln(
" old value: %f, new value: %f", oldval, self.get_param() " old value: %f, new value: %f", oldval, self.get_param()

View File

@ -8,17 +8,17 @@ void print_result(uint32_t x) {
} }
int main() { int main() {
FileStream wtest{"test.bin", StreamMode::write}; file_stream wtest{"test.bin", stream_mode::WRITE};
copy( copy(
iter({ 0xABCD1214, 0xBADC3264, 0xDEADBEEF, 0xBEEFDEAD }), iter({ 0xABCD1214, 0xBADC3264, 0xDEADBEEF, 0xBEEFDEAD }),
wtest.iter<uint32_t>() wtest.iter<uint32_t>()
); );
wtest.close(); wtest.close();
FileStream rtest{"test.bin"}; file_stream rtest{"test.bin"};
writefln("stream size: %d", rtest.size()); writefln("stream size: %d", rtest.size());
for (uint32_t x: map(rtest.iter<uint32_t>(), FromBigEndian<uint32_t>())) { for (uint32_t x: map(rtest.iter<uint32_t>(), from_big_endian<uint32_t>())) {
print_result(x); print_result(x);
} }

View File

@ -7,7 +7,7 @@ using namespace ostd;
int main() { int main() {
writeln("writing sample file..."); writeln("writing sample file...");
FileStream wtest{"test.txt", StreamMode::write}; file_stream wtest{"test.txt", stream_mode::WRITE};
std::string smpl = std::string smpl =
"This is a test file for later read.\n" "This is a test file for later read.\n"
@ -20,7 +20,7 @@ int main() {
copy(iter(smpl), wtest.iter()); copy(iter(smpl), wtest.iter());
wtest.close(); wtest.close();
FileStream test{"test.txt"}; file_stream test{"test.txt"};
writeln("## WHOLE FILE READ ##\n"); writeln("## WHOLE FILE READ ##\n");

View File

@ -10,9 +10,9 @@
#include <utility> #include <utility>
#include <functional> #include <functional>
#include <type_traits>
#include "ostd/range.hh" #include "ostd/range.hh"
#include "ostd/utility.hh"
namespace ostd { namespace ostd {

View File

@ -1,4 +1,4 @@
/* Signals/slots for OctaSTD. /* signals/slots for OctaSTD.
* *
* This file is part of OctaSTD. See COPYING.md for futher information. * This file is part of OctaSTD. See COPYING.md for futher information.
*/ */
@ -7,17 +7,16 @@
#define OSTD_EVENT_HH #define OSTD_EVENT_HH
#include <functional> #include <functional>
#include <utility>
#include "ostd/utility.hh"
namespace ostd { namespace ostd {
namespace detail { namespace detail {
template<typename C, typename ...A> template<typename C, typename ...A>
struct SignalBase { struct signal_base {
SignalBase(C *cl): p_class(cl), p_funcs(nullptr), p_nfuncs(0) {} signal_base(C *cl): p_class(cl), p_funcs(nullptr), p_nfuncs(0) {}
SignalBase(SignalBase const &ev): signal_base(signal_base const &ev):
p_class(ev.p_class), p_nfuncs(ev.p_nfuncs) p_class(ev.p_class), p_nfuncs(ev.p_nfuncs)
{ {
using func_t = std::function<void(C &, A...)>; using func_t = std::function<void(C &, A...)>;
@ -28,13 +27,13 @@ namespace detail {
p_funcs = nbuf; p_funcs = nbuf;
} }
SignalBase(SignalBase &&ev): signal_base(signal_base &&ev):
p_class(nullptr), p_funcs(nullptr), p_nfuncs(0) p_class(nullptr), p_funcs(nullptr), p_nfuncs(0)
{ {
swap(ev); swap(ev);
} }
SignalBase &operator=(SignalBase const &ev) { signal_base &operator=(signal_base const &ev) {
using func_t = std::function<void(C &, A...)>; using func_t = std::function<void(C &, A...)>;
p_class = ev.p_class; p_class = ev.p_class;
p_nfuncs = ev.p_nfuncs; p_nfuncs = ev.p_nfuncs;
@ -47,12 +46,12 @@ namespace detail {
return *this; return *this;
} }
SignalBase &operator=(SignalBase &&ev) { signal_base &operator=(signal_base &&ev) {
swap(ev); swap(ev);
return *this; return *this;
} }
~SignalBase() { clear(); } ~signal_base() { clear(); }
void clear() { void clear() {
for (size_t i = 0; i < p_nfuncs; ++i) { for (size_t i = 0; i < p_nfuncs; ++i) {
@ -115,7 +114,7 @@ namespace detail {
return ocl; return ocl;
} }
void swap(SignalBase &ev) { void swap(signal_base &ev) {
using std::swap; using std::swap;
swap(p_class, ev.p_class); swap(p_class, ev.p_class);
swap(p_funcs, ev.p_funcs); swap(p_funcs, ev.p_funcs);
@ -130,21 +129,21 @@ namespace detail {
} /* namespace detail */ } /* namespace detail */
template<typename C, typename ...A> template<typename C, typename ...A>
struct Signal { struct signal {
private: private:
using Base = detail::SignalBase<C, A...>; using base_t = detail::signal_base<C, A...>;
Base p_base; base_t p_base;
public: public:
Signal(C *cl): p_base(cl) {} signal(C *cl): p_base(cl) {}
Signal(Signal const &ev): p_base(ev.p_base) {} signal(signal const &ev): p_base(ev.p_base) {}
Signal(Signal &&ev): p_base(std::move(ev.p_base)) {} signal(signal &&ev): p_base(std::move(ev.p_base)) {}
Signal &operator=(Signal const &ev) { signal &operator=(signal const &ev) {
p_base = ev.p_base; p_base = ev.p_base;
return *this; return *this;
} }
Signal &operator=(Signal &&ev) { signal &operator=(signal &&ev) {
p_base = std::move(ev.p_base); p_base = std::move(ev.p_base);
return *this; return *this;
} }
@ -165,25 +164,25 @@ public:
C *get_class() const { return p_base.get_class(); } C *get_class() const { return p_base.get_class(); }
C *set_class(C *cl) { return p_base.set_class(cl); } C *set_class(C *cl) { return p_base.set_class(cl); }
void swap(Signal &ev) { p_base.swap(ev.p_base); } void swap(signal &ev) { p_base.swap(ev.p_base); }
}; };
template<typename C, typename ...A> template<typename C, typename ...A>
struct Signal<C const, A...> { struct signal<C const, A...> {
private: private:
using Base = detail::SignalBase<C const, A...>; using base_t = detail::signal_base<C const, A...>;
Base p_base; base_t p_base;
public: public:
Signal(C *cl): p_base(cl) {} signal(C *cl): p_base(cl) {}
Signal(Signal const &ev): p_base(ev.p_base) {} signal(signal const &ev): p_base(ev.p_base) {}
Signal(Signal &&ev): p_base(std::move(ev.p_base)) {} signal(signal &&ev): p_base(std::move(ev.p_base)) {}
Signal &operator=(Signal const &ev) { signal &operator=(signal const &ev) {
p_base = ev.p_base; p_base = ev.p_base;
return *this; return *this;
} }
Signal &operator=(Signal &&ev) { signal &operator=(signal &&ev) {
p_base = std::move(ev.p_base); p_base = std::move(ev.p_base);
return *this; return *this;
} }
@ -204,11 +203,11 @@ public:
C *get_class() const { return p_base.get_class(); } C *get_class() const { return p_base.get_class(); }
C *set_class(C *cl) { return p_base.set_class(cl); } C *set_class(C *cl) { return p_base.set_class(cl); }
void swap(Signal &ev) { p_base.swap(ev.p_base); } void swap(signal &ev) { p_base.swap(ev.p_base); }
}; };
template<typename C, typename ...A> template<typename C, typename ...A>
inline void swap(Signal<C, A...> &a, Signal<C, A...> &b) { inline void swap(signal<C, A...> &a, signal<C, A...> &b) {
a.swap(b); a.swap(b);
} }

View File

@ -27,11 +27,11 @@
namespace ostd { namespace ostd {
enum class FileType { enum class file_type {
unknown, regular, fifo, character, directory, block, symlink, socket UNKNOWN, REGULAR, FIFO, CHARACTER, DIRECTORY, BLOCK, SYMLINK, SOCKET
}; };
struct FileInfo; struct file_info;
#ifdef OSTD_PLATFORM_WIN32 #ifdef OSTD_PLATFORM_WIN32
static constexpr char PathSeparator = '\\'; static constexpr char PathSeparator = '\\';
@ -54,30 +54,30 @@ inline void path_normalize(char_range) {
/* TODO */ /* TODO */
} }
struct FileInfo { struct file_info {
FileInfo() {} file_info() {}
FileInfo(FileInfo const &i): file_info(file_info const &i):
p_slash(i.p_slash), p_dot(i.p_dot), p_type(i.p_type), p_slash(i.p_slash), p_dot(i.p_dot), p_type(i.p_type),
p_path(i.p_path), p_atime(i.p_atime), p_mtime(i.p_mtime), p_path(i.p_path), p_atime(i.p_atime), p_mtime(i.p_mtime),
p_ctime(i.p_ctime) p_ctime(i.p_ctime)
{} {}
FileInfo(FileInfo &&i): file_info(file_info &&i):
p_slash(i.p_slash), p_dot(i.p_dot), p_type(i.p_type), p_slash(i.p_slash), p_dot(i.p_dot), p_type(i.p_type),
p_path(std::move(i.p_path)), p_atime(i.p_atime), p_mtime(i.p_mtime), p_path(std::move(i.p_path)), p_atime(i.p_atime), p_mtime(i.p_mtime),
p_ctime(i.p_ctime) p_ctime(i.p_ctime)
{ {
i.p_slash = i.p_dot = std::string::npos; i.p_slash = i.p_dot = std::string::npos;
i.p_type = FileType::unknown; i.p_type = file_type::UNKNOWN;
i.p_atime = i.p_ctime = i.p_mtime = 0; i.p_atime = i.p_ctime = i.p_mtime = 0;
} }
FileInfo(string_range path) { file_info(string_range path) {
init_from_str(path); init_from_str(path);
} }
FileInfo &operator=(FileInfo const &i) { file_info &operator=(file_info const &i) {
p_slash = i.p_slash; p_slash = i.p_slash;
p_dot = i.p_dot; p_dot = i.p_dot;
p_type = i.p_type; p_type = i.p_type;
@ -88,7 +88,7 @@ struct FileInfo {
return *this; return *this;
} }
FileInfo &operator=(FileInfo &&i) { file_info &operator=(file_info &&i) {
swap(i); swap(i);
return *this; return *this;
} }
@ -114,7 +114,7 @@ struct FileInfo {
: path().slice(p_dot, p_path.size()); : path().slice(p_dot, p_path.size());
} }
FileType type() const { return p_type; } file_type type() const { return p_type; }
void normalize() { void normalize() {
path_normalize(ostd::iter(p_path)); path_normalize(ostd::iter(p_path));
@ -125,7 +125,7 @@ struct FileInfo {
time_t mtime() const { return p_mtime; } time_t mtime() const { return p_mtime; }
time_t ctime() const { return p_ctime; } time_t ctime() const { return p_ctime; }
void swap(FileInfo &i) { void swap(file_info &i) {
using std::swap; using std::swap;
swap(i.p_slash, p_slash); swap(i.p_slash, p_slash);
swap(i.p_dot, p_dot); swap(i.p_dot, p_dot);
@ -150,7 +150,7 @@ private:
#endif #endif
{ {
p_slash = p_dot = std::string::npos; p_slash = p_dot = std::string::npos;
p_type = FileType::unknown; p_type = file_type::UNKNOWN;
p_path.clear(); p_path.clear();
p_atime = p_mtime = p_ctime = 0; p_atime = p_mtime = p_ctime = 0;
return; return;
@ -173,17 +173,17 @@ private:
#ifdef OSTD_PLATFORM_WIN32 #ifdef OSTD_PLATFORM_WIN32
if (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
p_type = FileType::directory; p_type = file_type::DIRECTORY;
} else if (attr.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { } else if (attr.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
p_type = FileType::symlink; p_type = file_type::SYMLINK;
} else if (attr.dwFileAttributes & ( } else if (attr.dwFileAttributes & (
FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_COMPRESSED |
FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL |
FILE_ATTRIBUTE_SPARSE_FILE | FILE_ATTRIBUTE_TEMPORARY FILE_ATTRIBUTE_SPARSE_FILE | FILE_ATTRIBUTE_TEMPORARY
)) { )) {
p_type = FileType::regular; p_type = file_type::REGULAR;
} else { } else {
p_type = FileType::unknown; p_type = file_type::UNKNOWN;
} }
p_atime = detail::filetime_to_time_t(attr.ftLastAccessTime); p_atime = detail::filetime_to_time_t(attr.ftLastAccessTime);
@ -191,21 +191,21 @@ private:
p_ctime = detail::filetime_to_time_t(attr.ftCreationTime); p_ctime = detail::filetime_to_time_t(attr.ftCreationTime);
#else #else
if (S_ISREG(st.st_mode)) { if (S_ISREG(st.st_mode)) {
p_type = FileType::regular; p_type = file_type::REGULAR;
} else if (S_ISDIR(st.st_mode)) { } else if (S_ISDIR(st.st_mode)) {
p_type = FileType::directory; p_type = file_type::DIRECTORY;
} else if (S_ISCHR(st.st_mode)) { } else if (S_ISCHR(st.st_mode)) {
p_type = FileType::character; p_type = file_type::CHARACTER;
} else if (S_ISBLK(st.st_mode)) { } else if (S_ISBLK(st.st_mode)) {
p_type = FileType::block; p_type = file_type::BLOCK;
} else if (S_ISFIFO(st.st_mode)) { } else if (S_ISFIFO(st.st_mode)) {
p_type = FileType::fifo; p_type = file_type::FIFO;
} else if (S_ISLNK(st.st_mode)) { } else if (S_ISLNK(st.st_mode)) {
p_type = FileType::symlink; p_type = file_type::SYMLINK;
} else if (S_ISSOCK(st.st_mode)) { } else if (S_ISSOCK(st.st_mode)) {
p_type = FileType::socket; p_type = file_type::SOCKET;
} else { } else {
p_type = FileType::unknown; p_type = file_type::UNKNOWN;
} }
p_atime = st.st_atime; p_atime = st.st_atime;
@ -215,39 +215,39 @@ private:
} }
size_t p_slash = std::string::npos, p_dot = std::string::npos; size_t p_slash = std::string::npos, p_dot = std::string::npos;
FileType p_type = FileType::unknown; file_type p_type = file_type::UNKNOWN;
std::string p_path; std::string p_path;
time_t p_atime = 0, p_mtime = 0, p_ctime = 0; time_t p_atime = 0, p_mtime = 0, p_ctime = 0;
}; };
inline void swap(FileInfo &a, FileInfo &b) { inline void swap(file_info &a, file_info &b) {
a.swap(b); a.swap(b);
} }
struct directory_range; struct directory_range;
#ifndef OSTD_PLATFORM_WIN32 #ifndef OSTD_PLATFORM_WIN32
struct DirectoryStream { struct directory_stream {
friend struct directory_range; friend struct directory_range;
DirectoryStream(): p_d(), p_de(), p_path() {} directory_stream(): p_d(), p_de(), p_path() {}
DirectoryStream(DirectoryStream const &) = delete; directory_stream(directory_stream const &) = delete;
DirectoryStream(DirectoryStream &&s): directory_stream(directory_stream &&s):
p_d(s.p_d), p_de(s.p_de), p_path(std::move(s.p_path)) p_d(s.p_d), p_de(s.p_de), p_path(std::move(s.p_path))
{ {
s.p_d = nullptr; s.p_d = nullptr;
s.p_de = nullptr; s.p_de = nullptr;
} }
DirectoryStream(string_range path): DirectoryStream() { directory_stream(string_range path): directory_stream() {
open(path); open(path);
} }
~DirectoryStream() { close(); } ~directory_stream() { close(); }
DirectoryStream &operator=(DirectoryStream const &) = delete; directory_stream &operator=(directory_stream const &) = delete;
DirectoryStream &operator=(DirectoryStream &&s) { directory_stream &operator=(directory_stream &&s) {
close(); close();
swap(s); swap(s);
return *this; return *this;
@ -310,14 +310,14 @@ struct DirectoryStream {
return !p_de; return !p_de;
} }
FileInfo read() { file_info read() {
if (!pop_front()) { if (!pop_front()) {
return FileInfo(); return file_info();
} }
return front(); return front();
} }
void swap(DirectoryStream &s) { void swap(directory_stream &s) {
using std::swap; using std::swap;
swap(p_d, s.p_d); swap(p_d, s.p_d);
swap(p_de, s.p_de); swap(p_de, s.p_de);
@ -348,14 +348,14 @@ private:
return pop_front(p_d, &p_de); return pop_front(p_d, &p_de);
} }
FileInfo front() const { file_info front() const {
if (!p_de) { if (!p_de) {
return FileInfo(); return file_info();
} }
std::string ap = p_path; std::string ap = p_path;
ap += PathSeparator; ap += PathSeparator;
ap += static_cast<char const *>(p_de->d_name); ap += static_cast<char const *>(p_de->d_name);
return FileInfo(ap); return file_info(ap);
} }
DIR *p_d; DIR *p_d;
@ -365,26 +365,26 @@ private:
#else /* OSTD_PLATFORM_WIN32 */ #else /* OSTD_PLATFORM_WIN32 */
struct DirectoryStream { struct directory_stream {
friend struct directory_range; friend struct directory_range;
DirectoryStream(): p_handle(INVALID_HANDLE_VALUE), p_data(), p_path() {} directory_stream(): p_handle(INVALID_HANDLE_VALUE), p_data(), p_path() {}
DirectoryStream(DirectoryStream const &) = delete; directory_stream(directory_stream const &) = delete;
DirectoryStream(DirectoryStream &&s): directory_stream(directory_stream &&s):
p_handle(s.p_handle), p_data(s.p_data), p_path(std::move(s.p_path)) p_handle(s.p_handle), p_data(s.p_data), p_path(std::move(s.p_path))
{ {
s.p_handle = INVALID_HANDLE_VALUE; s.p_handle = INVALID_HANDLE_VALUE;
memset(&s.p_data, 0, sizeof(s.p_data)); memset(&s.p_data, 0, sizeof(s.p_data));
} }
DirectoryStream(string_range path): DirectoryStream() { directory_stream(string_range path): directory_stream() {
open(path); open(path);
} }
~DirectoryStream() { close(); } ~directory_stream() { close(); }
DirectoryStream &operator=(DirectoryStream const &) = delete; directory_stream &operator=(directory_stream const &) = delete;
DirectoryStream &operator=(DirectoryStream &&s) { directory_stream &operator=(directory_stream &&s) {
close(); close();
swap(s); swap(s);
return *this; return *this;
@ -481,14 +481,14 @@ struct DirectoryStream {
return p_data.cFileName[0] == '\0'; return p_data.cFileName[0] == '\0';
} }
FileInfo read() { file_info read() {
if (!pop_front()) { if (!pop_front()) {
return FileInfo(); return file_info();
} }
return front(); return front();
} }
void swap(DirectoryStream &s) { void swap(directory_stream &s) {
using std::swap; using std::swap;
swap(p_handle, s.p_handle); swap(p_handle, s.p_handle);
swap(p_data, s.p_data); swap(p_data, s.p_data);
@ -509,14 +509,14 @@ private:
return true; return true;
} }
FileInfo front() const { file_info front() const {
if (empty()) { if (empty()) {
return FileInfo(); return file_info();
} }
std::string ap = p_path; std::string ap = p_path;
ap += PathSeparator; ap += PathSeparator;
ap += static_cast<char const *>(p_data.cFileName); ap += static_cast<char const *>(p_data.cFileName);
return FileInfo(ap); return file_info(ap);
} }
HANDLE p_handle; HANDLE p_handle;
@ -525,19 +525,19 @@ private:
}; };
#endif /* OSTD_PLATFORM_WIN32 */ #endif /* OSTD_PLATFORM_WIN32 */
inline void swap(DirectoryStream &a, DirectoryStream &b) { inline void swap(directory_stream &a, directory_stream &b) {
a.swap(b); a.swap(b);
} }
struct directory_range: input_range<directory_range> { struct directory_range: input_range<directory_range> {
using range_category = input_range_tag; using range_category = input_range_tag;
using value_type = FileInfo; using value_type = file_info;
using reference = FileInfo; using reference = file_info;
using size_type = size_t; using size_type = size_t;
using difference_type = long; using difference_type = long;
directory_range() = delete; directory_range() = delete;
directory_range(DirectoryStream &s): p_stream(&s) {} directory_range(directory_stream &s): p_stream(&s) {}
directory_range(directory_range const &r): p_stream(r.p_stream) {} directory_range(directory_range const &r): p_stream(r.p_stream) {}
directory_range &operator=(directory_range const &r) { directory_range &operator=(directory_range const &r) {
@ -553,7 +553,7 @@ struct directory_range: input_range<directory_range> {
return p_stream->pop_front(); return p_stream->pop_front();
} }
FileInfo front() const { file_info front() const {
return p_stream->front(); return p_stream->front();
} }
@ -562,26 +562,26 @@ struct directory_range: input_range<directory_range> {
} }
private: private:
DirectoryStream *p_stream; directory_stream *p_stream;
}; };
inline directory_range DirectoryStream::iter() { inline directory_range directory_stream::iter() {
return directory_range(*this); return directory_range(*this);
} }
namespace detail { namespace detail {
template<size_t I> template<size_t I>
struct PathJoin { struct path_join {
template<typename T, typename ...A> template<typename T, typename ...A>
static void join(std::string &s, T const &a, A const &...b) { static void join(std::string &s, T const &a, A const &...b) {
s += a; s += a;
s += PathSeparator; s += PathSeparator;
PathJoin<I - 1>::join(s, b...); path_join<I - 1>::join(s, b...);
} }
}; };
template<> template<>
struct PathJoin<1> { struct path_join<1> {
template<typename T> template<typename T>
static void join(std::string &s, T const &a) { static void join(std::string &s, T const &a) {
s += a; s += a;
@ -590,11 +590,11 @@ namespace detail {
} }
template<typename ...A> template<typename ...A>
inline FileInfo path_join(A const &...args) { inline file_info path_join(A const &...args) {
std::string path; std::string path;
detail::PathJoin<sizeof...(A)>::join(path, args...); detail::path_join<sizeof...(A)>::join(path, args...);
path_normalize(ostd::iter(path)); path_normalize(ostd::iter(path));
return FileInfo(path); return file_info(path);
} }
inline bool directory_change(string_range path) { inline bool directory_change(string_range path) {

View File

@ -15,7 +15,6 @@
#include "ostd/algorithm.hh" #include "ostd/algorithm.hh"
#include "ostd/string.hh" #include "ostd/string.hh"
#include "ostd/utility.hh"
namespace ostd { namespace ostd {
@ -132,13 +131,13 @@ namespace detail {
} }
} }
struct FormatSpec { struct format_spec {
FormatSpec(): p_nested_escape(false), p_fmt() {} format_spec(): p_nested_escape(false), p_fmt() {}
FormatSpec(string_range fmt, bool escape = false): format_spec(string_range fmt, bool escape = false):
p_nested_escape(escape), p_fmt(fmt) p_nested_escape(escape), p_fmt(fmt)
{} {}
FormatSpec(char spec, int width = -1, int prec = -1, int flags = 0): format_spec(char spec, int width = -1, int prec = -1, int flags = 0):
p_flags(flags), p_flags(flags),
p_width((width >= 0) ? width : 0), p_width((width >= 0) ? width : 0),
p_precision((prec >= 0) ? prec : 0), p_precision((prec >= 0) ? prec : 0),
@ -437,17 +436,17 @@ protected:
template< template<
typename T, typename R, typename = std::enable_if_t< typename T, typename R, typename = std::enable_if_t<
std::is_same_v<decltype(std::declval<T const &>().to_format( std::is_same_v<decltype(std::declval<T const &>().to_format(
std::declval<R &>(), std::declval<FormatSpec const &>() std::declval<R &>(), std::declval<format_spec const &>()
)), void> )), void>
> >
> >
inline void to_format(T const &v, R &writer, FormatSpec const &fs) { inline void to_format(T const &v, R &writer, format_spec const &fs) {
v.to_format(writer, fs); v.to_format(writer, fs);
} }
namespace detail { namespace detail {
template<typename R, typename T> template<typename R, typename T>
inline size_t write_u(R &writer, FormatSpec const *fl, bool neg, T val) { inline size_t write_u(R &writer, format_spec const *fl, bool neg, T val) {
char buf[20]; char buf[20];
size_t r = 0, n = 0; size_t r = 0, n = 0;
@ -564,9 +563,9 @@ namespace detail {
template<typename R, typename T> template<typename R, typename T>
inline size_t write_range( inline size_t write_range(
R &writer, FormatSpec const *fl, bool escape, bool expandval, R &writer, format_spec const *fl, bool escape, bool expandval,
string_range sep, T const &val, string_range sep, T const &val,
std::enable_if_t<detail::IterableTest<T>, bool> = true std::enable_if_t<detail::iterable_test<T>, bool> = true
) { ) {
/* XXX: maybe handle error cases? */ /* XXX: maybe handle error cases? */
auto range = ostd::iter(val); auto range = ostd::iter(val);
@ -591,21 +590,21 @@ namespace detail {
template<typename R, typename T> template<typename R, typename T>
inline size_t write_range( inline size_t write_range(
R &, FormatSpec const *, bool, bool, string_range, R &, format_spec const *, bool, bool, string_range,
T const &, std::enable_if_t<!detail::IterableTest<T>, bool> = true T const &, std::enable_if_t<!detail::iterable_test<T>, bool> = true
) { ) {
throw format_error{"invalid value for ranged format"}; throw format_error{"invalid value for ranged format"};
} }
template<typename T> template<typename T>
static std::true_type test_fmt_tostr( static std::true_type test_fmt_tostr(
decltype(ostd::to_string(std::declval<T>())) * decltype(ostd::to_string<T>{}(std::declval<T>())) *
); );
template<typename> template<typename>
static std::false_type test_fmt_tostr(...); static std::false_type test_fmt_tostr(...);
template<typename T> template<typename T>
constexpr bool FmtTostrTest = decltype(test_fmt_tostr<T>(0))::value; constexpr bool fmt_tostr_test = decltype(test_fmt_tostr<T>(0))::value;
/* non-printable escapes up to 0x20 (space) */ /* non-printable escapes up to 0x20 (space) */
static constexpr char const *fmt_escapes[] = { static constexpr char const *fmt_escapes[] = {
@ -648,17 +647,17 @@ namespace detail {
template<typename T, typename R> template<typename T, typename R>
static std::true_type test_tofmt(decltype(to_format( static std::true_type test_tofmt(decltype(to_format(
std::declval<T const &>(), std::declval<R &>(), std::declval<T const &>(), std::declval<R &>(),
std::declval<FormatSpec const &>() std::declval<format_spec const &>()
)) *); )) *);
template<typename, typename> template<typename, typename>
static std::false_type test_tofmt(...); static std::false_type test_tofmt(...);
template<typename T, typename R> template<typename T, typename R>
constexpr bool FmtTofmtTest = decltype(test_tofmt<T, R>(0))::value; constexpr bool fmt_tofmt_test = decltype(test_tofmt<T, R>(0))::value;
struct WriteSpec: FormatSpec { struct write_spec: format_spec {
using FormatSpec::FormatSpec; using format_spec::format_spec;
/* string base writer */ /* string base writer */
template<typename R> template<typename R>
@ -757,7 +756,7 @@ namespace detail {
template<typename R, typename T> template<typename R, typename T>
size_t write_val(R &writer, bool escape, T const &val) const { size_t write_val(R &writer, bool escape, T const &val) const {
/* stuff fhat can be custom-formatted goes first */ /* stuff fhat can be custom-formatted goes first */
if constexpr(FmtTofmtTest<T, tostr_range<R>>) { if constexpr(fmt_tofmt_test<T, tostr_range<R>>) {
tostr_range<R> sink(writer); tostr_range<R> sink(writer);
to_format(val, sink, *this); to_format(val, sink, *this);
return sink.get_written(); return sink.get_written();
@ -788,7 +787,7 @@ namespace detail {
* char pointers are handled by the string case above * char pointers are handled by the string case above
*/ */
if constexpr(std::is_pointer_v<T>) { if constexpr(std::is_pointer_v<T>) {
FormatSpec sp{ format_spec sp{
(spec() == 's') ? 'x' : spec(), (spec() == 's') ? 'x' : spec(),
has_width() ? width() : -1, has_width() ? width() : -1,
has_precision() ? precision() : -1, has_precision() ? precision() : -1,
@ -815,11 +814,11 @@ namespace detail {
return write_float(writer, escape, val); return write_float(writer, escape, val);
} }
/* stuff that can be to_string'd, worst reliable case, allocates */ /* stuff that can be to_string'd, worst reliable case, allocates */
if constexpr(FmtTostrTest<T>) { if constexpr(fmt_tostr_test<T>) {
if (this->spec() != 's') { if (this->spec() != 's') {
throw format_error{"custom objects need the '%s' spec"}; throw format_error{"custom objects need the '%s' spec"};
} }
return write_val(writer, false, ostd::to_string(val)); return write_val(writer, false, ostd::to_string<T>{}(val));
} }
/* we ran out of options, failure */ /* we ran out of options, failure */
throw format_error{"the value cannot be formatted"}; throw format_error{"the value cannot be formatted"};
@ -866,7 +865,7 @@ namespace detail {
R &writer, bool escape, string_range fmt, A const &...args R &writer, bool escape, string_range fmt, A const &...args
) { ) {
size_t argidx = 1, twr = 0, written = 0; size_t argidx = 1, twr = 0, written = 0;
detail::WriteSpec spec(fmt, escape); detail::write_spec spec(fmt, escape);
while (spec.read_until_spec(writer, &twr)) { while (spec.read_until_spec(writer, &twr)) {
written += twr; written += twr;
size_t argpos = spec.index(); size_t argpos = spec.index();
@ -875,7 +874,7 @@ namespace detail {
argpos = argidx++; argpos = argidx++;
} }
/* FIXME: figure out a better way */ /* FIXME: figure out a better way */
detail::WriteSpec nspec(spec.nested(), spec.nested_escape()); detail::write_spec nspec(spec.nested(), spec.nested_escape());
written += nspec.write_range( written += nspec.write_range(
writer, argpos - 1, (spec.flags() & FMT_FLAG_HASH), writer, argpos - 1, (spec.flags() & FMT_FLAG_HASH),
spec.nested_sep(), args... spec.nested_sep(), args...
@ -916,7 +915,7 @@ namespace detail {
template<typename R> template<typename R>
inline ptrdiff_t format_impl(R &writer, bool, string_range fmt) { inline ptrdiff_t format_impl(R &writer, bool, string_range fmt) {
size_t written = 0; size_t written = 0;
detail::WriteSpec spec(fmt, false); detail::write_spec spec(fmt, false);
if (spec.read_until_spec(writer, &written)) { if (spec.read_until_spec(writer, &written)) {
throw format_error{"format spec without format arguments"}; throw format_error{"format spec without format arguments"};
} }
@ -930,9 +929,9 @@ inline size_t format(R &&writer, string_range fmt, A const &...args) {
} }
template<typename R, typename T> template<typename R, typename T>
inline size_t format(R &&writer, FormatSpec const &fmt, T const &val) { inline size_t format(R &&writer, format_spec const &fmt, T const &val) {
/* we can do this as there are no members added... but ugly, FIXME later */ /* we can do this as there are no members added... but ugly, FIXME later */
detail::WriteSpec const &wsp = static_cast<detail::WriteSpec const &>(fmt); detail::write_spec const &wsp = static_cast<detail::write_spec const &>(fmt);
return wsp.write_arg(writer, 0, val); return wsp.write_arg(writer, 0, val);
} }

View File

@ -17,8 +17,8 @@
namespace ostd { namespace ostd {
enum class StreamMode { enum class stream_mode {
read = 0, write, append, read_u, write_u, append_u READ = 0, WRITE, APPEND, READ_U, WRITE_U, APPEND_U
}; };
namespace detail { namespace detail {
@ -27,30 +27,30 @@ namespace detail {
}; };
} }
struct FileStream: Stream { struct file_stream: stream {
FileStream(): p_f(), p_owned(false) {} file_stream(): p_f(), p_owned(false) {}
FileStream(FileStream const &) = delete; file_stream(file_stream const &) = delete;
FileStream(FileStream &&s): p_f(s.p_f), p_owned(s.p_owned) { file_stream(file_stream &&s): p_f(s.p_f), p_owned(s.p_owned) {
s.p_f = nullptr; s.p_f = nullptr;
s.p_owned = false; s.p_owned = false;
} }
FileStream(string_range path, StreamMode mode = StreamMode::read): p_f() { file_stream(string_range path, stream_mode mode = stream_mode::READ): p_f() {
open(path, mode); open(path, mode);
} }
FileStream(FILE *f): p_f(f), p_owned(false) {} file_stream(FILE *f): p_f(f), p_owned(false) {}
~FileStream() { close(); } ~file_stream() { close(); }
FileStream &operator=(FileStream const &) = delete; file_stream &operator=(file_stream const &) = delete;
FileStream &operator=(FileStream &&s) { file_stream &operator=(file_stream &&s) {
close(); close();
swap(s); swap(s);
return *this; return *this;
} }
bool open(string_range path, StreamMode mode = StreamMode::read) { bool open(string_range path, stream_mode mode = stream_mode::READ) {
if (p_f || (path.size() > FILENAME_MAX)) { if (p_f || (path.size() > FILENAME_MAX)) {
return false; return false;
} }
@ -93,7 +93,7 @@ struct FileStream: Stream {
return feof(p_f) != 0; return feof(p_f) != 0;
} }
bool seek(StreamOffset pos, StreamSeek whence = StreamSeek::set) { bool seek(stream_off_t pos, stream_seek whence = stream_seek::SET) {
#ifndef OSTD_PLATFORM_WIN32 #ifndef OSTD_PLATFORM_WIN32
return fseeko(p_f, pos, int(whence)) >= 0; return fseeko(p_f, pos, int(whence)) >= 0;
#else #else
@ -101,7 +101,7 @@ struct FileStream: Stream {
#endif #endif
} }
StreamOffset tell() const { stream_off_t tell() const {
#ifndef OSTD_PLATFORM_WIN32 #ifndef OSTD_PLATFORM_WIN32
return ftello(p_f); return ftello(p_f);
#else #else
@ -127,7 +127,7 @@ struct FileStream: Stream {
return fputc(c, p_f) != EOF; return fputc(c, p_f) != EOF;
} }
void swap(FileStream &s) { void swap(file_stream &s) {
using std::swap; using std::swap;
swap(p_f, s.p_f); swap(p_f, s.p_f);
swap(p_owned, s.p_owned); swap(p_owned, s.p_owned);
@ -140,38 +140,38 @@ private:
bool p_owned; bool p_owned;
}; };
inline void swap(FileStream &a, FileStream &b) { inline void swap(file_stream &a, file_stream &b) {
a.swap(b); a.swap(b);
} }
static FileStream in(stdin); static file_stream in(stdin);
static FileStream out(stdout); static file_stream out(stdout);
static FileStream err(stderr); static file_stream err(stderr);
/* no need to call anything from FileStream, prefer simple calls... */ /* no need to call anything from file_stream, prefer simple calls... */
namespace detail { namespace detail {
/* lightweight output range for direct stdout */ /* lightweight output range for direct stdout */
struct StdoutRange: output_range<StdoutRange> { struct stdout_range: output_range<stdout_range> {
using value_type = char; using value_type = char;
using reference = char &; using reference = char &;
using size_type = size_t; using size_type = size_t;
using difference_type = ptrdiff_t; using difference_type = ptrdiff_t;
StdoutRange() {} stdout_range() {}
bool put(char c) { bool put(char c) {
return putchar(c) != EOF; return putchar(c) != EOF;
} }
}; };
inline size_t range_put_n(StdoutRange &, char const *p, size_t n) { inline size_t range_put_n(stdout_range &, char const *p, size_t n) {
return fwrite(p, 1, n, stdout); return fwrite(p, 1, n, stdout);
} }
} }
template<typename T> template<typename T>
inline void write(T const &v) { inline void write(T const &v) {
format(detail::StdoutRange{}, FormatSpec{'s'}, v); format(detail::stdout_range{}, format_spec{'s'}, v);
} }
template<typename T, typename ...A> template<typename T, typename ...A>
@ -200,7 +200,7 @@ inline void writeln(T const &v, A const &...args) {
template<typename ...A> template<typename ...A>
inline void writef(string_range fmt, A const &...args) { inline void writef(string_range fmt, A const &...args) {
format(detail::StdoutRange{}, fmt, args...); format(detail::stdout_range{}, fmt, args...);
} }
template<typename ...A> template<typename ...A>

View File

@ -149,12 +149,10 @@ inline std::uint64_t endian_swap64(std::uint64_t x) noexcept {
/* endian swap */ /* endian swap */
template<typename T, size_t N = sizeof(T), bool IsNum = std::is_arithmetic_v<T>> template<typename T, size_t N = sizeof(T), bool IsNum = std::is_arithmetic_v<T>>
struct EndianSwap; struct endian_swap;
template<typename T> template<typename T>
struct EndianSwap<T, 2, true> { struct endian_swap<T, 2, true> {
using Argument = T;
using Result = T;
T operator()(T v) const { T operator()(T v) const {
union { T iv; std::uint16_t sv; } u; union { T iv; std::uint16_t sv; } u;
u.iv = v; u.iv = v;
@ -164,9 +162,7 @@ struct EndianSwap<T, 2, true> {
}; };
template<typename T> template<typename T>
struct EndianSwap<T, 4, true> { struct endian_swap<T, 4, true> {
using Argument = T;
using Result = T;
T operator()(T v) const { T operator()(T v) const {
union { T iv; std::uint32_t sv; } u; union { T iv; std::uint32_t sv; } u;
u.iv = v; u.iv = v;
@ -176,9 +172,7 @@ struct EndianSwap<T, 4, true> {
}; };
template<typename T> template<typename T>
struct EndianSwap<T, 8, true> { struct endian_swap<T, 8, true> {
using Argument = T;
using Result = T;
T operator()(T v) const { T operator()(T v) const {
union { T iv; std::uint64_t sv; } u; union { T iv; std::uint64_t sv; } u;
u.iv = v; u.iv = v;
@ -187,52 +181,38 @@ struct EndianSwap<T, 8, true> {
} }
}; };
template<typename T>
T endian_swap(T x) { return EndianSwap<T>()(x); }
namespace detail { namespace detail {
template< template<
typename T, size_t N = sizeof(T), bool IsNum = std::is_arithmetic_v<T> typename T, size_t N = sizeof(T), bool IsNum = std::is_arithmetic_v<T>
> >
struct EndianSame; struct endian_same;
template<typename T> template<typename T>
struct EndianSame<T, 2, true> { struct endian_same<T, 2, true> {
using Argument = T;
using Result = T;
T operator()(T v) const { return v; } T operator()(T v) const { return v; }
}; };
template<typename T> template<typename T>
struct EndianSame<T, 4, true> { struct endian_same<T, 4, true> {
using Argument = T;
using Result = T;
T operator()(T v) const { return v; } T operator()(T v) const { return v; }
}; };
template<typename T> template<typename T>
struct EndianSame<T, 8, true> { struct endian_same<T, 8, true> {
using Argument = T;
using Result = T;
T operator()(T v) const { return v; } T operator()(T v) const { return v; }
}; };
} }
#if OSTD_BYTE_ORDER == OSTD_ENDIAN_LIL #if OSTD_BYTE_ORDER == OSTD_ENDIAN_LIL
template<typename T> template<typename T>
struct FromLilEndian: detail::EndianSame<T> {}; struct from_lil_endian: detail::endian_same<T> {};
template<typename T> template<typename T>
struct FromBigEndian: EndianSwap<T> {}; struct from_big_endian: endian_swap<T> {};
#else #else
template<typename T> template<typename T>
struct FromLilEndian: EndianSwap<T> {}; struct from_lil_endian: endian_swap<T> {};
template<typename T> template<typename T>
struct FromBigEndian: detail::EndianSame<T> {}; struct from_big_endian: detail::endian_same<T> {};
#endif #endif
template<typename T>
T from_lil_endian(T x) { return FromLilEndian<T>()(x); }
template<typename T>
T from_big_endian(T x) { return FromBigEndian<T>()(x); }
} }
#endif #endif

View File

@ -17,7 +17,6 @@
#include <initializer_list> #include <initializer_list>
#include "ostd/types.hh" #include "ostd/types.hh"
#include "ostd/utility.hh"
namespace ostd { namespace ostd {
@ -27,7 +26,7 @@ struct forward_range_tag: input_range_tag {};
struct bidirectional_range_tag: forward_range_tag {}; struct bidirectional_range_tag: forward_range_tag {};
struct random_access_range_tag: bidirectional_range_tag {}; struct random_access_range_tag: bidirectional_range_tag {};
struct finite_random_access_range_tag: random_access_range_tag {}; struct finite_random_access_range_tag: random_access_range_tag {};
struct ContiguousRangeTag: finite_random_access_range_tag {}; struct contiguous_range_tag: finite_random_access_range_tag {};
template<typename T> template<typename T>
struct range_half; struct range_half;
@ -172,7 +171,7 @@ template<typename T> constexpr bool is_infinite_random_access_range =
namespace detail { namespace detail {
template<typename T> template<typename T>
constexpr bool is_contiguous_range_core = constexpr bool is_contiguous_range_core =
std::is_convertible_v<range_category_t<T>, ContiguousRangeTag>; std::is_convertible_v<range_category_t<T>, contiguous_range_tag>;
template<typename T, bool = detail::is_range_test<T>> template<typename T, bool = detail::is_range_test<T>>
constexpr bool is_contiguous_range_base = false; constexpr bool is_contiguous_range_base = false;
@ -284,20 +283,20 @@ template<typename T>
struct half_range; struct half_range;
namespace detail { namespace detail {
template<typename R, bool = is_bidirectional_range<typename R::Range>> template<typename R, bool = is_bidirectional_range<typename R::range>>
struct RangeAdd; struct range_add;
template<typename R> template<typename R>
struct RangeAdd<R, true> { struct range_add<R, true> {
using Diff = range_difference_t<typename R::Range>; using diff_t = range_difference_t<typename R::range>;
static Diff add_n(R &half, Diff n) { static diff_t add_n(R &half, diff_t n) {
if (n < 0) { if (n < 0) {
return -half.prev_n(n); return -half.prev_n(n);
} }
return half.next_n(n); return half.next_n(n);
} }
static Diff sub_n(R &half, Diff n) { static diff_t sub_n(R &half, diff_t n) {
if (n < 0) { if (n < 0) {
return -half.next_n(n); return -half.next_n(n);
} }
@ -306,16 +305,16 @@ namespace detail {
}; };
template<typename R> template<typename R>
struct RangeAdd<R, false> { struct range_add<R, false> {
using Diff = range_difference_t<typename R::Range>; using diff_t = range_difference_t<typename R::range>;
static Diff add_n(R &half, Diff n) { static diff_t add_n(R &half, diff_t n) {
if (n < 0) { if (n < 0) {
return 0; return 0;
} }
return half.next_n(n); return half.next_n(n);
} }
static Diff sub_n(R &half, Diff n) { static diff_t sub_n(R &half, diff_t n) {
if (n < 0) { if (n < 0) {
return 0; return 0;
} }
@ -326,29 +325,29 @@ namespace detail {
namespace detail { namespace detail {
template<typename> template<typename>
struct range_iteratorTag { struct range_iterator_tag {
/* better range types all become random access iterators */ /* better range types all become random access iterators */
using Type = std::random_access_iterator_tag; using type = std::random_access_iterator_tag;
}; };
template<> template<>
struct range_iteratorTag<input_range_tag> { struct range_iterator_tag<input_range_tag> {
using Type = std::input_iterator_tag; using type = std::input_iterator_tag;
}; };
template<> template<>
struct range_iteratorTag<output_range_tag> { struct range_iterator_tag<output_range_tag> {
using Type = std::output_iterator_tag; using type = std::output_iterator_tag;
}; };
template<> template<>
struct range_iteratorTag<forward_range_tag> { struct range_iterator_tag<forward_range_tag> {
using Type = std::forward_iterator_tag; using type = std::forward_iterator_tag;
}; };
template<> template<>
struct range_iteratorTag<bidirectional_range_tag> { struct range_iterator_tag<bidirectional_range_tag> {
using Type = std::bidirectional_iterator_tag; using type = std::bidirectional_iterator_tag;
}; };
} }
@ -357,9 +356,9 @@ struct range_half {
private: private:
T p_range; T p_range;
public: public:
using Range = T; using range = T;
using iterator_category = typename detail::range_iteratorTag<T>::Type; using iterator_category = typename detail::range_iterator_tag<T>::type;
using value_type = range_value_t<T>; using value_type = range_value_t<T>;
using difference_type = range_difference_t<T>; using difference_type = range_difference_t<T>;
using pointer = range_value_t<T> *; using pointer = range_value_t<T> *;
@ -395,10 +394,10 @@ public:
} }
range_difference_t<T> add_n(range_difference_t<T> n) { range_difference_t<T> add_n(range_difference_t<T> n) {
return detail::RangeAdd<range_half<T>>::add_n(*this, n); return detail::range_add<range_half<T>>::add_n(*this, n);
} }
range_difference_t<T> sub_n(range_difference_t<T> n) { range_difference_t<T> sub_n(range_difference_t<T> n) {
return detail::RangeAdd<range_half<T>>::sub_n(*this, n); return detail::range_add<range_half<T>>::sub_n(*this, n);
} }
range_reference_t<T> get() const { range_reference_t<T> get() const {
@ -859,11 +858,11 @@ inline auto citer(T const &r) -> decltype(ranged_traits<T const>::iter(r)) {
template<typename T> template<typename T>
struct half_range: input_range<half_range<T>> { struct half_range: input_range<half_range<T>> {
using range_category = range_category_t <typename T::Range>; using range_category = range_category_t <typename T::range>;
using value_type = range_value_t <typename T::Range>; using value_type = range_value_t <typename T::range>;
using reference = range_reference_t <typename T::Range>; using reference = range_reference_t <typename T::range>;
using size_type = range_size_t <typename T::Range>; using size_type = range_size_t <typename T::range>;
using difference_type = range_difference_t<typename T::Range>; using difference_type = range_difference_t<typename T::range>;
private: private:
T p_beg; T p_beg;
@ -1553,38 +1552,38 @@ namespace detail {
template<typename> template<typename>
struct iterator_range_tag_base { struct iterator_range_tag_base {
/* fallback, the most basic range */ /* fallback, the most basic range */
using Type = input_range_tag; using type = input_range_tag;
}; };
template<> template<>
struct iterator_range_tag_base<std::output_iterator_tag> { struct iterator_range_tag_base<std::output_iterator_tag> {
using Type = output_range_tag; using type = output_range_tag;
}; };
template<> template<>
struct iterator_range_tag_base<std::forward_iterator_tag> { struct iterator_range_tag_base<std::forward_iterator_tag> {
using Type = forward_range_tag; using type = forward_range_tag;
}; };
template<> template<>
struct iterator_range_tag_base<std::bidirectional_iterator_tag> { struct iterator_range_tag_base<std::bidirectional_iterator_tag> {
using Type = bidirectional_range_tag; using type = bidirectional_range_tag;
}; };
template<> template<>
struct iterator_range_tag_base<std::random_access_iterator_tag> { struct iterator_range_tag_base<std::random_access_iterator_tag> {
using Type = finite_random_access_range_tag; using type = finite_random_access_range_tag;
}; };
} }
template<typename T> template<typename T>
using iterator_range_tag = typename detail::iterator_range_tag_base<T>::Type; using iterator_range_tag = typename detail::iterator_range_tag_base<T>::type;
template<typename T> template<typename T>
struct iterator_range: input_range<iterator_range<T>> { struct iterator_range: input_range<iterator_range<T>> {
using range_category = std::conditional_t< using range_category = std::conditional_t<
std::is_pointer_v<T>, std::is_pointer_v<T>,
ContiguousRangeTag, contiguous_range_tag,
iterator_range_tag<typename std::iterator_traits<T>::iterator_category> iterator_range_tag<typename std::iterator_traits<T>::iterator_category>
>; >;
using value_type = typename std::iterator_traits<T>::value_type; using value_type = typename std::iterator_traits<T>::value_type;
@ -1715,7 +1714,7 @@ struct iterator_range: input_range<iterator_range<T>> {
return range.p_end - p_end; return range.p_end - p_end;
} }
/* satisfy FiniteRandomAccessRange */ /* satisfy finite_random_access_range */
size_type size() const { return size_type(p_end - p_beg); } size_type size() const { return size_type(p_end - p_beg); }
iterator_range slice(size_type start, size_type end) const { iterator_range slice(size_type start, size_type end) const {

View File

@ -13,49 +13,48 @@
#include "ostd/types.hh" #include "ostd/types.hh"
#include "ostd/range.hh" #include "ostd/range.hh"
#include "ostd/string.hh" #include "ostd/string.hh"
#include "ostd/utility.hh"
#include "ostd/format.hh" #include "ostd/format.hh"
namespace ostd { namespace ostd {
#ifndef OSTD_PLATFORM_WIN32 #ifndef OSTD_PLATFORM_WIN32
using StreamOffset = off_t; using stream_off_t = off_t;
#else #else
using StreamOffset = __int64; using stream_off_t = __int64;
#endif #endif
enum class StreamSeek { enum class stream_seek {
cur = SEEK_CUR, CUR = SEEK_CUR,
end = SEEK_END, END = SEEK_END,
set = SEEK_SET SET = SEEK_SET
}; };
template<typename T = char, bool = std::is_pod_v<T>> template<typename T = char, bool = std::is_pod_v<T>>
struct stream_range; struct stream_range;
struct Stream { struct stream {
using Offset = StreamOffset; using offset_type = stream_off_t;
virtual ~Stream() {} virtual ~stream() {}
virtual void close() = 0; virtual void close() = 0;
virtual bool end() const = 0; virtual bool end() const = 0;
virtual Offset size() { virtual offset_type size() {
Offset p = tell(); offset_type p = tell();
if ((p < 0) || !seek(0, StreamSeek::end)) { if ((p < 0) || !seek(0, stream_seek::END)) {
return -1; return -1;
} }
Offset e = tell(); offset_type e = tell();
return ((p == e) || seek(p, StreamSeek::set)) ? e : -1; return ((p == e) || seek(p, stream_seek::SET)) ? e : -1;
} }
virtual bool seek(Offset, StreamSeek = StreamSeek::set) { virtual bool seek(offset_type, stream_seek = stream_seek::SET) {
return false; return false;
} }
virtual Offset tell() const { return -1; } virtual offset_type tell() const { return -1; }
virtual bool flush() { return true; } virtual bool flush() { return true; }
@ -149,17 +148,17 @@ struct stream_range<T, true>: input_range<stream_range<T>> {
using value_type = T; using value_type = T;
using reference = T; using reference = T;
using size_type = size_t; using size_type = size_t;
using difference_type = StreamOffset; using difference_type = stream_off_t;
template<typename TT> template<typename TT>
friend size_t range_put_n(stream_range<TT> &range, TT const *p, size_t n); friend size_t range_put_n(stream_range<TT> &range, TT const *p, size_t n);
stream_range() = delete; stream_range() = delete;
stream_range(Stream &s): p_stream(&s), p_size(s.size()) {} stream_range(stream &s): p_stream(&s), p_size(s.size()) {}
stream_range(stream_range const &r): p_stream(r.p_stream), p_size(r.p_size) {} stream_range(stream_range const &r): p_stream(r.p_stream), p_size(r.p_size) {}
bool empty() const { bool empty() const {
return (p_size - p_stream->tell()) < StreamOffset(sizeof(T)); return (p_size - p_stream->tell()) < stream_off_t(sizeof(T));
} }
bool pop_front() { bool pop_front() {
@ -172,7 +171,7 @@ struct stream_range<T, true>: input_range<stream_range<T>> {
T front() const { T front() const {
T val; T val;
p_stream->seek(-p_stream->read_bytes(&val, sizeof(T)), StreamSeek::cur); p_stream->seek(-p_stream->read_bytes(&val, sizeof(T)), stream_seek::CUR);
return val; return val;
} }
@ -194,8 +193,8 @@ struct stream_range<T, true>: input_range<stream_range<T>> {
} }
private: private:
Stream *p_stream; stream *p_stream;
StreamOffset p_size; stream_off_t p_size;
}; };
template<typename T> template<typename T>
@ -204,7 +203,7 @@ inline size_t range_put_n(stream_range<T> &range, T const *p, size_t n) {
} }
template<typename T> template<typename T>
inline stream_range<T> Stream::iter() { inline stream_range<T> stream::iter() {
return stream_range<T>(*this); return stream_range<T>(*this);
} }
@ -216,11 +215,11 @@ namespace detail {
using size_type = size_t; using size_type = size_t;
using difference_type = ptrdiff_t; using difference_type = ptrdiff_t;
fmt_stream_range(Stream &s): p_s(s) {} fmt_stream_range(stream &s): p_s(s) {}
bool put(char c) { bool put(char c) {
return p_s.write_bytes(&c, 1) == 1; return p_s.write_bytes(&c, 1) == 1;
} }
Stream &p_s; stream &p_s;
}; };
inline size_t range_put_n(fmt_stream_range &range, char const *p, size_t n) { inline size_t range_put_n(fmt_stream_range &range, char const *p, size_t n) {
@ -229,12 +228,12 @@ namespace detail {
} }
template<typename T> template<typename T>
inline void Stream::write(T const &v) { inline void stream::write(T const &v) {
format(detail::fmt_stream_range{*this}, FormatSpec{'s'}, v); format(detail::fmt_stream_range{*this}, format_spec{'s'}, v);
} }
template<typename ...A> template<typename ...A>
inline void Stream::writef(string_range fmt, A const &...args) { inline void stream::writef(string_range fmt, A const &...args) {
format(detail::fmt_stream_range{*this}, fmt, args...); format(detail::fmt_stream_range{*this}, fmt, args...);
} }

View File

@ -14,8 +14,8 @@
#include <string_view> #include <string_view>
#include <type_traits> #include <type_traits>
#include <functional> #include <functional>
#include <utility>
#include "ostd/utility.hh"
#include "ostd/range.hh" #include "ostd/range.hh"
#include "ostd/vector.hh" #include "ostd/vector.hh"
#include "ostd/algorithm.hh" #include "ostd/algorithm.hh"
@ -24,7 +24,7 @@ namespace ostd {
template<typename T, typename TR = std::char_traits<std::remove_const_t<T>>> template<typename T, typename TR = std::char_traits<std::remove_const_t<T>>>
struct basic_char_range: input_range<basic_char_range<T>> { struct basic_char_range: input_range<basic_char_range<T>> {
using range_category = ContiguousRangeTag; using range_category = contiguous_range_tag;
using value_type = T; using value_type = T;
using reference = T &; using reference = T &;
using size_type = size_t; using size_type = size_t;
@ -565,11 +565,6 @@ namespace detail {
return ret; return ret;
} }
template<typename T, typename R>
static auto test_stringify(int) -> std::integral_constant<
bool, std::is_same_v<decltype(std::declval<T>().stringify()), std::string>
>;
template<typename T, typename R> template<typename T, typename R>
static std::true_type test_stringify( static std::true_type test_stringify(
decltype(std::declval<T const &>().to_string(std::declval<R &>())) * decltype(std::declval<T const &>().to_string(std::declval<R &>())) *
@ -579,7 +574,7 @@ namespace detail {
static std::false_type test_stringify(...); static std::false_type test_stringify(...);
template<typename T, typename R> template<typename T, typename R>
constexpr bool StringifyTest = decltype(test_stringify<T, R>(0))::value; constexpr bool stringify_test = decltype(test_stringify<T, R>(0))::value;
template<typename T> template<typename T>
static std::true_type test_iterable(decltype(ostd::iter(std::declval<T>())) *); static std::true_type test_iterable(decltype(ostd::iter(std::declval<T>())) *);
@ -587,21 +582,18 @@ namespace detail {
static std::false_type test_iterable(...); static std::false_type test_iterable(...);
template<typename T> template<typename T>
constexpr bool IterableTest = decltype(test_iterable<T>(0))::value; constexpr bool iterable_test = decltype(test_iterable<T>(0))::value;
} }
template<typename T, typename = void> template<typename T, typename = void>
struct ToString; struct to_string;
template<typename T> template<typename T>
struct ToString<T, std::enable_if_t<detail::IterableTest<T>>> { struct to_string<T, std::enable_if_t<detail::iterable_test<T>>> {
using Argument = std::remove_cv_t<std::remove_reference_t<T>>;
using Result = std::string;
std::string operator()(T const &v) const { std::string operator()(T const &v) const {
std::string ret("{"); std::string ret("{");
auto x = appender<std::string>(); auto x = appender<std::string>();
if (concat(x, ostd::iter(v), ", ", ToString< if (concat(x, ostd::iter(v), ", ", to_string<
std::remove_const_t<std::remove_reference_t< std::remove_const_t<std::remove_reference_t<
range_reference_t<decltype(ostd::iter(v))> range_reference_t<decltype(ostd::iter(v))>
>> >>
@ -614,12 +606,9 @@ struct ToString<T, std::enable_if_t<detail::IterableTest<T>>> {
}; };
template<typename T> template<typename T>
struct ToString<T, std::enable_if_t< struct to_string<T, std::enable_if_t<
detail::StringifyTest<T, detail::tostr_range<appender_range<std::string>>> detail::stringify_test<T, detail::tostr_range<appender_range<std::string>>>
>> { >> {
using Argument = std::remove_cv_t<std::remove_reference_t<T>>;
using Result = std::string;
std::string operator()(T const &v) const { std::string operator()(T const &v) const {
auto app = appender<std::string>(); auto app = appender<std::string>();
detail::tostr_range<appender_range<std::string>> sink(app); detail::tostr_range<appender_range<std::string>> sink(app);
@ -631,18 +620,14 @@ struct ToString<T, std::enable_if_t<
}; };
template<> template<>
struct ToString<bool> { struct to_string<bool> {
using Argument = bool;
using Result = std::string;
std::string operator()(bool b) { std::string operator()(bool b) {
return b ? "true" : "false"; return b ? "true" : "false";
} }
}; };
template<> template<>
struct ToString<char> { struct to_string<char> {
using Argument = char;
using Result = std::string;
std::string operator()(char c) { std::string operator()(char c) {
std::string ret; std::string ret;
ret += c; ret += c;
@ -652,9 +637,7 @@ struct ToString<char> {
#define OSTD_TOSTR_NUM(T) \ #define OSTD_TOSTR_NUM(T) \
template<> \ template<> \
struct ToString<T> { \ struct to_string<T> { \
using Argument = T; \
using Result = std::string; \
std::string operator()(T v) { \ std::string operator()(T v) { \
return std::to_string(v); \ return std::to_string(v); \
} \ } \
@ -678,10 +661,8 @@ OSTD_TOSTR_NUM(ldouble)
#undef OSTD_TOSTR_NUM #undef OSTD_TOSTR_NUM
template<typename T> template<typename T>
struct ToString<T *> { struct to_string<T *> {
using Argument = T *; std::string operator()(T *v) {
using Result = std::string;
std::string operator()(Argument v) {
char buf[16]; char buf[16];
sprintf(buf, "%p", v); sprintf(buf, "%p", v);
return buf; return buf;
@ -689,59 +670,47 @@ struct ToString<T *> {
}; };
template<> template<>
struct ToString<char const *> { struct to_string<char const *> {
using Argument = char const *;
using Result = std::string;
std::string operator()(char const *s) { std::string operator()(char const *s) {
return s; return s;
} }
}; };
template<> template<>
struct ToString<char *> { struct to_string<char *> {
using Argument = char *;
using Result = std::string;
std::string operator()(char *s) { std::string operator()(char *s) {
return s; return s;
} }
}; };
template<> template<>
struct ToString<std::string> { struct to_string<std::string> {
using Argument = std::string; std::string operator()(std::string const &s) {
using Result = std::string;
std::string operator()(Argument const &s) {
return s; return s;
} }
}; };
template<> template<>
struct ToString<char_range> { struct to_string<char_range> {
using Argument = char_range; std::string operator()(char_range const &s) {
using Result = std::string;
std::string operator()(Argument const &s) {
return std::string{s}; return std::string{s};
} }
}; };
template<> template<>
struct ToString<string_range> { struct to_string<string_range> {
using Argument = string_range; std::string operator()(string_range const &s) {
using Result = std::string;
std::string operator()(Argument const &s) {
return std::string{s}; return std::string{s};
} }
}; };
template<typename T, typename U> template<typename T, typename U>
struct ToString<std::pair<T, U>> { struct to_string<std::pair<T, U>> {
using Argument = std::pair<T, U>; std::string operator()(std::pair<T, U> const &v) {
using Result = std::string;
std::string operator()(Argument const &v) {
std::string ret{"{"}; std::string ret{"{"};
ret += ToString<std::remove_cv_t<std::remove_reference_t<T>>>()(v.first); ret += to_string<std::remove_cv_t<std::remove_reference_t<T>>>()(v.first);
ret += ", "; ret += ", ";
ret += ToString<std::remove_cv_t<std::remove_reference_t<U>>>()(v.second); ret += to_string<std::remove_cv_t<std::remove_reference_t<U>>>()(v.second);
ret += "}"; ret += "}";
return ret; return ret;
} }
@ -749,71 +718,59 @@ struct ToString<std::pair<T, U>> {
namespace detail { namespace detail {
template<size_t I, size_t N> template<size_t I, size_t N>
struct TupleToString { struct tuple_to_str {
template<typename T> template<typename T>
static void append(std::string &ret, T const &tup) { static void append(std::string &ret, T const &tup) {
ret += ", "; ret += ", ";
ret += ToString<std::remove_cv_t<std::remove_reference_t< ret += to_string<std::remove_cv_t<std::remove_reference_t<
decltype(std::get<I>(tup)) decltype(std::get<I>(tup))
>>>()(std::get<I>(tup)); >>>()(std::get<I>(tup));
TupleToString<I + 1, N>::append(ret, tup); tuple_to_str<I + 1, N>::append(ret, tup);
} }
}; };
template<size_t N> template<size_t N>
struct TupleToString<N, N> { struct tuple_to_str<N, N> {
template<typename T> template<typename T>
static void append(std::string &, T const &) {} static void append(std::string &, T const &) {}
}; };
template<size_t N> template<size_t N>
struct TupleToString<0, N> { struct tuple_to_str<0, N> {
template<typename T> template<typename T>
static void append(std::string &ret, T const &tup) { static void append(std::string &ret, T const &tup) {
ret += ToString<std::remove_cv_t<std::remove_reference_t< ret += to_string<std::remove_cv_t<std::remove_reference_t<
decltype(std::get<0>(tup)) decltype(std::get<0>(tup))
>>>()(std::get<0>(tup)); >>>()(std::get<0>(tup));
TupleToString<1, N>::append(ret, tup); tuple_to_str<1, N>::append(ret, tup);
} }
}; };
} }
template<typename ...T> template<typename ...T>
struct ToString<std::tuple<T...>> { struct to_string<std::tuple<T...>> {
using Argument = std::tuple<T...>; std::string operator()(std::tuple<T...> const &v) {
using Result = std::string;
std::string operator()(Argument const &v) {
std::string ret("{"); std::string ret("{");
detail::TupleToString<0, sizeof...(T)>::append(ret, v); detail::tuple_to_str<0, sizeof...(T)>::append(ret, v);
ret += "}"; ret += "}";
return ret; return ret;
} }
}; };
template<typename T>
typename ToString<T>::Result to_string(T const &v) {
return ToString<std::remove_cv_t<std::remove_reference_t<T>>>()(v);
}
template<typename T>
std::string to_string(std::initializer_list<T> init) {
return to_string(iter(init));
}
template<typename R> template<typename R>
struct TempCString { struct temp_c_string {
private: private:
std::remove_cv_t<range_value_t<R>> *p_buf; std::remove_cv_t<range_value_t<R>> *p_buf;
bool p_allocated; bool p_allocated;
public: public:
TempCString() = delete; temp_c_string() = delete;
TempCString(TempCString const &) = delete; temp_c_string(temp_c_string const &) = delete;
TempCString(TempCString &&s): p_buf(s.p_buf), p_allocated(s.p_allocated) { temp_c_string(temp_c_string &&s): p_buf(s.p_buf), p_allocated(s.p_allocated) {
s.p_buf = nullptr; s.p_buf = nullptr;
s.p_allocated = false; s.p_allocated = false;
} }
TempCString(R input, std::remove_cv_t<range_value_t<R>> *sbuf, size_t bufsize) temp_c_string(R input, std::remove_cv_t<range_value_t<R>> *sbuf, size_t bufsize)
: p_buf(nullptr), p_allocated(false) { : p_buf(nullptr), p_allocated(false) {
if (input.empty()) { if (input.empty()) {
return; return;
@ -826,14 +783,14 @@ public:
} }
p_buf[input.copy(p_buf)] = '\0'; p_buf[input.copy(p_buf)] = '\0';
} }
~TempCString() { ~temp_c_string() {
if (p_allocated) { if (p_allocated) {
delete[] p_buf; delete[] p_buf;
} }
} }
TempCString &operator=(TempCString const &) = delete; temp_c_string &operator=(temp_c_string const &) = delete;
TempCString &operator=(TempCString &&s) { temp_c_string &operator=(temp_c_string &&s) {
swap(s); swap(s);
return *this; return *this;
} }
@ -841,7 +798,7 @@ public:
operator std::remove_cv_t<range_value_t<R>> const *() const { return p_buf; } operator std::remove_cv_t<range_value_t<R>> const *() const { return p_buf; }
std::remove_cv_t<range_value_t<R>> const *get() const { return p_buf; } std::remove_cv_t<range_value_t<R>> const *get() const { return p_buf; }
void swap(TempCString &s) { void swap(temp_c_string &s) {
using std::swap; using std::swap;
swap(p_buf, s.p_buf); swap(p_buf, s.p_buf);
swap(p_allocated, s.p_allocated); swap(p_allocated, s.p_allocated);
@ -849,15 +806,15 @@ public:
}; };
template<typename R> template<typename R>
inline void swap(TempCString<R> &a, TempCString<R> &b) { inline void swap(temp_c_string<R> &a, temp_c_string<R> &b) {
a.swap(b); a.swap(b);
} }
template<typename R> template<typename R>
inline TempCString<R> to_temp_cstr( inline temp_c_string<R> to_temp_cstr(
R input, std::remove_cv_t<range_value_t<R>> *buf, size_t bufsize R input, std::remove_cv_t<range_value_t<R>> *buf, size_t bufsize
) { ) {
return TempCString<R>(input, buf, bufsize); return temp_c_string<R>(input, buf, bufsize);
} }
} /* namespace ostd */ } /* namespace ostd */

View File

@ -26,7 +26,7 @@ using ldouble = long double;
/* used occasionally for template variables */ /* used occasionally for template variables */
namespace detail { namespace detail {
template<typename> struct Undefined; template<typename> struct undef_t;
} }
} }

View File

@ -1,230 +0,0 @@
/* Utilities for OctaSTD.
*
* This file is part of OctaSTD. See COPYING.md for futher information.
*/
#ifndef OSTD_UTILITY_HH
#define OSTD_UTILITY_HH
#include <stddef.h>
#include <utility>
#include <tuple>
#include <type_traits>
#include "ostd/types.hh"
namespace ostd {
namespace detail {
template<typename T, typename U,
bool = std::is_same_v<std::remove_cv_t<T>, std::remove_cv_t<U>>,
bool = std::is_empty_v<T>, bool = std::is_empty_v<U>
>
constexpr size_t CompressedPairSwitch = detail::Undefined<T>();
/* neither empty */
template<typename T, typename U, bool Same>
constexpr size_t CompressedPairSwitch<T, U, Same, false, false> = 0;
/* first empty */
template<typename T, typename U, bool Same>
constexpr size_t CompressedPairSwitch<T, U, Same, true, false> = 1;
/* second empty */
template<typename T, typename U, bool Same>
constexpr size_t CompressedPairSwitch<T, U, Same, false, true> = 2;
/* both empty, not the same */
template<typename T, typename U>
constexpr size_t CompressedPairSwitch<T, U, false, true, true> = 3;
/* both empty and same */
template<typename T, typename U>
constexpr size_t CompressedPairSwitch<T, U, true, true, true> = 1;
template<typename T, typename U, size_t = CompressedPairSwitch<T, U>>
struct CompressedPairBase;
template<typename T, typename U>
struct CompressedPairBase<T, U, 0> {
T p_first;
U p_second;
template<typename TT, typename UU>
CompressedPairBase(TT &&a, UU &&b):
p_first(std::forward<TT>(a)), p_second(std::forward<UU>(b))
{}
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
CompressedPairBase(
std::piecewise_construct_t,
std::tuple<A1...> &fa, std::tuple<A2...> &sa,
std::index_sequence<I1...>, std::index_sequence<I2...>
);
T &first() { return p_first; }
T const &first() const { return p_first; }
U &second() { return p_second; }
U const &second() const { return p_second; }
void swap(CompressedPairBase &v) {
swap_adl(p_first, v.p_first);
swap_adl(p_second, v.p_second);
}
};
template<typename T, typename U>
struct CompressedPairBase<T, U, 1>: T {
U p_second;
template<typename TT, typename UU>
CompressedPairBase(TT &&a, UU &&b):
T(std::forward<TT>(a)), p_second(std::forward<UU>(b))
{}
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
CompressedPairBase(
std::piecewise_construct_t,
std::tuple<A1...> &fa, std::tuple<A2...> &sa,
std::index_sequence<I1...>, std::index_sequence<I2...>
);
T &first() { return *this; }
T const &first() const { return *this; }
U &second() { return p_second; }
U const &second() const { return p_second; }
void swap(CompressedPairBase &v) {
swap_adl(p_second, v.p_second);
}
};
template<typename T, typename U>
struct CompressedPairBase<T, U, 2>: U {
T p_first;
template<typename TT, typename UU>
CompressedPairBase(TT &&a, UU &&b):
U(std::forward<UU>(b)), p_first(std::forward<TT>(a))
{}
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
CompressedPairBase(
std::piecewise_construct_t,
std::tuple<A1...> &fa, std::tuple<A2...> &sa,
std::index_sequence<I1...>, std::index_sequence<I2...>
);
T &first() { return p_first; }
T const &first() const { return p_first; }
U &second() { return *this; }
U const &second() const { return *this; }
void swap(CompressedPairBase &v) {
swap_adl(p_first, v.p_first);
}
};
template<typename T, typename U>
struct CompressedPairBase<T, U, 3>: T, U {
template<typename TT, typename UU>
CompressedPairBase(TT &&a, UU &&b):
T(std::forward<TT>(a)), U(std::forward<UU>(b))
{}
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
CompressedPairBase(
std::piecewise_construct_t,
std::tuple<A1...> &fa, std::tuple<A2...> &sa,
std::index_sequence<I1...>, std::index_sequence<I2...>
);
T &first() { return *this; }
T const &first() const { return *this; }
U &second() { return *this; }
U const &second() const { return *this; }
void swap(CompressedPairBase &) {}
};
template<typename T, typename U>
struct CompressedPair: CompressedPairBase<T, U> {
using Base = CompressedPairBase<T, U>;
template<typename TT, typename UU>
CompressedPair(TT &&a, UU &&b):
Base(std::forward<TT>(a), std::forward<UU>(b))
{}
template<typename ...A1, typename ...A2>
CompressedPair(
std::piecewise_construct_t pc,
std::tuple<A1...> fa, std::tuple<A2...> sa
):
Base(
pc, fa, sa,
std::make_index_sequence<sizeof...(A1)>(),
std::make_index_sequence<sizeof...(A2)>()
)
{}
T &first() { return Base::first(); }
T const &first() const { return Base::first(); }
U &second() { return Base::second(); }
U const &second() const { return Base::second(); }
void swap(CompressedPair &v) {
Base::swap(v);
}
};
template<typename T, typename U>
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
CompressedPairBase<T, U, 0>::CompressedPairBase(
std::piecewise_construct_t, std::tuple<A1...> &fa, std::tuple<A2...> &sa,
std::index_sequence<I1...>, std::index_sequence<I2...>
):
p_first(std::forward<A1>(std::get<I1>(fa))...),
p_second(std::forward<A2>(std::get<I2>(sa))...)
{}
template<typename T, typename U>
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
CompressedPairBase<T, U, 1>::CompressedPairBase(
std::piecewise_construct_t, std::tuple<A1...> &fa, std::tuple<A2...> &sa,
std::index_sequence<I1...>, std::index_sequence<I2...>
):
T(std::forward<A1>(std::get<I1>(fa))...),
p_second(std::forward<A2>(std::get<I2>(sa))...)
{}
template<typename T, typename U>
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
CompressedPairBase<T, U, 2>::CompressedPairBase(
std::piecewise_construct_t, std::tuple<A1...> &fa, std::tuple<A2...> &sa,
std::index_sequence<I1...>, std::index_sequence<I2...>
):
U(std::forward<A2>(std::get<I2>(sa))...),
p_first(std::forward<A1>(std::get<I1>(fa))...)
{}
template<typename T, typename U>
template<typename ...A1, typename ...A2, size_t ...I1, size_t ...I2>
CompressedPairBase<T, U, 3>::CompressedPairBase(
std::piecewise_construct_t, std::tuple<A1...> &fa, std::tuple<A2...> &sa,
std::index_sequence<I1...>, std::index_sequence<I2...>
):
T(std::forward<A1>(std::get<I1>(fa))...),
U(std::forward<A2>(std::get<I2>(sa))...)
{}
} /* namespace detail */
} /* namespace ostd */
#endif

View File

@ -11,57 +11,57 @@
namespace ostd { namespace ostd {
template<typename T> template<typename T>
struct Vec2 { struct vec2 {
union { union {
struct { T x, y; }; struct { T x, y; };
T value[2]; T value[2];
}; };
Vec2(): x(0), y(0) {} vec2(): x(0), y(0) {}
Vec2(Vec2 const &v): x(v.x), y(v.y) {} vec2(vec2 const &v): x(v.x), y(v.y) {}
Vec2(T v): x(v), y(v) {} vec2(T v): x(v), y(v) {}
Vec2(T x, T y): x(x), y(y) {} vec2(T x, T y): x(x), y(y) {}
T &operator[](size_t idx) { return value[idx]; } T &operator[](size_t idx) { return value[idx]; }
T operator[](size_t idx) const { return value[idx]; } T operator[](size_t idx) const { return value[idx]; }
Vec2 &add(T v) { vec2 &add(T v) {
x += v; y += v; x += v; y += v;
return *this; return *this;
} }
Vec2 &add(Vec2 const &o) { vec2 &add(vec2 const &o) {
x += o.x; y += o.y; x += o.x; y += o.y;
return *this; return *this;
} }
Vec2 &sub(T v) { vec2 &sub(T v) {
x -= v; y -= v; x -= v; y -= v;
return *this; return *this;
} }
Vec2 &sub(Vec2 const &o) { vec2 &sub(vec2 const &o) {
x -= o.x; y -= o.y; x -= o.x; y -= o.y;
return *this; return *this;
} }
Vec2 &mul(T v) { vec2 &mul(T v) {
x *= v; y *= v; x *= v; y *= v;
return *this; return *this;
} }
Vec2 &mul(Vec2 const &o) { vec2 &mul(vec2 const &o) {
x *= o.x; y *= o.y; x *= o.x; y *= o.y;
return *this; return *this;
} }
Vec2 &div(T v) { vec2 &div(T v) {
x /= v; y /= v; x /= v; y /= v;
return *this; return *this;
} }
Vec2 &div(Vec2 const &o) { vec2 &div(vec2 const &o) {
x /= o.x; y /= o.y; x /= o.x; y /= o.y;
return *this; return *this;
} }
Vec2 &neg() { vec2 &neg() {
x = -x; y = -y; x = -x; y = -y;
return *this; return *this;
} }
@ -70,124 +70,124 @@ struct Vec2 {
return (x == 0) && (y == 0); return (x == 0) && (y == 0);
} }
T dot(Vec2<T> const &o) const { T dot(vec2<T> const &o) const {
return (x * o.x) + (y * o.y); return (x * o.x) + (y * o.y);
} }
}; };
template<typename T> template<typename T>
inline bool operator==(Vec2<T> const &a, Vec2<T> const &b) { inline bool operator==(vec2<T> const &a, vec2<T> const &b) {
return (a.x == b.x) && (a.y == b.y); return (a.x == b.x) && (a.y == b.y);
} }
template<typename T> template<typename T>
inline bool operator!=(Vec2<T> const &a, Vec2<T> const &b) { inline bool operator!=(vec2<T> const &a, vec2<T> const &b) {
return (a.x != b.x) || (a.y != b.y); return (a.x != b.x) || (a.y != b.y);
} }
template<typename T> template<typename T>
inline Vec2<T> operator+(Vec2<T> const &a, Vec2<T> const &b) { inline vec2<T> operator+(vec2<T> const &a, vec2<T> const &b) {
return Vec2<T>(a).add(b); return vec2<T>(a).add(b);
} }
template<typename T> template<typename T>
inline Vec2<T> operator+(Vec2<T> const &a, T b) { inline vec2<T> operator+(vec2<T> const &a, T b) {
return Vec2<T>(a).add(b); return vec2<T>(a).add(b);
} }
template<typename T> template<typename T>
inline Vec2<T> operator-(Vec2<T> const &a, Vec2<T> const &b) { inline vec2<T> operator-(vec2<T> const &a, vec2<T> const &b) {
return Vec2<T>(a).sub(b); return vec2<T>(a).sub(b);
} }
template<typename T> template<typename T>
inline Vec2<T> operator-(Vec2<T> const &a, T b) { inline vec2<T> operator-(vec2<T> const &a, T b) {
return Vec2<T>(a).sub(b); return vec2<T>(a).sub(b);
} }
template<typename T> template<typename T>
inline Vec2<T> operator*(Vec2<T> const &a, Vec2<T> const &b) { inline vec2<T> operator*(vec2<T> const &a, vec2<T> const &b) {
return Vec2<T>(a).mul(b); return vec2<T>(a).mul(b);
} }
template<typename T> template<typename T>
inline Vec2<T> operator*(Vec2<T> const &a, T b) { inline vec2<T> operator*(vec2<T> const &a, T b) {
return Vec2<T>(a).mul(b); return vec2<T>(a).mul(b);
} }
template<typename T> template<typename T>
inline Vec2<T> operator/(Vec2<T> const &a, Vec2<T> const &b) { inline vec2<T> operator/(vec2<T> const &a, vec2<T> const &b) {
return Vec2<T>(a).div(b); return vec2<T>(a).div(b);
} }
template<typename T> template<typename T>
inline Vec2<T> operator/(Vec2<T> const &a, T b) { inline vec2<T> operator/(vec2<T> const &a, T b) {
return Vec2<T>(a).div(b); return vec2<T>(a).div(b);
} }
template<typename T> template<typename T>
inline Vec2<T> operator-(Vec2<T> const &a) { inline vec2<T> operator-(vec2<T> const &a) {
return Vec2<T>(a).neg(); return vec2<T>(a).neg();
} }
using Vec2f = Vec2<float>; using vec2f = vec2<float>;
using Vec2d = Vec2<double>; using vec2d = vec2<double>;
using Vec2b = Vec2<byte>; using vec2b = vec2<byte>;
using Vec2i = Vec2<int>; using vec2i = vec2<int>;
template<typename T> template<typename T>
struct Vec3 { struct vec3 {
union { union {
struct { T x, y, z; }; struct { T x, y, z; };
struct { T r, g, b; }; struct { T r, g, b; };
T value[3]; T value[3];
}; };
Vec3(): x(0), y(0), z(0) {} vec3(): x(0), y(0), z(0) {}
Vec3(Vec3 const &v): x(v.x), y(v.y), z(v.z) {} vec3(vec3 const &v): x(v.x), y(v.y), z(v.z) {}
Vec3(T v): x(v), y(v), z(v) {} vec3(T v): x(v), y(v), z(v) {}
Vec3(T x, T y, T z): x(x), y(y), z(z) {} vec3(T x, T y, T z): x(x), y(y), z(z) {}
T &operator[](size_t idx) { return value[idx]; } T &operator[](size_t idx) { return value[idx]; }
T operator[](size_t idx) const { return value[idx]; } T operator[](size_t idx) const { return value[idx]; }
Vec3 &add(T v) { vec3 &add(T v) {
x += v; y += v; z += v; x += v; y += v; z += v;
return *this; return *this;
} }
Vec3 &add(Vec3 const &o) { vec3 &add(vec3 const &o) {
x += o.x; y += o.y; z += o.z; x += o.x; y += o.y; z += o.z;
return *this; return *this;
} }
Vec3 &sub(T v) { vec3 &sub(T v) {
x -= v; y -= v; z -= v; x -= v; y -= v; z -= v;
return *this; return *this;
} }
Vec3 &sub(Vec3 const &o) { vec3 &sub(vec3 const &o) {
x -= o.x; y -= o.y; z -= o.z; x -= o.x; y -= o.y; z -= o.z;
return *this; return *this;
} }
Vec3 &mul(T v) { vec3 &mul(T v) {
x *= v; y *= v; z *= v; x *= v; y *= v; z *= v;
return *this; return *this;
} }
Vec3 &mul(Vec3 const &o) { vec3 &mul(vec3 const &o) {
x *= o.x; y *= o.y; z *= o.z; x *= o.x; y *= o.y; z *= o.z;
return *this; return *this;
} }
Vec3 &div(T v) { vec3 &div(T v) {
x /= v; y /= v; z /= v; x /= v; y /= v; z /= v;
return *this; return *this;
} }
Vec3 &div(Vec3 const &o) { vec3 &div(vec3 const &o) {
x /= o.x; y /= o.y; z /= o.z; x /= o.x; y /= o.y; z /= o.z;
return *this; return *this;
} }
Vec3 &neg() { vec3 &neg() {
x = -x; y = -y; z = -z; x = -x; y = -y; z = -z;
return *this; return *this;
} }
@ -196,124 +196,124 @@ struct Vec3 {
return (x == 0) && (y == 0) && (z == 0); return (x == 0) && (y == 0) && (z == 0);
} }
T dot(Vec3<T> const &o) const { T dot(vec3<T> const &o) const {
return (x * o.x) + (y * o.y) + (z * o.z); return (x * o.x) + (y * o.y) + (z * o.z);
} }
}; };
template<typename T> template<typename T>
inline bool operator==(Vec3<T> const &a, Vec3<T> const &b) { inline bool operator==(vec3<T> const &a, vec3<T> const &b) {
return (a.x == b.x) && (a.y == b.y) && (a.z == b.z); return (a.x == b.x) && (a.y == b.y) && (a.z == b.z);
} }
template<typename T> template<typename T>
inline bool operator!=(Vec3<T> const &a, Vec3<T> const &b) { inline bool operator!=(vec3<T> const &a, vec3<T> const &b) {
return (a.x != b.x) || (a.y != b.y) || (a.z != b.z); return (a.x != b.x) || (a.y != b.y) || (a.z != b.z);
} }
template<typename T> template<typename T>
inline Vec3<T> operator+(Vec3<T> const &a, Vec3<T> const &b) { inline vec3<T> operator+(vec3<T> const &a, vec3<T> const &b) {
return Vec3<T>(a).add(b); return vec3<T>(a).add(b);
} }
template<typename T> template<typename T>
inline Vec3<T> operator+(Vec3<T> const &a, T b) { inline vec3<T> operator+(vec3<T> const &a, T b) {
return Vec3<T>(a).add(b); return vec3<T>(a).add(b);
} }
template<typename T> template<typename T>
inline Vec3<T> operator-(Vec3<T> const &a, Vec3<T> const &b) { inline vec3<T> operator-(vec3<T> const &a, vec3<T> const &b) {
return Vec3<T>(a).sub(b); return vec3<T>(a).sub(b);
} }
template<typename T> template<typename T>
inline Vec3<T> operator-(Vec3<T> const &a, T b) { inline vec3<T> operator-(vec3<T> const &a, T b) {
return Vec3<T>(a).sub(b); return vec3<T>(a).sub(b);
} }
template<typename T> template<typename T>
inline Vec3<T> operator*(Vec3<T> const &a, Vec3<T> const &b) { inline vec3<T> operator*(vec3<T> const &a, vec3<T> const &b) {
return Vec3<T>(a).mul(b); return vec3<T>(a).mul(b);
} }
template<typename T> template<typename T>
inline Vec3<T> operator*(Vec3<T> const &a, T b) { inline vec3<T> operator*(vec3<T> const &a, T b) {
return Vec3<T>(a).mul(b); return vec3<T>(a).mul(b);
} }
template<typename T> template<typename T>
inline Vec3<T> operator/(Vec3<T> const &a, Vec3<T> const &b) { inline vec3<T> operator/(vec3<T> const &a, vec3<T> const &b) {
return Vec3<T>(a).div(b); return vec3<T>(a).div(b);
} }
template<typename T> template<typename T>
inline Vec3<T> operator/(Vec3<T> const &a, T b) { inline vec3<T> operator/(vec3<T> const &a, T b) {
return Vec3<T>(a).div(b); return vec3<T>(a).div(b);
} }
template<typename T> template<typename T>
inline Vec3<T> operator-(Vec3<T> const &a) { inline vec3<T> operator-(vec3<T> const &a) {
return Vec3<T>(a).neg(); return vec3<T>(a).neg();
} }
using Vec3f = Vec3<float>; using vec3f = vec3<float>;
using Vec3d = Vec3<double>; using vec3d = vec3<double>;
using Vec3b = Vec3<byte>; using vec3b = vec3<byte>;
using Vec3i = Vec3<int>; using vec3i = vec3<int>;
template<typename T> template<typename T>
struct Vec4 { struct vec4 {
union { union {
struct { T x, y, z, w; }; struct { T x, y, z, w; };
struct { T r, g, b, a; }; struct { T r, g, b, a; };
T value[4]; T value[4];
}; };
Vec4(): x(0), y(0), z(0), w(0) {} vec4(): x(0), y(0), z(0), w(0) {}
Vec4(Vec4 const &v): x(v.x), y(v.y), z(v.z), w(v.w) {} vec4(vec4 const &v): x(v.x), y(v.y), z(v.z), w(v.w) {}
Vec4(T v): x(v), y(v), z(v), w(v) {} vec4(T v): x(v), y(v), z(v), w(v) {}
Vec4(T x, T y, T z, T w): x(x), y(y), z(z), w(w) {} vec4(T x, T y, T z, T w): x(x), y(y), z(z), w(w) {}
T &operator[](size_t idx) { return value[idx]; } T &operator[](size_t idx) { return value[idx]; }
T operator[](size_t idx) const { return value[idx]; } T operator[](size_t idx) const { return value[idx]; }
Vec4 &add(T v) { vec4 &add(T v) {
x += v; y += v; z += v; w += v; x += v; y += v; z += v; w += v;
return *this; return *this;
} }
Vec4 &add(Vec4 const &o) { vec4 &add(vec4 const &o) {
x += o.x; y += o.y; z += o.z; w += o.w; x += o.x; y += o.y; z += o.z; w += o.w;
return *this; return *this;
} }
Vec4 &sub(T v) { vec4 &sub(T v) {
x -= v; y -= v; z -= v; w -= v; x -= v; y -= v; z -= v; w -= v;
return *this; return *this;
} }
Vec4 &sub(Vec4 const &o) { vec4 &sub(vec4 const &o) {
x -= o.x; y -= o.y; z -= o.z; w -= o.w; x -= o.x; y -= o.y; z -= o.z; w -= o.w;
return *this; return *this;
} }
Vec4 &mul(T v) { vec4 &mul(T v) {
x *= v; y *= v; z *= v; w *= v; x *= v; y *= v; z *= v; w *= v;
return *this; return *this;
} }
Vec4 &mul(Vec4 const &o) { vec4 &mul(vec4 const &o) {
x *= o.x; y *= o.y; z *= o.z; w *= o.w; x *= o.x; y *= o.y; z *= o.z; w *= o.w;
return *this; return *this;
} }
Vec4 &div(T v) { vec4 &div(T v) {
x /= v; y /= v; z /= v; w /= v; x /= v; y /= v; z /= v; w /= v;
return *this; return *this;
} }
Vec4 &div(Vec4 const &o) { vec4 &div(vec4 const &o) {
x /= o.x; y /= o.y; z /= o.z; w /= o.w; x /= o.x; y /= o.y; z /= o.z; w /= o.w;
return *this; return *this;
} }
Vec4 &neg() { vec4 &neg() {
x = -x; y = -y; z = -z; w = -w; x = -x; y = -y; z = -z; w = -w;
return *this; return *this;
} }
@ -322,70 +322,70 @@ struct Vec4 {
return (x == 0) && (y == 0) && (z == 0) && (w == 0); return (x == 0) && (y == 0) && (z == 0) && (w == 0);
} }
T dot(Vec4<T> const &o) const { T dot(vec4<T> const &o) const {
return (x * o.x) + (y * o.y) + (z * o.z) + (w * o.w); return (x * o.x) + (y * o.y) + (z * o.z) + (w * o.w);
} }
}; };
template<typename T> template<typename T>
inline bool operator==(Vec4<T> const &a, Vec4<T> const &b) { inline bool operator==(vec4<T> const &a, vec4<T> const &b) {
return (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w); return (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w);
} }
template<typename T> template<typename T>
inline bool operator!=(Vec4<T> const &a, Vec4<T> const &b) { inline bool operator!=(vec4<T> const &a, vec4<T> const &b) {
return (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w); return (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w);
} }
template<typename T> template<typename T>
inline Vec4<T> operator+(Vec4<T> const &a, Vec4<T> const &b) { inline vec4<T> operator+(vec4<T> const &a, vec4<T> const &b) {
return Vec4<T>(a).add(b); return vec4<T>(a).add(b);
} }
template<typename T> template<typename T>
inline Vec4<T> operator+(Vec4<T> const &a, T b) { inline vec4<T> operator+(vec4<T> const &a, T b) {
return Vec4<T>(a).add(b); return vec4<T>(a).add(b);
} }
template<typename T> template<typename T>
inline Vec4<T> operator-(Vec4<T> const &a, Vec4<T> const &b) { inline vec4<T> operator-(vec4<T> const &a, vec4<T> const &b) {
return Vec4<T>(a).sub(b); return vec4<T>(a).sub(b);
} }
template<typename T> template<typename T>
inline Vec4<T> operator-(Vec4<T> const &a, T b) { inline vec4<T> operator-(vec4<T> const &a, T b) {
return Vec4<T>(a).sub(b); return vec4<T>(a).sub(b);
} }
template<typename T> template<typename T>
inline Vec4<T> operator*(Vec4<T> const &a, Vec4<T> const &b) { inline vec4<T> operator*(vec4<T> const &a, vec4<T> const &b) {
return Vec4<T>(a).mul(b); return vec4<T>(a).mul(b);
} }
template<typename T> template<typename T>
inline Vec4<T> operator*(Vec4<T> const &a, T b) { inline vec4<T> operator*(vec4<T> const &a, T b) {
return Vec4<T>(a).mul(b); return vec4<T>(a).mul(b);
} }
template<typename T> template<typename T>
inline Vec4<T> operator/(Vec4<T> const &a, Vec4<T> const &b) { inline vec4<T> operator/(vec4<T> const &a, vec4<T> const &b) {
return Vec4<T>(a).div(b); return vec4<T>(a).div(b);
} }
template<typename T> template<typename T>
inline Vec4<T> operator/(Vec4<T> const &a, T b) { inline vec4<T> operator/(vec4<T> const &a, T b) {
return Vec4<T>(a).div(b); return vec4<T>(a).div(b);
} }
template<typename T> template<typename T>
inline Vec4<T> operator-(Vec4<T> const &a) { inline vec4<T> operator-(vec4<T> const &a) {
return Vec4<T>(a).neg(); return vec4<T>(a).neg();
} }
using Vec4f = Vec4<float>; using vec4f = vec4<float>;
using Vec4d = Vec4<double>; using vec4d = vec4<double>;
using Vec4b = Vec4<byte>; using vec4b = vec4<byte>;
using Vec4i = Vec4<int>; using vec4i = vec4<int>;
} /* namespace ostd */ } /* namespace ostd */