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(
|
project(
|
||||||
pipeline_asio
|
pipe
|
||||||
VERSION 0.1.0
|
VERSION 0.1.0
|
||||||
LANGUAGES CXX)
|
LANGUAGES CXX)
|
||||||
|
|
||||||
@ -9,5 +9,11 @@ find_package(fmt REQUIRED)
|
|||||||
add_subdirectory(external/pipeline)
|
add_subdirectory(external/pipeline)
|
||||||
add_subdirectory(external/pipes)
|
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()
|
enable_testing()
|
||||||
add_subdirectory(tests)
|
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
|
target_link_libraries(pipeline.test benchmark::benchmark_main
|
||||||
pipeline::pipeline joboccara::pipes)
|
pipeline::pipeline joboccara::pipes)
|
||||||
add_test(NAME pipeline.test COMMAND pipeline.test)
|
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