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 */
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()) {
case 'i':
writer.put_string("Foo1");
@ -27,7 +27,7 @@ void to_format(Foo const &, R &writer, FormatSpec const &fs) {
struct Bar {
/* implementing formatting for custom objects - method */
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()) {
case 'i':
writer.put_string("Bar1");

View File

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

View File

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

View File

@ -8,17 +8,17 @@ void print_result(uint32_t x) {
}
int main() {
FileStream wtest{"test.bin", StreamMode::write};
file_stream wtest{"test.bin", stream_mode::WRITE};
copy(
iter({ 0xABCD1214, 0xBADC3264, 0xDEADBEEF, 0xBEEFDEAD }),
wtest.iter<uint32_t>()
);
wtest.close();
FileStream rtest{"test.bin"};
file_stream rtest{"test.bin"};
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);
}

View File

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

View File

@ -10,9 +10,9 @@
#include <utility>
#include <functional>
#include <type_traits>
#include "ostd/range.hh"
#include "ostd/utility.hh"
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.
*/
@ -7,17 +7,16 @@
#define OSTD_EVENT_HH
#include <functional>
#include "ostd/utility.hh"
#include <utility>
namespace ostd {
namespace detail {
template<typename C, typename ...A>
struct SignalBase {
SignalBase(C *cl): p_class(cl), p_funcs(nullptr), p_nfuncs(0) {}
struct signal_base {
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)
{
using func_t = std::function<void(C &, A...)>;
@ -28,13 +27,13 @@ namespace detail {
p_funcs = nbuf;
}
SignalBase(SignalBase &&ev):
signal_base(signal_base &&ev):
p_class(nullptr), p_funcs(nullptr), p_nfuncs(0)
{
swap(ev);
}
SignalBase &operator=(SignalBase const &ev) {
signal_base &operator=(signal_base const &ev) {
using func_t = std::function<void(C &, A...)>;
p_class = ev.p_class;
p_nfuncs = ev.p_nfuncs;
@ -47,12 +46,12 @@ namespace detail {
return *this;
}
SignalBase &operator=(SignalBase &&ev) {
signal_base &operator=(signal_base &&ev) {
swap(ev);
return *this;
}
~SignalBase() { clear(); }
~signal_base() { clear(); }
void clear() {
for (size_t i = 0; i < p_nfuncs; ++i) {
@ -115,7 +114,7 @@ namespace detail {
return ocl;
}
void swap(SignalBase &ev) {
void swap(signal_base &ev) {
using std::swap;
swap(p_class, ev.p_class);
swap(p_funcs, ev.p_funcs);
@ -130,21 +129,21 @@ namespace detail {
} /* namespace detail */
template<typename C, typename ...A>
struct Signal {
struct signal {
private:
using Base = detail::SignalBase<C, A...>;
Base p_base;
using base_t = detail::signal_base<C, A...>;
base_t p_base;
public:
Signal(C *cl): p_base(cl) {}
Signal(Signal const &ev): p_base(ev.p_base) {}
Signal(Signal &&ev): p_base(std::move(ev.p_base)) {}
signal(C *cl): p_base(cl) {}
signal(signal const &ev): p_base(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;
return *this;
}
Signal &operator=(Signal &&ev) {
signal &operator=(signal &&ev) {
p_base = std::move(ev.p_base);
return *this;
}
@ -165,25 +164,25 @@ public:
C *get_class() const { return p_base.get_class(); }
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>
struct Signal<C const, A...> {
struct signal<C const, A...> {
private:
using Base = detail::SignalBase<C const, A...>;
Base p_base;
using base_t = detail::signal_base<C const, A...>;
base_t p_base;
public:
Signal(C *cl): p_base(cl) {}
Signal(Signal const &ev): p_base(ev.p_base) {}
Signal(Signal &&ev): p_base(std::move(ev.p_base)) {}
signal(C *cl): p_base(cl) {}
signal(signal const &ev): p_base(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;
return *this;
}
Signal &operator=(Signal &&ev) {
signal &operator=(signal &&ev) {
p_base = std::move(ev.p_base);
return *this;
}
@ -204,11 +203,11 @@ public:
C *get_class() const { return p_base.get_class(); }
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>
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);
}

View File

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

View File

@ -15,7 +15,6 @@
#include "ostd/algorithm.hh"
#include "ostd/string.hh"
#include "ostd/utility.hh"
namespace ostd {
@ -132,13 +131,13 @@ namespace detail {
}
}
struct FormatSpec {
FormatSpec(): p_nested_escape(false), p_fmt() {}
FormatSpec(string_range fmt, bool escape = false):
struct format_spec {
format_spec(): p_nested_escape(false), p_fmt() {}
format_spec(string_range fmt, bool escape = false):
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_width((width >= 0) ? width : 0),
p_precision((prec >= 0) ? prec : 0),
@ -437,17 +436,17 @@ protected:
template<
typename T, typename R, typename = std::enable_if_t<
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>
>
>
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);
}
namespace detail {
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];
size_t r = 0, n = 0;
@ -564,9 +563,9 @@ namespace detail {
template<typename R, typename T>
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,
std::enable_if_t<detail::IterableTest<T>, bool> = true
std::enable_if_t<detail::iterable_test<T>, bool> = true
) {
/* XXX: maybe handle error cases? */
auto range = ostd::iter(val);
@ -591,21 +590,21 @@ namespace detail {
template<typename R, typename T>
inline size_t write_range(
R &, FormatSpec const *, bool, bool, string_range,
T const &, std::enable_if_t<!detail::IterableTest<T>, bool> = true
R &, format_spec const *, bool, bool, string_range,
T const &, std::enable_if_t<!detail::iterable_test<T>, bool> = true
) {
throw format_error{"invalid value for ranged format"};
}
template<typename T>
static std::true_type test_fmt_tostr(
decltype(ostd::to_string(std::declval<T>())) *
decltype(ostd::to_string<T>{}(std::declval<T>())) *
);
template<typename>
static std::false_type test_fmt_tostr(...);
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) */
static constexpr char const *fmt_escapes[] = {
@ -648,17 +647,17 @@ namespace detail {
template<typename T, typename R>
static std::true_type test_tofmt(decltype(to_format(
std::declval<T const &>(), std::declval<R &>(),
std::declval<FormatSpec const &>()
std::declval<format_spec const &>()
)) *);
template<typename, typename>
static std::false_type test_tofmt(...);
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 {
using FormatSpec::FormatSpec;
struct write_spec: format_spec {
using format_spec::format_spec;
/* string base writer */
template<typename R>
@ -757,7 +756,7 @@ namespace detail {
template<typename R, typename T>
size_t write_val(R &writer, bool escape, T const &val) const {
/* 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);
to_format(val, sink, *this);
return sink.get_written();
@ -788,7 +787,7 @@ namespace detail {
* char pointers are handled by the string case above
*/
if constexpr(std::is_pointer_v<T>) {
FormatSpec sp{
format_spec sp{
(spec() == 's') ? 'x' : spec(),
has_width() ? width() : -1,
has_precision() ? precision() : -1,
@ -815,11 +814,11 @@ namespace detail {
return write_float(writer, escape, val);
}
/* 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') {
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 */
throw format_error{"the value cannot be formatted"};
@ -866,7 +865,7 @@ namespace detail {
R &writer, bool escape, string_range fmt, A const &...args
) {
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)) {
written += twr;
size_t argpos = spec.index();
@ -875,7 +874,7 @@ namespace detail {
argpos = argidx++;
}
/* 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(
writer, argpos - 1, (spec.flags() & FMT_FLAG_HASH),
spec.nested_sep(), args...
@ -916,7 +915,7 @@ namespace detail {
template<typename R>
inline ptrdiff_t format_impl(R &writer, bool, string_range fmt) {
size_t written = 0;
detail::WriteSpec spec(fmt, false);
detail::write_spec spec(fmt, false);
if (spec.read_until_spec(writer, &written)) {
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>
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 */
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);
}

View File

@ -17,8 +17,8 @@
namespace ostd {
enum class StreamMode {
read = 0, write, append, read_u, write_u, append_u
enum class stream_mode {
READ = 0, WRITE, APPEND, READ_U, WRITE_U, APPEND_U
};
namespace detail {
@ -27,30 +27,30 @@ namespace detail {
};
}
struct FileStream: Stream {
FileStream(): p_f(), p_owned(false) {}
FileStream(FileStream const &) = delete;
FileStream(FileStream &&s): p_f(s.p_f), p_owned(s.p_owned) {
struct file_stream: stream {
file_stream(): p_f(), p_owned(false) {}
file_stream(file_stream const &) = delete;
file_stream(file_stream &&s): p_f(s.p_f), p_owned(s.p_owned) {
s.p_f = nullptr;
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);
}
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;
FileStream &operator=(FileStream &&s) {
file_stream &operator=(file_stream const &) = delete;
file_stream &operator=(file_stream &&s) {
close();
swap(s);
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)) {
return false;
}
@ -93,7 +93,7 @@ struct FileStream: Stream {
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
return fseeko(p_f, pos, int(whence)) >= 0;
#else
@ -101,7 +101,7 @@ struct FileStream: Stream {
#endif
}
StreamOffset tell() const {
stream_off_t tell() const {
#ifndef OSTD_PLATFORM_WIN32
return ftello(p_f);
#else
@ -127,7 +127,7 @@ struct FileStream: Stream {
return fputc(c, p_f) != EOF;
}
void swap(FileStream &s) {
void swap(file_stream &s) {
using std::swap;
swap(p_f, s.p_f);
swap(p_owned, s.p_owned);
@ -140,38 +140,38 @@ private:
bool p_owned;
};
inline void swap(FileStream &a, FileStream &b) {
inline void swap(file_stream &a, file_stream &b) {
a.swap(b);
}
static FileStream in(stdin);
static FileStream out(stdout);
static FileStream err(stderr);
static file_stream in(stdin);
static file_stream out(stdout);
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 {
/* lightweight output range for direct stdout */
struct StdoutRange: output_range<StdoutRange> {
struct stdout_range: output_range<stdout_range> {
using value_type = char;
using reference = char &;
using size_type = size_t;
using difference_type = ptrdiff_t;
StdoutRange() {}
stdout_range() {}
bool put(char c) {
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);
}
}
template<typename T>
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>
@ -200,7 +200,7 @@ inline void writeln(T const &v, A const &...args) {
template<typename ...A>
inline void writef(string_range fmt, A const &...args) {
format(detail::StdoutRange{}, fmt, args...);
format(detail::stdout_range{}, fmt, args...);
}
template<typename ...A>

View File

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

View File

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

View File

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

View File

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

View File

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