├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── example ├── CMakeLists.txt ├── components.h └── main.cpp └── include ├── Circuit.h ├── Common.h └── Component.h /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.user 3 | build 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(route20) 4 | 5 | set(CMAKE_CXX_STANDARD 20) 6 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 7 | set(CMAKE_CXX_EXTENSIONS OFF) 8 | 9 | if(MSVC) 10 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W4") 11 | else() 12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -pthread") 13 | endif() 14 | 15 | add_subdirectory(example) 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2021, Marcus Tomlinson 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Route20 2 | 3 | Cross-Platform C++ Dataflow Metaprogramming Framework 4 | 5 | Route20 is a powerful C++ dataflow metaprogramming library that allows you to create and route complex dataflow systems at compile-time. 6 | 7 | ## Build & Run 8 | 9 | _**NOTE:** A C++20 compatible compiler is required to build this project._ 10 | 11 | ``` 12 | git clone https://github.com/cross-platform/route20.git 13 | cd route20 14 | mkdir build 15 | cd build 16 | cmake .. 17 | make 18 | 19 | ./example/route20-example 20 | ``` 21 | 22 | - *`cmake ..` will auto-detect your IDE / compiler. To manually select one, use `cmake -G`.* 23 | - *When building for an IDE, instead of `make`, simply open the cmake generated project file.* 24 | 25 | The source code for the `route20-example` application above can be found in the "example" folder. 26 | -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(route20-example) 2 | 3 | include_directories( 4 | ${CMAKE_SOURCE_DIR}/include 5 | ${CMAKE_CURRENT_SOURCE_DIR} 6 | ) 7 | 8 | file(GLOB srcs *.cpp) 9 | 10 | add_executable( 11 | ${PROJECT_NAME} 12 | ${srcs} 13 | ) 14 | -------------------------------------------------------------------------------- /example/components.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | Route20 - Cross-Platform C++ Dataflow Metaprogramming Framework 3 | Copyright (c) 2021 Marcus Tomlinson 4 | 5 | This file is part of Route20. 6 | 7 | Simplified BSD Licence: 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ************************************************************************/ 31 | 32 | #pragma once 33 | 34 | #include 35 | 36 | namespace Route20 37 | { 38 | 39 | /// RandBool: 40 | /// RandBool has 1 output. 41 | /// This component generates a random boolean value then outputs the result. 42 | 43 | class RandBool 44 | { 45 | private: 46 | class RandBoolRt final 47 | { 48 | public: 49 | RandBoolRt() 50 | { 51 | // seed randomizer 52 | srand( static_cast( time( nullptr ) ) ); 53 | } 54 | 55 | RandBoolRt( const RandBoolRt& ) = delete; 56 | RandBoolRt& operator=( const RandBoolRt& ) = delete; 57 | 58 | std::tuple<> inputs; 59 | std::tuple outputs; 60 | }; 61 | 62 | public: 63 | using runtime = RandBoolRt; 64 | 65 | void Tick( runtime& rt ) const 66 | { 67 | std::get<0>( rt.outputs ) = rand() % 2 == 0; 68 | } 69 | }; 70 | 71 | /// And: 72 | /// And has 2 inputs and 1 output. 73 | /// This component performs a logic AND on 2 boolean input values and outputs the result. 74 | 75 | class And 76 | { 77 | private: 78 | class AndRt final 79 | { 80 | public: 81 | AndRt() = default; 82 | AndRt( const AndRt& ) = delete; 83 | AndRt& operator=( const AndRt& ) = delete; 84 | 85 | std::tuple inputs; 86 | std::tuple outputs; 87 | }; 88 | 89 | public: 90 | using runtime = AndRt; 91 | 92 | void Tick( runtime& rt ) const 93 | { 94 | std::get<0>( rt.outputs ) = std::get<0>( rt.inputs ) && std::get<1>( rt.inputs ); 95 | } 96 | }; 97 | 98 | /// PrintBool: 99 | /// PrintBool has 1 input. 100 | /// This component receives a boolean value and outputs it to the console. 101 | 102 | class PrintBool 103 | { 104 | private: 105 | class PrintBoolRt final 106 | { 107 | public: 108 | PrintBoolRt() = default; 109 | PrintBoolRt( const PrintBoolRt& ) = delete; 110 | PrintBoolRt& operator=( const PrintBoolRt& ) = delete; 111 | 112 | std::tuple inputs; 113 | std::tuple<> outputs; 114 | }; 115 | 116 | public: 117 | using runtime = PrintBoolRt; 118 | 119 | void Tick( runtime& rt ) const 120 | { 121 | std::cout << ( std::get<0>( rt.inputs ) ? "true" : "false" ) << std::endl; 122 | } 123 | }; 124 | 125 | } // namespace Route20 126 | -------------------------------------------------------------------------------- /example/main.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | Route20 - Cross-Platform C++ Dataflow Metaprogramming Framework 3 | Copyright (c) 2021 Marcus Tomlinson 4 | 5 | This file is part of Route20. 6 | 7 | Simplified BSD Licence: 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ************************************************************************/ 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | using namespace Route20; 38 | 39 | /// In this example we create a simple Route20 circuit that generates random boolean 40 | /// pairs, performs a logic AND on each pair, then prints the result to screen. 41 | 42 | int main() 43 | { 44 | // Instantiate 2x RandBools with IDs 0 and 1 (compile time) 45 | constexpr auto randBoolGen1 = Component<0, RandBool>(); 46 | constexpr auto randBoolGen2 = Component<1, RandBool>(); 47 | 48 | // Instantiate an And component with ID 2, and connect RandBools to inputs 0 and 1 (compile time) 49 | constexpr auto logicAnd = Component<2, And, randBoolGen1, 0, 0, randBoolGen2, 0, 1>(); 50 | 51 | // Instantiate a PrintBool component with ID 3, and connect And output 0 to input 0 (compile time) 52 | constexpr auto boolPrinter = Component<3, PrintBool, logicAnd, 0, 0>(); 53 | 54 | // Instantiate a Circuit (run time) 55 | auto circuit = Circuit(); 56 | 57 | // Run the Circuit (run time) 58 | for ( int i = 0; i < 100; i++ ) 59 | { 60 | circuit.Tick(); 61 | } 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /include/Circuit.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | Route20 - Cross-Platform C++ Dataflow Metaprogramming Framework 3 | Copyright (c) 2021 Marcus Tomlinson 4 | 5 | This file is part of Route20. 6 | 7 | Simplified BSD Licence: 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ************************************************************************/ 31 | 32 | #pragma once 33 | 34 | #include 35 | 36 | #include 37 | 38 | namespace Route20 39 | { 40 | 41 | template 42 | class Circuit final 43 | { 44 | public: 45 | Circuit() 46 | { 47 | InitMaps(); 48 | } 49 | 50 | Circuit( const Circuit& ) = delete; 51 | Circuit& operator=( const Circuit& ) = delete; 52 | 53 | void Tick() 54 | { 55 | Tick(); 56 | for ( auto& [_, ticked] : tickeds ) 57 | { 58 | ticked = false; 59 | } 60 | } 61 | 62 | private: 63 | template 64 | void InitMaps() 65 | { 66 | InitMaps(); 67 | InitMaps(); 68 | } 69 | 70 | template 71 | void InitMaps() 72 | { 73 | using CompRt = typename decltype( comp )::runtime; 74 | rts[comp.id].template emplace(); 75 | tickeds[comp.id] = false; 76 | } 77 | 78 | template 79 | void Tick() 80 | { 81 | Tick(); 82 | Tick(); 83 | } 84 | 85 | template 86 | void Tick() 87 | { 88 | if ( tickeds[comp.id] ) 89 | { 90 | return; 91 | } 92 | tickeds[comp.id] = true; 93 | 94 | using CompRt = typename decltype( comp )::runtime; 95 | 96 | comp.InputWires( [this]() { 97 | Tick(); 98 | 99 | using FromCompRt = typename decltype( fromComp )::runtime; 100 | 101 | std::get( std::get( rts[comp.id] ).inputs ) = 102 | std::get( std::get( rts[fromComp.id] ).outputs ); 103 | } ); 104 | 105 | comp.Tick( std::get( rts[comp.id] ) ); 106 | } 107 | 108 | std::map>> rts; 109 | std::map tickeds; 110 | }; 111 | 112 | } // namespace Route20 113 | -------------------------------------------------------------------------------- /include/Common.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | Route20 - Cross-Platform C++ Dataflow Metaprogramming Framework 3 | Copyright (c) 2021 Marcus Tomlinson 4 | 5 | This file is part of Route20. 6 | 7 | Simplified BSD Licence: 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ************************************************************************/ 31 | 32 | #pragma once 33 | 34 | #include 35 | 36 | namespace Route20 37 | { 38 | 39 | template 40 | struct contains; 41 | 42 | template 43 | struct contains, Needle> : contains, Needle> 44 | { 45 | }; 46 | 47 | template 48 | struct contains, Needle> : std::true_type 49 | { 50 | }; 51 | 52 | template 53 | struct contains, Needle> : std::false_type 54 | { 55 | }; 56 | 57 | template 58 | struct filter; 59 | 60 | template 61 | struct filter, std::variant> 62 | { 63 | using type = typename std::conditional, InCar>::value, 64 | filter, std::variant>, 65 | filter, std::variant>>::type::type; 66 | }; 67 | 68 | template 69 | struct filter> 70 | { 71 | using type = Out; 72 | }; 73 | 74 | template 75 | using dedup_variant = typename filter, T>::type; 76 | 77 | } // namespace Route20 78 | -------------------------------------------------------------------------------- /include/Component.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | Route20 - Cross-Platform C++ Dataflow Metaprogramming Framework 3 | Copyright (c) 2021 Marcus Tomlinson 4 | 5 | This file is part of Route20. 6 | 7 | Simplified BSD Licence: 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ************************************************************************/ 31 | 32 | #pragma once 33 | 34 | namespace Route20 35 | { 36 | 37 | template 38 | class Component final : public Impl 39 | { 40 | public: 41 | const unsigned int id = uid; 42 | 43 | consteval Component() = default; 44 | consteval Component( const Component& ) = default; 45 | Component& operator=( const Component& ) = delete; 46 | 47 | void InputWires( const auto& callback ) const 48 | { 49 | InputWires( callback ); 50 | } 51 | 52 | template 53 | void InputWires( const auto& callback ) const 54 | { 55 | InputWires<_fromComp, _output, _input>( callback ); 56 | InputWires<_nextFromComp, _nextOutput, _nextInput...>( callback ); 57 | } 58 | 59 | template 60 | void InputWires( const auto& callback ) const 61 | { 62 | callback.template operator()<_fromComp, _output, _input>(); 63 | } 64 | 65 | template 66 | void InputWires( const auto& ) const 67 | { 68 | } 69 | }; 70 | 71 | } // namespace Route20 72 | --------------------------------------------------------------------------------