feat: simple pipeline
This commit is contained in:
parent
0509c62bf1
commit
4d37acdda7
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.20...4.0)
|
||||
project(
|
||||
pipeline_asio
|
||||
pipe
|
||||
VERSION 0.1.0
|
||||
LANGUAGES CXX)
|
||||
|
||||
@ -9,5 +9,11 @@ find_package(fmt REQUIRED)
|
||||
add_subdirectory(external/pipeline)
|
||||
add_subdirectory(external/pipes)
|
||||
|
||||
# Specify the include directories include_directories(include)
|
||||
|
||||
add_library(pipe INTERFACE)
|
||||
target_compile_features(pipe INTERFACE cxx_std_23)
|
||||
target_include_directories(pipe INTERFACE include)
|
||||
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
|
||||
72
include/freepipe/freepipe.hpp
Normal file
72
include/freepipe/freepipe.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright 2025, Luís Murta
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <any>
|
||||
#include <concepts>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace freepipe {
|
||||
|
||||
template <typename... Args> struct Task {
|
||||
explicit constexpr Task(Args &&...args)
|
||||
requires(sizeof...(Args) > 0)
|
||||
: args_(std::forward<Args>(args)...) {}
|
||||
|
||||
explicit constexpr Task()
|
||||
requires(sizeof...(Args) == 0)
|
||||
{}
|
||||
|
||||
constexpr auto const &operator*() const & { return args_; }
|
||||
constexpr auto &operator*() & { return args_; }
|
||||
constexpr auto &&operator*() && { return std::move(args_); }
|
||||
constexpr auto const &&operator*() const && { return std::move(args_); }
|
||||
|
||||
private:
|
||||
std::tuple<Args...> args_;
|
||||
};
|
||||
|
||||
template <typename... Args, std::regular_invocable<Args...> F>
|
||||
constexpr auto operator|(Task<Args...> const &task, F &&func) {
|
||||
using R = std::invoke_result_t<F, Args...>;
|
||||
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
std::apply(std::forward<F>(func), *task);
|
||||
return Task<>{};
|
||||
} else {
|
||||
return Task<R>{std::apply(std::forward<F>(func), *task)};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args, std::regular_invocable<Args...> F>
|
||||
constexpr auto operator|(Task<Args...> &&task, F &&func) {
|
||||
using R = std::invoke_result_t<F, Args...>;
|
||||
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
std::apply(std::forward<F>(func), *std::move(task));
|
||||
return Task<>{};
|
||||
} else {
|
||||
return Task<R>{std::apply(std::forward<F>(func), *std::move(task))};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args, typename CharT, typename Traits = std::char_traits<CharT>>
|
||||
constexpr auto operator|(Task<Args...> const &task, std::basic_ostream<CharT, Traits> &os) {
|
||||
std::apply([&os](auto &&...args) { ((os << args << '\n'), ...); }, *task);
|
||||
return Task<>{};
|
||||
}
|
||||
|
||||
template <typename... Args, typename CharT, typename Traits = std::char_traits<CharT>>
|
||||
constexpr auto operator|(Task<Args...> &&task, std::basic_ostream<CharT, Traits> &os) {
|
||||
std::apply([&os](auto &&...args) { ((os << args << '\n'), ...); }, *std::move(task));
|
||||
return Task<>{};
|
||||
}
|
||||
|
||||
class Pipe : public Task<> {};
|
||||
|
||||
} // namespace freepipe
|
||||
@ -5,3 +5,8 @@ target_compile_features(pipeline.test PUBLIC cxx_std_23)
|
||||
target_link_libraries(pipeline.test benchmark::benchmark_main
|
||||
pipeline::pipeline joboccara::pipes)
|
||||
add_test(NAME pipeline.test COMMAND pipeline.test)
|
||||
|
||||
find_package(GTest REQUIRED)
|
||||
add_executable(pipe.test pipe.test.cpp)
|
||||
target_compile_features(pipe.test PUBLIC cxx_std_23)
|
||||
target_link_libraries(pipe.test GTest::gtest_main pipe)
|
||||
|
||||
25
tests/pipe.test.cpp
Normal file
25
tests/pipe.test.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include <freepipe/freepipe.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace freepipe {
|
||||
|
||||
TEST(PipeTest, Single) {
|
||||
Pipe p;
|
||||
|
||||
auto r = p | [] { return 42; } |
|
||||
[](auto result) {
|
||||
EXPECT_EQ(result, 42);
|
||||
return result;
|
||||
} |
|
||||
std::cout |
|
||||
[] {
|
||||
SUCCEED();
|
||||
return 0;
|
||||
} |
|
||||
[](auto result) { EXPECT_EQ(result, 0); } | [] { return 0; };
|
||||
|
||||
EXPECT_EQ(*r, std::tuple{0});
|
||||
}
|
||||
|
||||
} // namespace freepipe
|
||||
Loading…
x
Reference in New Issue
Block a user