Remove unneccessary files from utils
Reviewers: buda Reviewed By: buda Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D276
This commit is contained in:
parent
59a9aaea16
commit
bba20cf89c
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "logging/logger.hpp"
|
||||
#include "query/typed_value.hpp"
|
||||
#include "utils/bswap.hpp"
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -56,9 +57,7 @@ class BaseEncoder : public Loggable {
|
||||
WriteRAW(reinterpret_cast<const uint8_t *>(&value), sizeof(value));
|
||||
}
|
||||
|
||||
void WriteNull() {
|
||||
WriteRAW(underlying_cast(Marker::Null));
|
||||
}
|
||||
void WriteNull() { WriteRAW(underlying_cast(Marker::Null)); }
|
||||
|
||||
void WriteBool(const bool &value) {
|
||||
if (value)
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "storage/unique_object_store.hpp"
|
||||
#include "storage/vertex.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "utils/pass_key.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
|
||||
// TODO: Maybe split this in another layer between Db and Dbms. Where the new
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "io/network/addrinfo.hpp"
|
||||
|
||||
#include "io/network/network_error.hpp"
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
namespace io::network {
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "traversal/path.hpp"
|
||||
#include "utils/exceptions/basic_exception.hpp"
|
||||
#include "utils/total_ordering.hpp"
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
namespace query {
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "storage/edge.hpp"
|
||||
#include "storage/record_accessor.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
#include "utils/reference_wrapper.hpp"
|
||||
|
||||
// forward declaring the VertexAccessor because it's returned
|
||||
// by some functions
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "utils/exceptions/stacktrace_exception.hpp"
|
||||
#include "utils/total_ordering.hpp"
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
/**
|
||||
* Encapsulation of a value and it's type encapsulated in a class that has no
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "storage/record_accessor.hpp"
|
||||
#include "database/graph_db_accessor.hpp"
|
||||
#include "storage/edge.hpp"
|
||||
#include "storage/record_accessor.hpp"
|
||||
#include "storage/vertex.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
|
||||
@ -48,7 +48,7 @@ GraphDbAccessor &RecordAccessor<TRecord>::db_accessor() const {
|
||||
}
|
||||
|
||||
template <typename TRecord>
|
||||
const uint64_t RecordAccessor<TRecord>::temporary_id() const {
|
||||
uint64_t RecordAccessor<TRecord>::temporary_id() const {
|
||||
return (uint64_t)vlist_;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
//#include "database/graph_db_accessor.hpp"
|
||||
#include "mvcc/version_list.hpp"
|
||||
#include "storage/property_value.hpp"
|
||||
#include "utils/pass_key.hpp"
|
||||
|
||||
#include "storage/property_value_store.hpp"
|
||||
|
||||
@ -134,7 +133,7 @@ class RecordAccessor {
|
||||
*
|
||||
* @return See above.
|
||||
*/
|
||||
const uint64_t temporary_id() const;
|
||||
uint64_t temporary_id() const;
|
||||
|
||||
/*
|
||||
* Switches this record accessor to use the latest
|
||||
|
@ -4,9 +4,19 @@
|
||||
#include <stdint.h>
|
||||
#include <atomic>
|
||||
|
||||
#include <linux/futex.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "lock_timeout_error.hpp"
|
||||
#include "utils/cpu_relax.hpp"
|
||||
#include "utils/sys.hpp"
|
||||
|
||||
namespace sys {
|
||||
inline int futex(void *addr1, int op, int val1, const struct timespec *timeout,
|
||||
void *addr2, int val3) {
|
||||
return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
|
||||
};
|
||||
}
|
||||
|
||||
class Futex {
|
||||
using futex_t = uint32_t;
|
||||
@ -61,7 +71,7 @@ class Futex {
|
||||
UNLOCKED;
|
||||
}
|
||||
|
||||
void lock(const struct timespec* timeout = nullptr) {
|
||||
void lock(const struct timespec *timeout = nullptr) {
|
||||
// try to fast lock a few times before going to sleep
|
||||
for (size_t i = 0; i < LOCK_RETRIES; ++i) {
|
||||
// try to lock and exit if we succeed
|
||||
@ -125,7 +135,7 @@ class Futex {
|
||||
private:
|
||||
mutex_t mutex;
|
||||
|
||||
int futex_wait(int value, const struct timespec* timeout = nullptr) {
|
||||
int futex_wait(int value, const struct timespec *timeout = nullptr) {
|
||||
return sys::futex(&mutex.all, FUTEX_WAIT_PRIVATE, value, timeout, nullptr,
|
||||
0);
|
||||
}
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
class Thread {
|
||||
static std::atomic<unsigned> thread_counter;
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// FROM: A Malloc Tutorial, Marwan Burelle, 2009
|
||||
|
||||
// align address x to 4 bytes
|
||||
#define align_4(x) (((((x)-1) >> 2) << 2) + 4)
|
||||
|
||||
// align address x to 8 bytes
|
||||
#define align_8(x) (((((x)-1) >> 3) << 3) + 8)
|
@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace bash_color {
|
||||
auto blue = "\033[94m";
|
||||
auto green = "\033[92m";
|
||||
auto yellow = "\033[93m";
|
||||
auto red = "\033[91m";
|
||||
auto end = "\033[0m";
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "utils/numerics/ceil.hpp"
|
||||
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(size_t capacity, size_t chunk_size)
|
||||
: capacity(capacity), chunk_size(chunk_size) {}
|
||||
|
||||
Buffer& append(const std::string& string) {
|
||||
return this->append(string.c_str(), string.size());
|
||||
}
|
||||
|
||||
Buffer& append(const char* string, size_t n) {
|
||||
auto new_size = size() + n;
|
||||
|
||||
if (capacity < new_size) {
|
||||
capacity = new_size;
|
||||
data = static_cast<char*>(realloc(data, new_size));
|
||||
}
|
||||
|
||||
size = new_size;
|
||||
}
|
||||
|
||||
Buffer& operator<<(const std::string& string) {}
|
||||
|
||||
size_t size() const { return str.size(); }
|
||||
|
||||
private:
|
||||
size_t size_, capacity, chunk_size;
|
||||
char* data;
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include "utils/total_ordering.hpp"
|
||||
|
||||
class CharStr : public TotalOrdering<CharStr> {
|
||||
public:
|
||||
CharStr(const char *str) : str(str) {}
|
||||
|
||||
std::string to_string() const { return std::string(str); }
|
||||
|
||||
friend bool operator==(const CharStr &lhs, const CharStr &rhs) {
|
||||
return strcmp(lhs.str, rhs.str) == 0;
|
||||
}
|
||||
|
||||
friend bool operator<(const CharStr &lhs, const CharStr &rhs) {
|
||||
return strcmp(lhs.str, rhs.str) < 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const char *str;
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
template <class T>
|
||||
class EqWrapper {
|
||||
public:
|
||||
EqWrapper(T t) : t(t) {}
|
||||
|
||||
friend bool operator==(const EqWrapper &a, const EqWrapper &b) {
|
||||
return a.t == b.t;
|
||||
}
|
||||
|
||||
friend bool operator!=(const EqWrapper &a, const EqWrapper &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
T t;
|
||||
};
|
@ -8,9 +8,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <unistd.h>
|
||||
#include <unistd.h>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
@ -23,11 +25,26 @@ namespace fs = std::experimental::filesystem;
|
||||
#include "logging/loggable.hpp"
|
||||
#include "utils/algorithm.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
#include "utils/exceptions/stacktrace_exception.hpp"
|
||||
#include "utils/linux.hpp"
|
||||
#include "utils/exceptions/basic_exception.hpp"
|
||||
#include "utils/likely.hpp"
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
namespace utils {
|
||||
namespace linux_os {
|
||||
void set_non_blocking(int fd) {
|
||||
auto flags = fcntl(fd, F_GETFL, 0);
|
||||
|
||||
if (UNLIKELY(flags == -1))
|
||||
throw BasicException("Cannot read flags from file descriptor.");
|
||||
|
||||
flags |= O_NONBLOCK;
|
||||
|
||||
auto status = fcntl(fd, F_SETFL, flags);
|
||||
|
||||
if (UNLIKELY(status == -1))
|
||||
throw BasicException("Can't set NON_BLOCK flag to file descriptor");
|
||||
}
|
||||
}
|
||||
|
||||
using ms = std::chrono::milliseconds;
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Source object is going to be traversed by Writer and Writer will
|
||||
* write that data into the Destination object.
|
||||
*
|
||||
* Writer object defines write format.
|
||||
*/
|
||||
template <typename Destination, typename Writer, typename Source>
|
||||
Destination handle_write(const Source& source) {
|
||||
Destination destination;
|
||||
Writer writter(destination);
|
||||
source.handle(writter);
|
||||
return destination;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/range_iterator.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace iter {
|
||||
// Class which turns ranged iterator with next() into accessor.
|
||||
// T - type of return value
|
||||
// I - iterator type
|
||||
template <class T, class I>
|
||||
class OneTimeAccessor {
|
||||
public:
|
||||
OneTimeAccessor() : it(Option<RangeIterator<T, I>>()) {}
|
||||
OneTimeAccessor(I &&it) : it(RangeIterator<T, I>(std::move(it))) {}
|
||||
|
||||
RangeIterator<T, I> begin() { return it.take(); }
|
||||
|
||||
RangeIterator<T, I> end() { return RangeIterator<T, I>(); }
|
||||
|
||||
private:
|
||||
Option<RangeIterator<T, I>> it;
|
||||
};
|
||||
|
||||
template <class I>
|
||||
auto make_one_time_accessor(I &&iter) {
|
||||
// Because function isn't receving or in any way using type T from
|
||||
// OneTimeAccessor compiler can't deduce it thats way there is decltype in
|
||||
// construction of OneTimeAccessor. Resoulting type of iter.next().take() is
|
||||
// T.
|
||||
return OneTimeAccessor<decltype(iter.next().take()), I>(std::move(iter));
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
// Class which Combined two iterators IT1 and IT2.
|
||||
// Both return values T
|
||||
// T - type of return value
|
||||
// IT1 - first iterator type
|
||||
// IT2 - second iterator type
|
||||
template <class T, class IT1, class IT2>
|
||||
class Combined : public IteratorBase<T>,
|
||||
public Composable<T, Combined<T, IT1, IT2>> {
|
||||
public:
|
||||
Combined() = delete;
|
||||
|
||||
// Combined operation is designed to be used in chained calls which operate
|
||||
// on a iterator. Combined will in that usecase receive other iterator by
|
||||
// value and std::move is a optimization for it.
|
||||
Combined(IT1 &&iter1, IT2 &&iter2)
|
||||
: iter1(Option<IT1>(std::move(iter1))),
|
||||
iter2(Option<IT2>(std::move(iter2))) {}
|
||||
|
||||
// Return values first from first iterator then from second.
|
||||
Option<T> next() final {
|
||||
if (iter1.is_present()) {
|
||||
auto ret = iter1.get().next();
|
||||
if (ret.is_present()) {
|
||||
return std::move(ret);
|
||||
} else {
|
||||
iter1.take();
|
||||
}
|
||||
}
|
||||
|
||||
return iter2.next();
|
||||
}
|
||||
|
||||
Count count() final {
|
||||
return iter1.map_or([](auto &it) { return it.count(); }, 0) + iter2.count();
|
||||
}
|
||||
|
||||
private:
|
||||
Option<IT1> iter1;
|
||||
IT2 iter2;
|
||||
};
|
||||
|
||||
template <class IT1, class IT2>
|
||||
auto make_combined(IT1 &&iter1, IT2 &&iter2) {
|
||||
// Compiler cant deduce type T. decltype is here to help with it.
|
||||
return Combined<decltype(iter1.next().take()), IT1, IT2>(std::move(iter1),
|
||||
std::move(iter2));
|
||||
}
|
||||
}
|
@ -1,190 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/crtp.hpp"
|
||||
#include "utils/iterator/count.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_map(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_filter(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class C>
|
||||
void for_all(I &&iter, C &&consumer);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_flat_map(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_inspect(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_limited_map(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_virtual(I &&iter);
|
||||
|
||||
template <class IT1, class IT2>
|
||||
auto make_combined(IT1 &&iter1, IT2 &&iter2);
|
||||
|
||||
// Class for creating easy composable iterators fo querying.
|
||||
//
|
||||
// Derived - type of derived class
|
||||
// T - return type
|
||||
template <class T, class Derived>
|
||||
class Composable : public Crtp<Derived> {
|
||||
// Moves self
|
||||
Derived &&move() { return std::move(this->derived()); }
|
||||
|
||||
public:
|
||||
auto virtualize() { return iter::make_virtual(move()); }
|
||||
|
||||
template <class IT>
|
||||
auto combine(IT &&it) {
|
||||
return iter::make_combined<Derived, IT>(move(), std::move(it));
|
||||
}
|
||||
|
||||
template <class OP>
|
||||
auto map(OP &&op) {
|
||||
return iter::make_map<Derived, OP>(move(), std::move(op));
|
||||
}
|
||||
|
||||
template <class OP>
|
||||
auto filter(OP &&op) {
|
||||
return iter::make_filter<Derived, OP>(move(), std::move(op));
|
||||
}
|
||||
|
||||
// Replaces every item with item taken from n if it exists.
|
||||
template <class R>
|
||||
auto replace(Option<R> &n) {
|
||||
return iter::make_limited_map<Derived>(
|
||||
move(), [&](auto v) mutable { return std::move(n); });
|
||||
}
|
||||
|
||||
// For all items calls OP.
|
||||
template <class OP>
|
||||
void for_all(OP &&op) {
|
||||
iter::for_all(move(), std::move(op));
|
||||
}
|
||||
|
||||
// All items must satisfy given predicate for this function to return true.
|
||||
// Otherwise stops calling predicate on firts false and returns fasle.
|
||||
template <class OP>
|
||||
bool all(OP &&op) {
|
||||
auto iter = move();
|
||||
auto e = iter.next();
|
||||
while (e.is_present()) {
|
||||
if (!op(e.take())) {
|
||||
return false;
|
||||
}
|
||||
e = iter.next();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// !! MEMGRAPH specific composable filters
|
||||
// TODO: isolate, but it is not trivial because this class
|
||||
// is a base for other generic classes
|
||||
|
||||
// Maps with call to method to() and filters with call to fill.
|
||||
auto to() {
|
||||
return map([](auto er) { return er.to(); }).fill();
|
||||
}
|
||||
|
||||
// Maps with call to method from() and filters with call to fill.
|
||||
auto from() {
|
||||
return map([](auto er) { return er.from(); }).fill();
|
||||
}
|
||||
|
||||
// Combines out iterators into one iterator.
|
||||
auto out() {
|
||||
return iter::make_flat_map<Derived>(
|
||||
move(), [](auto vr) { return vr.out().fill(); });
|
||||
}
|
||||
|
||||
auto in() {
|
||||
return iter::make_flat_map<Derived>(move(),
|
||||
[](auto vr) { return vr.in().fill(); });
|
||||
}
|
||||
|
||||
// Filters with label on from vertex.
|
||||
template <class LABEL>
|
||||
auto from_label(LABEL const &label) {
|
||||
return filter([&](auto &ra) {
|
||||
auto va = ra.from();
|
||||
return va.fill() && va.has_label(label);
|
||||
});
|
||||
}
|
||||
|
||||
// Calls update on values and returns result.
|
||||
auto update() {
|
||||
return map([](auto ar) { return ar.update(); });
|
||||
}
|
||||
|
||||
// Filters with property under given key
|
||||
template <class KEY>
|
||||
auto has_property(KEY &key) {
|
||||
return filter([&](auto &va) { return !va.at(key).is_empty(); });
|
||||
}
|
||||
|
||||
// Filters with property under given key
|
||||
template <class KEY, class PROP>
|
||||
auto has_property(KEY &key, PROP const &prop) {
|
||||
return filter([&](auto &va) { return va.at(key) == prop; });
|
||||
}
|
||||
|
||||
// Copy-s pasing value to t before they are returned.
|
||||
auto clone_to(Option<const T> &t) {
|
||||
return iter::make_inspect<Derived>(
|
||||
move(), [&](auto &v) mutable { t = Option<const T>(v); });
|
||||
}
|
||||
|
||||
// auto clone_to(Option<T> &t)
|
||||
// {
|
||||
// return iter::make_inspect<Derived>(
|
||||
// move(), [&](auto &e) mutable { t = Option<T>(e); });
|
||||
// }
|
||||
|
||||
// Filters with call to method fill()
|
||||
auto fill() {
|
||||
return filter([](auto &ra) { return ra.fill(); });
|
||||
}
|
||||
|
||||
// Filters with type
|
||||
template <class TYPE>
|
||||
auto type(TYPE const &type) {
|
||||
return filter([&](auto &ra) { return ra.edge_type() == type; });
|
||||
}
|
||||
|
||||
// Filters with label.
|
||||
template <class LABEL>
|
||||
auto label(LABEL const &label) {
|
||||
return filter([&](auto &va) { return va.has_label(label); });
|
||||
}
|
||||
|
||||
// Filters out vertices which are connected.
|
||||
auto isolated() {
|
||||
return filter([&](auto &element) { return element.isolated(); });
|
||||
}
|
||||
|
||||
// filter elements based on properties (all properties have to match)
|
||||
// TRANSACTION -> transaction
|
||||
// PROPERTIES -> [(name, property)]
|
||||
template <class TRANSACTION, class PROPERTIES>
|
||||
auto properties_filter(TRANSACTION &t, PROPERTIES &properties) {
|
||||
return filter([&](auto &element) {
|
||||
for (auto &name_value : properties) {
|
||||
auto property_key = t.vertex_property_key(
|
||||
name_value.first, name_value.second.key.flags());
|
||||
if (!element.properties().contains(property_key)) return false;
|
||||
auto vertex_property_value = element.at(property_key);
|
||||
if (!(vertex_property_value == name_value.second)) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/numerics/saturate.hpp"
|
||||
#include "utils/total_ordering.hpp"
|
||||
|
||||
// Represents number of to be returned elements from iterator. Where acutal
|
||||
// number is probably somwhere in [min,max].
|
||||
// NOTE: Experimental
|
||||
class Count : public TotalOrdering<Count> {
|
||||
public:
|
||||
Count(size_t exact) : min(exact), max(exact) {}
|
||||
|
||||
Count(size_t min, size_t max) : min(min), max(max) {}
|
||||
|
||||
Count min_zero() const { return Count(0, max); }
|
||||
|
||||
size_t avg() const { return ((max - min) >> 1) + min; }
|
||||
|
||||
friend constexpr bool operator<(const Count &lhs, const Count &rhs) {
|
||||
return lhs.avg() < rhs.avg();
|
||||
}
|
||||
|
||||
friend constexpr bool operator==(const Count &lhs, const Count &rhs) {
|
||||
return lhs.avg() == rhs.avg();
|
||||
}
|
||||
|
||||
friend Count operator+(const Count &lhs, const Count &rhs) {
|
||||
return Count(num::saturating_add(lhs.min, rhs.min),
|
||||
num::saturating_add(lhs.max, rhs.max));
|
||||
}
|
||||
|
||||
size_t min;
|
||||
size_t max;
|
||||
};
|
@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
// Class which filters values T returned by I iterator if OP returns true for
|
||||
// them.
|
||||
// T - type of return value
|
||||
// I - iterator type
|
||||
// OP - type of filter function. OP: T& -> bool
|
||||
template <class T, class I, class OP>
|
||||
class Filter : public IteratorBase<T>, public Composable<T, Filter<T, I, OP>> {
|
||||
public:
|
||||
Filter() = delete;
|
||||
|
||||
// Filter operation is designed to be used in chained calls which operate on
|
||||
// a
|
||||
// iterator. Filter will in that usecase receive other iterator by value and
|
||||
// std::move is a optimization for it.
|
||||
Filter(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
|
||||
|
||||
// Return values for which filter return true.
|
||||
Option<T> next() final {
|
||||
auto item = Option<T>();
|
||||
do {
|
||||
item = iter.next();
|
||||
if (!item.is_present()) {
|
||||
return Option<T>();
|
||||
}
|
||||
} while (!op(item.get()));
|
||||
|
||||
return std::move(item);
|
||||
}
|
||||
|
||||
Count count() final { return iter.count().min_zero(); }
|
||||
|
||||
private:
|
||||
I iter;
|
||||
OP op;
|
||||
};
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_filter(I &&iter, OP &&op) {
|
||||
// Compiler cant deduce type T. decltype is here to help with it.
|
||||
return Filter<decltype(iter.next().take()), I, OP>(std::move(iter),
|
||||
std::move(op));
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
// Class which maps values returned by I iterator into iterators of type J
|
||||
// ,which
|
||||
// return value of type T, with function OP.
|
||||
// function.
|
||||
// T - type of return value
|
||||
// I - iterator type
|
||||
// J - iterator type returned from OP
|
||||
// OP - type of mapper function
|
||||
// TODO: Split into flat operation and map operation.
|
||||
template <class T, class I, class J, class OP>
|
||||
class FlatMap : public IteratorBase<T>,
|
||||
public Composable<T, FlatMap<T, I, J, OP>> {
|
||||
public:
|
||||
FlatMap() = delete;
|
||||
|
||||
// FlatMap operation is designed to be used in chained calls which operate
|
||||
// on a
|
||||
// iterator. FlatMap will in that usecase receive other iterator by value
|
||||
// and
|
||||
// std::move is a optimization for it.
|
||||
FlatMap(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
|
||||
|
||||
FlatMap(FlatMap &&m)
|
||||
: iter(std::move(m.iter)),
|
||||
op(std::move(m.op)),
|
||||
sub_iter(std::move(m.sub_iter)) {}
|
||||
|
||||
~FlatMap() final {}
|
||||
|
||||
Option<T> next() final {
|
||||
do {
|
||||
if (!sub_iter.is_present()) {
|
||||
auto item = iter.next();
|
||||
if (item.is_present()) {
|
||||
sub_iter = Option<J>(op(item.take()));
|
||||
} else {
|
||||
return Option<T>();
|
||||
}
|
||||
}
|
||||
|
||||
auto item = sub_iter.get().next();
|
||||
if (item.is_present()) {
|
||||
return std::move(item);
|
||||
} else {
|
||||
sub_iter.take();
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
Count count() final {
|
||||
// TODO: Correct count, are at least correcter
|
||||
return iter.count();
|
||||
}
|
||||
|
||||
private:
|
||||
I iter;
|
||||
Option<J> sub_iter;
|
||||
OP op;
|
||||
};
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_flat_map(I &&iter, OP &&op) {
|
||||
// Compiler cant deduce type T and J. decltype is here to help with it.
|
||||
return FlatMap<decltype(op(iter.next().take()).next().take()), I,
|
||||
decltype(op(iter.next().take())), OP>(std::move(iter),
|
||||
std::move(op));
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace iter {
|
||||
template <class I, class C>
|
||||
void for_all(I &&iter, C &&consumer) {
|
||||
auto e = iter.next();
|
||||
while (e.is_present()) {
|
||||
consumer(e.take());
|
||||
e = iter.next();
|
||||
}
|
||||
}
|
||||
|
||||
template <class I, class C>
|
||||
void for_all(std::unique_ptr<I> &&iter, C &&consumer) {
|
||||
auto e = iter->next();
|
||||
while (e.is_present()) {
|
||||
consumer(e.take());
|
||||
e = iter->next();
|
||||
}
|
||||
}
|
||||
|
||||
template <class I, class C>
|
||||
void find(I iter, C &&consumer) {
|
||||
auto e = iter.next();
|
||||
while (e.is_present()) {
|
||||
if (consumer(e.take())) {
|
||||
return;
|
||||
}
|
||||
e = iter.next();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
// Class which inspects values returned by I iterator
|
||||
// before passing them as a result.
|
||||
// function.
|
||||
// T - type of return value
|
||||
// I - iterator type
|
||||
// OP - type of inspector function. OP: T&->void
|
||||
template <class T, class I, class OP>
|
||||
class Inspect : public IteratorBase<T>,
|
||||
public Composable<T, Inspect<T, I, OP>> {
|
||||
public:
|
||||
Inspect() = delete;
|
||||
|
||||
// Inspect operation is designed to be used
|
||||
// in chained calls which operate on an
|
||||
// iterator. Inspect will in that usecase
|
||||
// receive other iterator by value and
|
||||
// std::move is a optimization for it.
|
||||
Inspect(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
|
||||
|
||||
Inspect(Inspect &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {}
|
||||
|
||||
~Inspect() final {}
|
||||
|
||||
Option<T> next() final {
|
||||
auto item = iter.next();
|
||||
if (item.is_present()) {
|
||||
op(item.get());
|
||||
return std::move(item);
|
||||
} else {
|
||||
return Option<T>();
|
||||
}
|
||||
}
|
||||
|
||||
Count count() final { return iter.count(); }
|
||||
|
||||
private:
|
||||
I iter;
|
||||
OP op;
|
||||
};
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_inspect(I &&iter, OP &&op) {
|
||||
// Compiler cant deduce type T. decltype is here to help with it.
|
||||
return Inspect<decltype(iter.next().take()), I, OP>(std::move(iter),
|
||||
std::move(op));
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/accessor.hpp"
|
||||
#include "utils/iterator/combined.hpp"
|
||||
#include "utils/iterator/count.hpp"
|
||||
#include "utils/iterator/filter.hpp"
|
||||
#include "utils/iterator/flat_map.hpp"
|
||||
#include "utils/iterator/for_all.hpp"
|
||||
#include "utils/iterator/inspect.hpp"
|
||||
#include "utils/iterator/iterator_accessor.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
#include "utils/iterator/lambda_iterator.hpp"
|
||||
#include "utils/iterator/limited_map.hpp"
|
||||
#include "utils/iterator/map.hpp"
|
||||
#include "utils/iterator/range_iterator.hpp"
|
||||
#include "utils/iterator/virtual_iter.hpp"
|
@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
// Class which turns accessor int next() based iterator.
|
||||
// T - type of return value
|
||||
// I - iterator type gotten from accessor
|
||||
// A - accessor type
|
||||
template <class T, class I, class A>
|
||||
class IteratorAccessor : public IteratorBase<T>,
|
||||
public Composable<T, IteratorAccessor<T, I, A>> {
|
||||
public:
|
||||
IteratorAccessor() = delete;
|
||||
|
||||
IteratorAccessor(A &&acc)
|
||||
: begin(std::move(acc.begin())), acc(std::forward<A>(acc)), returned(0) {}
|
||||
|
||||
IteratorAccessor(IteratorAccessor &&other)
|
||||
: begin(std::move(other.begin)),
|
||||
acc(std::forward<A>(other.acc)),
|
||||
returned(other.returned) {}
|
||||
|
||||
~IteratorAccessor() final {}
|
||||
|
||||
// Iter(const Iter &other) = delete;
|
||||
// Iter(Iter &&other) :
|
||||
// begin(std::move(other.begin)),end(std::move(other.end)) {};
|
||||
|
||||
Option<T> next() final {
|
||||
if (begin != acc.end()) {
|
||||
auto ret = Option<T>(&(*(begin.operator->())));
|
||||
begin++;
|
||||
returned++;
|
||||
return ret;
|
||||
} else {
|
||||
return Option<T>();
|
||||
}
|
||||
}
|
||||
|
||||
Count count() final {
|
||||
auto size = acc.size();
|
||||
if (size > returned) {
|
||||
return Count(0);
|
||||
} else {
|
||||
return Count(size - returned);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
I begin;
|
||||
A acc;
|
||||
size_t returned;
|
||||
};
|
||||
|
||||
// TODO: Join to make functions into one
|
||||
template <class A>
|
||||
auto make_iter(A &&acc) {
|
||||
// Compiler cant deduce types T and I. decltype are here to help with it.
|
||||
return IteratorAccessor<decltype(&(*(acc.begin().operator->()))),
|
||||
decltype(acc.begin()), A>(std::move(acc));
|
||||
}
|
||||
|
||||
template <class A>
|
||||
auto make_iter_ref(A &acc) {
|
||||
// Compiler cant deduce types T and I. decltype are here to help with it.
|
||||
return IteratorAccessor<decltype(&(*(acc.begin().operator->()))),
|
||||
decltype(acc.begin()), A &>(acc);
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/count.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
// Base iterator for next() kind iterator.
|
||||
// T - type of return value
|
||||
template <class T>
|
||||
class IteratorBase {
|
||||
public:
|
||||
virtual ~IteratorBase(){};
|
||||
|
||||
virtual Option<T> next() = 0;
|
||||
|
||||
virtual Count count() = 0;
|
||||
};
|
@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter {
|
||||
// Wraps lambda into interator with next().
|
||||
// T - type of return value
|
||||
// F - type of wraped lambda
|
||||
template <class T, class F>
|
||||
class LambdaIterator : public IteratorBase<T>,
|
||||
public Composable<T, LambdaIterator<T, F>> {
|
||||
public:
|
||||
LambdaIterator(F &&f, size_t count) : func(std::move(f)), _count(count) {}
|
||||
|
||||
LambdaIterator(LambdaIterator &&other)
|
||||
: func(std::move(other.func)), _count(other._count) {}
|
||||
|
||||
~LambdaIterator() final {}
|
||||
|
||||
Option<T> next() final {
|
||||
_count = _count > 0 ? _count - 1 : 0;
|
||||
return func();
|
||||
}
|
||||
|
||||
Count count() final { return Count(_count); }
|
||||
|
||||
private:
|
||||
F func;
|
||||
size_t _count;
|
||||
};
|
||||
|
||||
// Wraps lambda which returns options as an iterator.
|
||||
template <class F>
|
||||
auto make_iterator(F &&f) {
|
||||
return make_iterator<F>(std::move(f), ~((size_t)0));
|
||||
}
|
||||
|
||||
// Wraps lambda which returns options as an iterator.
|
||||
template <class F>
|
||||
auto make_iterator(F &&f, size_t count) {
|
||||
// Because function isn't receving or in any way using type T from
|
||||
// FunctionIterator compiler can't deduce it thats way there is decltype in
|
||||
// construction of FunctionIterator. Resoulting type of iter.next().take()
|
||||
// is T.
|
||||
return LambdaIterator<decltype(f().take()), F>(std::move(f), count);
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
// Class which maps values returned by I iterator into value of type T with OP
|
||||
// function and ends when op returns empty optional.
|
||||
// T - type of return value
|
||||
// I - iterator type
|
||||
// OP - type of mapper function. OP: V -> Option<T>
|
||||
template <class T, class I, class OP>
|
||||
class LimitedMap : public IteratorBase<T>,
|
||||
public Composable<T, LimitedMap<T, I, OP>> {
|
||||
public:
|
||||
LimitedMap() = delete;
|
||||
|
||||
// LimitedMap operation is designed to be used in chained calls which
|
||||
// operate on a
|
||||
// iterator. LimitedMap will in that usecase receive other iterator by value
|
||||
// and
|
||||
// std::move is a optimization for it.
|
||||
LimitedMap(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
|
||||
|
||||
LimitedMap(LimitedMap &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {}
|
||||
|
||||
~LimitedMap() final {}
|
||||
|
||||
Option<T> next() final {
|
||||
auto item = iter.next();
|
||||
if (item.is_present()) {
|
||||
return op(item.take());
|
||||
} else {
|
||||
return Option<T>();
|
||||
}
|
||||
}
|
||||
|
||||
Count count() final { return iter.count(); }
|
||||
|
||||
private:
|
||||
I iter;
|
||||
OP op;
|
||||
};
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_limited_map(I &&iter, OP &&op) {
|
||||
// Compiler cant deduce type T. decltype is here to help with it.
|
||||
return LimitedMap<decltype(op(iter.next().take()).take()), I, OP>(
|
||||
std::move(iter), std::move(op));
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
// Class which maps values returned by I iterator into value of type T with OP
|
||||
// function.
|
||||
// T - type of return value
|
||||
// I - iterator type
|
||||
// OP - type of mapper function
|
||||
template <class T, class I, class OP>
|
||||
class Map : public IteratorBase<T>, public Composable<T, Map<T, I, OP>> {
|
||||
public:
|
||||
Map() = delete;
|
||||
|
||||
// Map operation is designed to be used in chained calls which operate on a
|
||||
// iterator. Map will in that usecase receive other iterator by value and
|
||||
// std::move is a optimization for it.
|
||||
Map(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
|
||||
|
||||
Map(Map &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {}
|
||||
|
||||
~Map() final {}
|
||||
|
||||
Option<T> next() final {
|
||||
auto item = iter.next();
|
||||
if (item.is_present()) {
|
||||
return Option<T>(op(item.take()));
|
||||
} else {
|
||||
return Option<T>();
|
||||
}
|
||||
}
|
||||
|
||||
Count count() final { return iter.count(); }
|
||||
|
||||
private:
|
||||
I iter;
|
||||
OP op;
|
||||
};
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_map(I &&iter, OP &&op) {
|
||||
// Compiler cant deduce type T. decltype is here to help with it.
|
||||
return Map<decltype(op(iter.next().take())), I, OP>(std::move(iter),
|
||||
std::move(op));
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "storage/vertex_accessor.hpp"
|
||||
#include "utils/iterator/iterator.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace query_help {
|
||||
|
||||
template <class A>
|
||||
bool fill(A &a) {
|
||||
return a.fill();
|
||||
}
|
||||
};
|
||||
|
||||
// Base iterator for next() kind iterator.
|
||||
// Vertex::Accessor - type of return value
|
||||
template <>
|
||||
class IteratorBase<Vertex::Accessor> {
|
||||
public:
|
||||
virtual Option<Vertex::Accessor> next() = 0;
|
||||
|
||||
auto fill() { return iter::make_filter(std::move(*this), query_help::fill); }
|
||||
};
|
@ -1,63 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/assert.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
// Class which wraps iterator with next() into C++ iterator.
|
||||
// T - type of return value
|
||||
// I - iterator type
|
||||
template <class T, class I>
|
||||
class RangeIterator {
|
||||
public:
|
||||
RangeIterator() : iter(Option<I>()), value(Option<T>()){};
|
||||
|
||||
RangeIterator(I &&iter)
|
||||
: value(iter.next()), iter(Option<I>(std::move(iter))) {}
|
||||
|
||||
T &operator*() {
|
||||
debug_assert(value.is_present(), "No value.");
|
||||
return value.get();
|
||||
}
|
||||
|
||||
T *operator->() {
|
||||
debug_assert(value.is_present(), "No value.");
|
||||
return &value.get();
|
||||
}
|
||||
|
||||
operator T &() {
|
||||
debug_assert(value.is_present(), "No value.");
|
||||
return value.get();
|
||||
}
|
||||
|
||||
RangeIterator &operator++() {
|
||||
debug_assert(iter.is_present(), "No value.");
|
||||
value = iter.get().next();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
RangeIterator &operator++(int) { return operator++(); }
|
||||
|
||||
friend bool operator==(const RangeIterator &a, const RangeIterator &b) {
|
||||
return a.value.is_present() == b.value.is_present();
|
||||
}
|
||||
|
||||
friend bool operator!=(const RangeIterator &a, const RangeIterator &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
private:
|
||||
Option<I> iter;
|
||||
Option<T> value;
|
||||
};
|
||||
|
||||
template <class I>
|
||||
auto make_range_iterator(I &&iter) {
|
||||
// Because this function isn't receving or in any way using type T from
|
||||
// RangeIterator, compiler can't deduce it. That is the reason why
|
||||
// there is decltype in construction of RangeIterator.
|
||||
// declytype(iter.next().take()) is T.
|
||||
return RangeIterator<decltype(iter.next().take()), I>(std::move(iter));
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter {
|
||||
|
||||
// Class which wraps iterator and hides it's type. It actualy does this by
|
||||
// dynamicly allocating iterator on heap.
|
||||
// T - type of return value
|
||||
template <class T>
|
||||
class Virtual : public Composable<T, Virtual<T>> {
|
||||
public:
|
||||
Virtual() = delete;
|
||||
|
||||
// Virtual operation is designed to be used in chained calls which operate
|
||||
// on a
|
||||
// iterator. Virtual will in that usecase receive other iterator by value
|
||||
// and
|
||||
// std::move is a optimization for it.
|
||||
|
||||
template <class I>
|
||||
Virtual(I &&iter) : it(std::make_unique<I>(std::move(iter))) {}
|
||||
|
||||
Virtual(Virtual &&m) : it(std::move(m.it)) {}
|
||||
|
||||
~Virtual() {}
|
||||
|
||||
Option<T> next() { return it.get()->next(); }
|
||||
|
||||
Count count() { return it.get()->count(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<IteratorBase<T>> it;
|
||||
};
|
||||
|
||||
template <class I>
|
||||
auto make_virtual(I &&iter) {
|
||||
// Compiler can't deduce type T. decltype is here to help with it.
|
||||
return Virtual<decltype(iter.next().take())>(std::move(iter));
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// ** Books **
|
||||
// http://instructor.sdu.edu.kz/~konst/sysprog2015fall/readings/linux%20system%20programming/The%20Linux%20Programming%20Interface-Michael%20Kerrisk.pdf
|
||||
|
||||
// ** Documentation **
|
||||
// http://man7.org/linux/man-pages/man2/read.2.html
|
||||
// http://man7.org/linux/man-pages/man2/select.2.html
|
||||
// http://man7.org/linux/man-pages/man2/fcntl.2.html
|
||||
|
||||
// ** Community **
|
||||
// http://stackoverflow.com/questions/5616092/non-blocking-call-for-reading-descriptor
|
||||
// http://stackoverflow.com/questions/2917881/how-to-implement-a-timeout-in-read-function-call
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "utils/exceptions/not_yet_implemented.hpp"
|
||||
#include "utils/exceptions/stacktrace_exception.hpp"
|
||||
#include "utils/likely.hpp"
|
||||
|
||||
namespace linux_os {
|
||||
class LinuxException : public StacktraceException {
|
||||
using StacktraceException::StacktraceException;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets non blocking flag to a file descriptor.
|
||||
*/
|
||||
void set_non_blocking(int fd) {
|
||||
auto flags = fcntl(fd, F_GETFL, 0);
|
||||
|
||||
if (UNLIKELY(flags == -1))
|
||||
throw LinuxException("Cannot read flags from file descriptor.");
|
||||
|
||||
flags |= O_NONBLOCK;
|
||||
|
||||
auto status = fcntl(fd, F_SETFL, flags);
|
||||
|
||||
if (UNLIKELY(status == -1))
|
||||
throw LinuxException("Can't set NON_BLOCK flag to file descriptor");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file descriptor with timeout.
|
||||
*/
|
||||
void tread() { throw NotYetImplemented(); }
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
template <class T>
|
||||
struct MarkRef {
|
||||
MarkRef() = default;
|
||||
MarkRef(MarkRef&) = default;
|
||||
MarkRef(MarkRef&&) = default;
|
||||
|
||||
bool is_marked() const { return ptr & 0x1L; }
|
||||
|
||||
bool set_mark() { return ptr |= 0x1L; }
|
||||
|
||||
bool clear_mark() { return ptr &= ~0x1L; }
|
||||
|
||||
T* get() const { return reinterpret_cast<T*>(ptr & ~0x1L); }
|
||||
|
||||
T& operator*() { return *get(); }
|
||||
T* operator->() { return get(); }
|
||||
|
||||
operator T*() { return get(); }
|
||||
|
||||
uintptr_t ptr;
|
||||
};
|
@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Defines ordering of data
|
||||
enum Order : uint8_t {
|
||||
None = 0,
|
||||
Ascending = 1,
|
||||
Descending = 2,
|
||||
};
|
@ -1,21 +0,0 @@
|
||||
//
|
||||
// Copyright 2017 Memgraph
|
||||
// Created by Marko Budiselic
|
||||
//
|
||||
// SOURCES:
|
||||
// http://arne-mertz.de/2016/10/passkey-idiom/
|
||||
// http://stackoverflow.com/questions/3217390/clean-c-granular-friend-equivalent-answer-attorney-client-idiom
|
||||
|
||||
#pragma once
|
||||
|
||||
template <typename T>
|
||||
class PassKey {
|
||||
friend T;
|
||||
|
||||
private:
|
||||
// default constructor has to be manually defined otherwise = default
|
||||
// would allow aggregate initialization to bypass default constructor
|
||||
// both, default and copy constructors have to be user-defined
|
||||
// otherwise are public by default
|
||||
PassKey() {}
|
||||
};
|
@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
// ReferenceWrapper was created because std::reference_wrapper
|
||||
// wasn't copyable
|
||||
// Implementation has been taken from:
|
||||
// http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper
|
||||
// TODO: once the c++ implementation will have proper implementation
|
||||
// this class should be deleted and replaced with std::reference_wrapper
|
||||
|
||||
template <class T>
|
||||
class ReferenceWrapper {
|
||||
public:
|
||||
// types
|
||||
typedef T type;
|
||||
|
||||
// construct/copy/destroy
|
||||
ReferenceWrapper(T &ref) noexcept : _ptr(std::addressof(ref)) {}
|
||||
ReferenceWrapper(T &&) = delete;
|
||||
ReferenceWrapper(const ReferenceWrapper &) noexcept = default;
|
||||
|
||||
// assignment
|
||||
ReferenceWrapper &operator=(const ReferenceWrapper &x) noexcept = default;
|
||||
|
||||
// access
|
||||
operator T &() const noexcept { return *_ptr; }
|
||||
T &get() const noexcept { return *_ptr; }
|
||||
|
||||
// template <class... ArgTypes>
|
||||
// typename std::result_of<T &(ArgTypes &&...)>::type
|
||||
// operator()(ArgTypes &&... args) const
|
||||
// {
|
||||
// return std::invoke(get(), std::forward<ArgTypes>(args)...);
|
||||
// }
|
||||
|
||||
private:
|
||||
T *_ptr;
|
||||
};
|
@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Wraps stream with convinient methods which need only one method:
|
||||
// write (const char* s, n);
|
||||
template <class STREAM>
|
||||
class StreamWrapper {
|
||||
public:
|
||||
StreamWrapper() = delete;
|
||||
StreamWrapper(STREAM &s) : stream(s) {}
|
||||
|
||||
void write(const unsigned char value) {
|
||||
stream.write(reinterpret_cast<const char *>(&value), 1);
|
||||
}
|
||||
|
||||
void write(const unsigned char *value, size_t n) {
|
||||
stream.write(reinterpret_cast<const char *>(value), n);
|
||||
}
|
||||
|
||||
private:
|
||||
STREAM &stream;
|
||||
};
|
@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace utils {
|
||||
|
||||
class StringBuffer {
|
||||
public:
|
||||
StringBuffer() = default;
|
||||
~StringBuffer() = default;
|
||||
|
||||
StringBuffer(const StringBuffer &) = delete;
|
||||
StringBuffer(StringBuffer &&) = default;
|
||||
|
||||
StringBuffer &operator=(const StringBuffer &) = delete;
|
||||
StringBuffer &operator=(StringBuffer &&) = default;
|
||||
|
||||
StringBuffer(std::string::size_type count) { resize(count); }
|
||||
|
||||
void resize(std::string::size_type count) { data.resize(count); }
|
||||
|
||||
StringBuffer &operator<<(const std::string &str) {
|
||||
data += str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuffer &operator<<(const char *str) {
|
||||
data += str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuffer &operator<<(char c) {
|
||||
data += c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string &str() { return data; }
|
||||
|
||||
private:
|
||||
std::string data;
|
||||
};
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <errno.h>
|
||||
#include <linux/futex.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace sys {
|
||||
// Code from stackoverflow:
|
||||
// http://stackoverflow.com/questions/676787/how-to-do-fsync-on-an-ofstream
|
||||
// Extracts FILE* from streams in std.
|
||||
inline int GetFileDescriptor(std::filebuf &filebuf) {
|
||||
class my_filebuf : public std::filebuf {
|
||||
public:
|
||||
int handle() { return _M_file.fd(); }
|
||||
};
|
||||
|
||||
return static_cast<my_filebuf &>(filebuf).handle();
|
||||
}
|
||||
|
||||
inline int futex(void *addr1, int op, int val1, const struct timespec *timeout,
|
||||
void *addr2, int val3) {
|
||||
return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
|
||||
};
|
||||
|
||||
// Ensures that everything written to file will be writen on disk when the
|
||||
// function call returns. !=0 if error occured
|
||||
template <class STREAM>
|
||||
inline size_t flush_file_to_disk(STREAM &file) {
|
||||
file.flush();
|
||||
if (fsync(GetFileDescriptor(*file.rdbuf())) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return errno;
|
||||
};
|
||||
|
||||
// True if succesffull
|
||||
inline bool ensure_directory_exists(std::string const &path) {
|
||||
struct stat st = {0};
|
||||
|
||||
if (stat(path.c_str(), &st) == -1) {
|
||||
return mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
@ -11,19 +11,54 @@
|
||||
*/
|
||||
template <typename TLhs, typename TRhs = TLhs, typename TReturn = bool>
|
||||
struct TotalOrdering {
|
||||
friend constexpr TReturn operator!=(const TLhs &a, const TRhs &b) {
|
||||
friend constexpr TReturn operator!=(const TLhs& a, const TRhs& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend constexpr TReturn operator<=(const TLhs &a, const TRhs &b) {
|
||||
friend constexpr TReturn operator<=(const TLhs& a, const TRhs& b) {
|
||||
return a < b || a == b;
|
||||
}
|
||||
|
||||
friend constexpr TReturn operator>(const TLhs &a, const TRhs &b) {
|
||||
friend constexpr TReturn operator>(const TLhs& a, const TRhs& b) {
|
||||
return !(a <= b);
|
||||
}
|
||||
|
||||
friend constexpr TReturn operator>=(const TLhs &a, const TRhs &b) {
|
||||
friend constexpr TReturn operator>=(const TLhs& a, const TRhs& b) {
|
||||
return !(a < b);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Derived, class T>
|
||||
struct TotalOrderingWith {
|
||||
friend constexpr bool operator!=(const Derived& a, const T& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator<=(const Derived& a, const T& b) {
|
||||
return a < b || a == b;
|
||||
}
|
||||
|
||||
friend constexpr bool operator>(const Derived& a, const T& b) {
|
||||
return !(a <= b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator>=(const Derived& a, const T& b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator!=(const T& a, const Derived& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator<=(const T& a, const Derived& b) {
|
||||
return a < b || a == b;
|
||||
}
|
||||
|
||||
friend constexpr bool operator>(const T& a, const Derived& b) {
|
||||
return !(a <= b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator>=(const T& a, const Derived& b) {
|
||||
return !(a < b);
|
||||
}
|
||||
};
|
||||
|
@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
template <class Derived, class T>
|
||||
struct TotalOrderingWith {
|
||||
friend constexpr bool operator!=(const Derived& a, const T& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator<=(const Derived& a, const T& b) {
|
||||
return a < b || a == b;
|
||||
}
|
||||
|
||||
friend constexpr bool operator>(const Derived& a, const T& b) {
|
||||
return !(a <= b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator>=(const Derived& a, const T& b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator!=(const T& a, const Derived& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator<=(const T& a, const Derived& b) {
|
||||
return a < b || a == b;
|
||||
}
|
||||
|
||||
friend constexpr bool operator>(const T& a, const Derived& b) {
|
||||
return !(a <= b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator>=(const T& a, const Derived& b) {
|
||||
return !(a < b);
|
||||
}
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/total_ordering.hpp"
|
||||
|
||||
// Type which represents nothing.
|
||||
class Void : public TotalOrdering<Void> {
|
||||
public:
|
||||
friend bool operator<(const Void &lhs, const Void &rhs) { return false; }
|
||||
|
||||
friend bool operator==(const Void &lhs, const Void &rhs) { return true; }
|
||||
};
|
||||
|
||||
static Void _void = {};
|
Loading…
Reference in New Issue
Block a user