-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: turuslan <[email protected]>
- Loading branch information
Showing
65 changed files
with
3,340 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
```bash | ||
brew install nasm # vcpkg liblsquic | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <boost/asio/buffer.hpp> | ||
#include <qtils/bytes.hpp> | ||
|
||
namespace qtils { | ||
inline boost::asio::const_buffer asioBuffer(BytesIn s) { | ||
return {s.data(), s.size()}; | ||
} | ||
|
||
boost::asio::mutable_buffer asioBuffer(auto &&t) | ||
requires(requires { BytesOut{t}; }) | ||
{ | ||
BytesOut s{t}; | ||
return {s.data(), s.size()}; | ||
} | ||
|
||
inline BytesIn asioBuffer(const boost::asio::const_buffer &s) { | ||
// NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) | ||
return {reinterpret_cast<const uint8_t *>(s.data()), s.size()}; | ||
} | ||
|
||
inline BytesOut asioBuffer(const boost::asio::mutable_buffer &s) { | ||
// NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) | ||
return {reinterpret_cast<uint8_t *>(s.data()), s.size()}; | ||
} | ||
} // namespace qtils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <optional> | ||
#include <qtils/bytes.hpp> | ||
#include <stdexcept> | ||
|
||
namespace qtils { | ||
inline bool fromSpan(BytesOut out, BytesIn span) { | ||
if (span.size() != out.size()) { | ||
return false; | ||
} | ||
memcpy(out.data(), span.data(), out.size()); | ||
return true; | ||
} | ||
|
||
template <typename T> | ||
std::optional<T> fromSpan(BytesIn span) { | ||
T out; | ||
if (not fromSpan(out, span)) { | ||
return std::nullopt; | ||
} | ||
return out; | ||
} | ||
} // namespace qtils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <utility> | ||
|
||
#define FORWARD(x) std::forward<decltype(x)>(x) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <memory> | ||
|
||
#define MAKE_SHARED_(x_, ...) \ | ||
x_ { \ | ||
std::make_shared<decltype(x_)::element_type>(__VA_ARGS__) \ | ||
} | ||
|
||
#define MAKE_SHARED_T(T, ...) std::make_shared<T::element_type>(__VA_ARGS__) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <utility> | ||
|
||
#define MOVE(x) \ | ||
x { \ | ||
std::move(x) \ | ||
} | ||
|
||
#define MOVE_(x) \ | ||
x##_ { \ | ||
std::move(x) \ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <memory> | ||
|
||
#define WEAK_SELF \ | ||
weak_self { \ | ||
weak_from_this() \ | ||
} | ||
|
||
#define WEAK_LOCK(name) \ | ||
auto name = weak_##name.lock(); \ | ||
if (not name) return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <map> | ||
#include <stdexcept> | ||
#include <unordered_map> | ||
#include <variant> | ||
|
||
namespace qtils { | ||
template <typename M> | ||
struct MapEntry { | ||
using I = typename M::iterator; | ||
using K = typename M::key_type; | ||
|
||
MapEntry(M &map, const K &key) : map{map} { | ||
if (auto it = map.find(key); it != map.end()) { | ||
it_or_key = it; | ||
} else { | ||
it_or_key = key; | ||
} | ||
} | ||
|
||
bool has() const { | ||
return std::holds_alternative<I>(it_or_key); | ||
} | ||
operator bool() const { | ||
return has(); | ||
} | ||
auto &operator*() { | ||
if (not has()) { | ||
throw std::logic_error{"MapEntry::operator*"}; | ||
} | ||
return std::get<I>(it_or_key)->second; | ||
} | ||
auto *operator->() { | ||
if (not has()) { | ||
throw std::logic_error{"MapEntry::operator->"}; | ||
} | ||
return &std::get<I>(it_or_key)->second; | ||
} | ||
void insert(M::mapped_type value) { | ||
if (has()) { | ||
throw std::logic_error{"MapEntry::insert"}; | ||
} | ||
it_or_key = | ||
map.emplace(std::move(std::get<K>(it_or_key)), std::move(value)) | ||
.first; | ||
} | ||
void insert_or_assign(M::mapped_type value) { | ||
if (not has()) { | ||
insert(std::move(value)); | ||
} else { | ||
**this = std::move(value); | ||
} | ||
} | ||
M::mapped_type remove() { | ||
if (not has()) { | ||
throw std::logic_error{"MapEntry::remove"}; | ||
} | ||
auto node = map.extract(std::get<I>(it_or_key)); | ||
it_or_key = std::move(node.key()); | ||
return std::move(node.mapped()); | ||
} | ||
|
||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) | ||
M ↦ | ||
std::variant<I, K> it_or_key{}; | ||
}; | ||
|
||
template <typename K, typename V, typename L, typename A> | ||
auto entry(std::map<K, V, L, A> &map, const K &key) { | ||
return MapEntry<std::remove_cvref_t<decltype(map)>>{map, key}; | ||
} | ||
|
||
template <typename K, typename V, typename H, typename E, typename A> | ||
auto entry(std::unordered_map<K, V, H, E, A> &map, const K &key) { | ||
return MapEntry<std::remove_cvref_t<decltype(map)>>{map, key}; | ||
} | ||
} // namespace qtils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <utility> | ||
|
||
namespace qtils { | ||
template <typename T> | ||
size_t stdHashOf(const T &v) { | ||
return std::hash<T>()(v); | ||
} | ||
} // namespace qtils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,5 @@ | |
# All Rights Reserved | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
|
||
add_subdirectory(snp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <boost/asio/awaitable.hpp> | ||
#include <qtils/outcome.hpp> | ||
|
||
namespace jam { | ||
/** | ||
* Return type for coroutine. | ||
* | ||
* Does not resume when: | ||
* - called directly outside executor, returns coroutine. | ||
* - `coroSpawn` called when not running inside executor, | ||
* resumes on next executor tick. | ||
* int main() { | ||
* boost::asio::io_context io; | ||
* coroSpawn(io, []() -> Coro<void> { co_return; }); // suspended | ||
* io.run_one(); // resumes | ||
* // may complete before next statement | ||
* } | ||
* Resumes when: | ||
* - `coroSpawn` when running inside specified executor. | ||
* post(executor, [] { | ||
* coroSpawn(executor, []() -> Coro<void> { co_return; }) // resumes | ||
* // may complete before next statement | ||
* }) | ||
* co_await coroSpawn([]() -> Coro<void> { co_return; }) // resumes | ||
* // may complete before next statement | ||
* - `co_await` | ||
* co_await foo() // resumes | ||
* // may complete before next statement | ||
* After resuming may complete before specified statement ends. | ||
* | ||
* Use `CORO_YIELD` explicitly to suspend coroutine until next executor tick. | ||
*/ | ||
template <typename T> | ||
using Coro = boost::asio::awaitable<T>; | ||
|
||
/** | ||
* Return type for coroutine returning outcome. | ||
*/ | ||
template <typename T> | ||
using CoroOutcome = Coro<outcome::result<T>>; | ||
} // namespace jam |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/** | ||
* Copyright Quadrivium LLC | ||
* All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <TODO_qtils/macro/move.hpp> | ||
#include <deque> | ||
#include <jam/coro/handler.hpp> | ||
#include <jam/coro/set_thread.hpp> | ||
#include <stdexcept> | ||
#include <variant> | ||
|
||
namespace jam { | ||
template <typename T> | ||
class SharedFuture { | ||
public: | ||
using Self = std::shared_ptr<SharedFuture<T>>; | ||
|
||
SharedFuture(IoContextPtr io_context_ptr) : MOVE_(io_context_ptr) {} | ||
|
||
static Coro<bool> ready(Self self) { | ||
SET_CORO_THREAD(self->io_context_ptr_); | ||
co_return std::holds_alternative<T>(self->state_); | ||
} | ||
|
||
/** | ||
* Resumes coroutine immediately or inside `set`. | ||
*/ | ||
static Coro<T> get(Self self) { | ||
SET_CORO_THREAD(self->io_context_ptr_); | ||
if (auto *value = std::get_if<T>(&self->state_)) { | ||
co_return *value; | ||
} | ||
auto &handlers = std::get<Handlers>(self->state_); | ||
co_return co_await coroHandler<T>([&](CoroHandler<T> &&handler) { | ||
handlers.emplace_back(std::move(handler)); | ||
}); | ||
} | ||
|
||
/** | ||
* Set value and wake waiting coroutines. | ||
* Coroutines may complete before `set` returns. | ||
*/ | ||
static Coro<void> set(Self self, T value) { | ||
SET_CORO_THREAD(self->io_context_ptr_); | ||
if (std::holds_alternative<T>(self->state_)) { | ||
throw std::logic_error{"SharedFuture::set must be called once"}; | ||
} | ||
auto handlers = std::move(std::get<Handlers>(self->state_)); | ||
self->state_ = std::move(value); | ||
auto &state_value = std::get<T>(self->state_); | ||
for (auto &handler : handlers) { | ||
handler(state_value); | ||
} | ||
} | ||
|
||
private: | ||
using Handlers = std::deque<CoroHandler<T>>; | ||
|
||
IoContextPtr io_context_ptr_; | ||
std::variant<Handlers, T> state_; | ||
}; | ||
} // namespace jam |
Oops, something went wrong.