Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameter packs for Blockio #63

Open
jonas-frei opened this issue Jul 15, 2024 · 0 comments
Open

Parameter packs for Blockio #63

jonas-frei opened this issue Jul 15, 2024 · 0 comments

Comments

@jonas-frei
Copy link
Contributor

Blockio currently allows to create a block with N inputs and M outputs of type Tin and Tout. However, it does not allow to mix types (e.g. have two inputs - one being an int and the other a double). We could use parameter packs to implement this and make the blockio class more versatile.

#include <tuple>
#include <utility>
#include <iostream>

// Helper metafunction to extract input and output tuples from Types...
template <size_t N, size_t M, typename... Types>
struct SplitTypes;

template <size_t N, size_t M, typename... Tin, typename... Tout>
struct SplitTypes<N, M, std::tuple<Tin...>, std::tuple<Tout...>> {
    using Inputs = std::tuple<Tin...>;
    using Outputs = std::tuple<Tout...>;
};

template <size_t N, size_t M, typename First, typename... Rest, typename... Tin, typename... Tout>
struct SplitTypes<N, M, std::tuple<Tin...>, std::tuple<Tout...>, First, Rest...>
    : SplitTypes<N - 1, M, std::tuple<Tin..., First>, std::tuple<Tout...>, Rest...> {};

template <size_t M, typename First, typename... Rest, typename... Tin, typename... Tout>
struct SplitTypes<0, M, std::tuple<Tin...>, std::tuple<Tout...>, First, Rest...>
    : SplitTypes<0, M - 1, std::tuple<Tin...>, std::tuple<Tout..., First>, Rest...> {};

template <typename... Tin, typename... Tout>
struct SplitTypes<0, 0, std::tuple<Tin...>, std::tuple<Tout...>> {
    using Inputs = std::tuple<Tin...>;
    using Outputs = std::tuple<Tout...>;
};

template <size_t N, size_t M, typename... Types>
using SplitTypes_t = SplitTypes<N, M, std::tuple<>, std::tuple<>, Types...>;

// Blockio demo class
template <size_t N, size_t M, typename... Types>
class Blockio {
    static_assert(sizeof...(Types) == N + M, "Total number of types must match N + M");

    using Split = SplitTypes_t<N, M, Types...>;
    using InputTuple = typename Split::Inputs;
    using OutputTuple = typename Split::Outputs;

    InputTuple inputs;
    OutputTuple outputs;

public:
    Blockio() = default;

    // Function to set inputs
    template<typename... Tin>
    void setInputs(Tin... in) {
        static_assert(sizeof...(Tin) == N, "Number of inputs must match N");
        inputs = std::make_tuple(in...);
    }

    // Function to get inputs
    InputTuple getInputs() const {
        return inputs;
    }

    // Function to set outputs
    template<typename... Tout>
    void setOutputs(Tout... out) {
        static_assert(sizeof...(Tout) == M, "Number of outputs must match M");
        outputs = std::make_tuple(out...);
    }

    // Function to get outputs
    OutputTuple getOutputs() const {
        return outputs;
    }

    // Example method to display the inputs and outputs
    void display() const {
        std::cout << "Inputs: ";
        std::apply([](auto&&... args) {
            ((std::cout << args << " "), ...);
        }, inputs);
        std::cout << "\nOutputs: ";
        std::apply([](auto&&... args) {
            ((std::cout << args << " "), ...);
        }, outputs);
        std::cout << std::endl;
    }
};

int main() {
    // Define the Blockio class with 3 inputs and 2 outputs
    Blockio<3, 2, int, double, float, char, bool> block;

    // Set the inputs and outputs
    block.setInputs(1, 2.3, 4.5f);
    block.setOutputs('a', true);

    // Display the inputs and outputs
    block.display();

    return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant