Compare commits
No commits in common. "bd8e17b2ab86726c3cbda214715fce490a531c79" and "abc78334d044c63bbc1f73e128e8abdfeefcef42" have entirely different histories.
bd8e17b2ab
...
abc78334d0
@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
BasedOnStyle: LLVM
|
|
||||||
ColumnLimit: 100
|
|
||||||
14
.clang-tidy
14
.clang-tidy
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
Checks:
|
|
||||||
- boost-*
|
|
||||||
- bugprone-*
|
|
||||||
- clang-analyzer-*
|
|
||||||
- concurrency-*
|
|
||||||
- cppcoreguidelines-*
|
|
||||||
- misc-*
|
|
||||||
- modernize-*
|
|
||||||
- performance-*
|
|
||||||
- portability-*
|
|
||||||
- readability-*
|
|
||||||
- -readability-identifier-length
|
|
||||||
FormatStyle: file
|
|
||||||
39
.gitignore
vendored
39
.gitignore
vendored
@ -1,39 +0,0 @@
|
|||||||
### C++ ###
|
|
||||||
# Prerequisites
|
|
||||||
*.d
|
|
||||||
|
|
||||||
# Compiled Object files
|
|
||||||
*.slo
|
|
||||||
*.lo
|
|
||||||
*.o
|
|
||||||
*.obj
|
|
||||||
|
|
||||||
# Precompiled Headers
|
|
||||||
*.gch
|
|
||||||
*.pch
|
|
||||||
|
|
||||||
# Compiled Dynamic libraries
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
*.dll
|
|
||||||
|
|
||||||
# Fortran module files
|
|
||||||
*.mod
|
|
||||||
*.smod
|
|
||||||
|
|
||||||
# Compiled Static libraries
|
|
||||||
*.lai
|
|
||||||
*.la
|
|
||||||
*.a
|
|
||||||
*.lib
|
|
||||||
|
|
||||||
# Executables
|
|
||||||
*.exe
|
|
||||||
*.out
|
|
||||||
*.app
|
|
||||||
|
|
||||||
### clangd ###
|
|
||||||
.cache
|
|
||||||
|
|
||||||
### build ###
|
|
||||||
build/
|
|
||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,6 +1,3 @@
|
|||||||
[submodule "external/pipeline"]
|
[submodule "external/pipeline"]
|
||||||
path = external/pipeline
|
path = external/pipeline
|
||||||
url = https://github.com/p-ranav/pipeline.git
|
url = https://github.com/p-ranav/pipeline.git
|
||||||
[submodule "external/pipes"]
|
|
||||||
path = external/pipes
|
|
||||||
url = https://github.com/joboccara/pipes.git
|
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.20...4.0)
|
|
||||||
project(
|
|
||||||
pipe
|
|
||||||
VERSION 0.1.0
|
|
||||||
LANGUAGES CXX)
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
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)
|
|
||||||
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2025 Luís Murta
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
2
external/pipeline
vendored
2
external/pipeline
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 9a6741d8a3ee819ec045cd8f14366189462f104a
|
Subproject commit 31fffe6af101da57513eebca7518b1e434f5de87
|
||||||
1
external/pipes
vendored
1
external/pipes
vendored
@ -1 +0,0 @@
|
|||||||
Subproject commit b91d984798765127b4325ef7206d1db42c528d24
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
// 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
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
InheritParentConfig: true
|
|
||||||
Checks:
|
|
||||||
- -clang-analyzer-deadcode.DeadStores
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
find_package(benchmark REQUIRED)
|
|
||||||
|
|
||||||
add_executable(pipeline.test pipeline.test.cpp)
|
|
||||||
target_compile_features(pipeline.test PUBLIC cxx_std_23)
|
|
||||||
target_link_libraries(pipeline.test benchmark::benchmark_main
|
|
||||||
pipeline::pipeline joboccara::pipes pipe)
|
|
||||||
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)
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
#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
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
#include <benchmark/benchmark.h>
|
|
||||||
|
|
||||||
#include <freepipe/freepipe.hpp>
|
|
||||||
#include <pipeline/pipeline.hpp>
|
|
||||||
#include <pipes/pipes.hpp>
|
|
||||||
#include <tuple>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
void BM_Pipeline(benchmark::State& state) {
|
|
||||||
using namespace pipeline;
|
|
||||||
|
|
||||||
for (auto _ : state) {
|
|
||||||
auto add = fn([](auto a, auto b) { return a + b; });
|
|
||||||
auto double_it = fn([](auto a) { return a * 2; });
|
|
||||||
auto square_it = fn([](auto a) { return a * a; });
|
|
||||||
auto pipeline = add | double_it | square_it;
|
|
||||||
|
|
||||||
auto ans = pipeline(0, 1);
|
|
||||||
benchmark::DoNotOptimize(ans);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BENCHMARK(BM_Pipeline);
|
|
||||||
|
|
||||||
void BM_Pipes(benchmark::State& state) {
|
|
||||||
using namespace pipes;
|
|
||||||
|
|
||||||
for (auto _ : state) {
|
|
||||||
std::vector<int> ans;
|
|
||||||
|
|
||||||
mux(std::vector<int>{0}, std::vector<int>{1}) >>=
|
|
||||||
transform([](int a, int b) { return a + b; }) >>=
|
|
||||||
transform([](int a) { return a * 2; }) >>=
|
|
||||||
transform([](int a) { return a * a; }) >>= push_back(ans);
|
|
||||||
|
|
||||||
benchmark::DoNotOptimize(ans);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BENCHMARK(BM_Pipes);
|
|
||||||
|
|
||||||
void BM_Pipe(benchmark::State &state) {
|
|
||||||
using namespace freepipe;
|
|
||||||
|
|
||||||
for (auto _ : state) {
|
|
||||||
const Pipe p;
|
|
||||||
|
|
||||||
auto r = p | [] { return std::tuple{0, 1}; } | [](auto ab) {
|
|
||||||
auto a = std::get<0>(ab);
|
|
||||||
auto b = std::get<1>(ab);
|
|
||||||
|
|
||||||
return a + b;
|
|
||||||
} | [](auto a) {
|
|
||||||
return a * 2;
|
|
||||||
} | [](auto a) { return a * a; };
|
|
||||||
|
|
||||||
benchmark::DoNotOptimize(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BENCHMARK(BM_Pipe);
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// 2025-08-06T21:13:50+01:00
|
|
||||||
// Running /home/murta/src/pipeline/build/tests/pipeline.test
|
|
||||||
// Run on (16 X 3199.99 MHz CPU s)
|
|
||||||
// CPU Caches:
|
|
||||||
// L1 Data 32 KiB (x8)
|
|
||||||
// L1 Instruction 64 KiB (x8)
|
|
||||||
// L2 Unified 512 KiB (x8)
|
|
||||||
// L3 Unified 8192 KiB (x2)
|
|
||||||
// Load Average: 1.68, 1.49, 0.97
|
|
||||||
// -------------------------------------------------------
|
|
||||||
// Benchmark Time CPU Iterations
|
|
||||||
// -------------------------------------------------------
|
|
||||||
// BM_Pipeline 0.323 ns 0.323 ns 2163778209
|
|
||||||
// BM_Pipes 12.2 ns 12.2 ns 57225038
|
|
||||||
// BM_Pipe 0.320 ns 0.320 ns 2173384108
|
|
||||||
Loading…
x
Reference in New Issue
Block a user