Dobiasd / FunctionalPlus

Functional Programming Library for C++. Write concise and readable C++ code.
http://www.editgym.com/fplus-api-search/
Boost Software License 1.0
2.1k stars 167 forks source link

Function to print std::tuple #269

Closed ferdymercury closed 1 year ago

ferdymercury commented 1 year ago

Hello, I was wondering if there is already a simple way of printing out the contents of an std::tuple using fplus.

Or if you would consider adding some of these solutions to your lib: https://stackoverflow.com/questions/6245735/pretty-print-stdtuple

Thanks for your library!

Dobiasd commented 1 year ago

Hi, thanks for the positive feedback and the excellent idea. :slightly_smiling_face:

So far, there is nothing in FunctionalPlus to print tuples.

To keep it generic (and reuse the separator/prefix/suffix logic from the fplus::show_cont... function family), I guess it would make sense not to add something to directly print a tuple but to just convert it into a list of strings.

Would you like to give the implementation a try in a pull request?

Otherwise, I'd see if I can do something, based on the cppreference example.

ferdymercury commented 1 year ago

Thanks for the swift reply.

To keep it generic (and reuse the separator/prefix/suffix logic from the fplus::show_cont... function family), I guess it would make sense not to add something to directly print a tuple but to just convert it into a list of strings.

You mean using stringstream instead of iostream ?

ferdymercury commented 1 year ago

This could do the job:

#include <iostream>
#include <tuple>
#include <string>
#include <sstream>
#include <list>

template<class Tuple, std::size_t N>
struct TuplePrinter {
    static void print(const Tuple& t, std::list<std::string>& sl) 
    {
        TuplePrinter<Tuple, N-1>::print(t,sl);
        std::stringstream ss;
        ss << std::get<N-1>(t);
        sl.emplace_back(ss.str());
    }
};

template<class Tuple>
struct TuplePrinter<Tuple, 1> {
    static void print(const Tuple& t, std::list<std::string>& sl) 
    {
        std::stringstream ss;
        ss << std::get<0>(t);
        sl.emplace_back(ss.str());
    }
};

template<typename... Args, std::enable_if_t<sizeof...(Args) == 0, int> = 0>
void print(const std::tuple<Args...>& t, std::list<std::string>& sl)
{
    return;
}

template<typename... Args, std::enable_if_t<sizeof...(Args) != 0, int> = 0>
std::list<std::string> print(const std::tuple<Args...>& t)
{
    std::list<std::string> sl;
    TuplePrinter<decltype(t), sizeof...(Args)>::print(t,sl);
    return std::move(sl);
}

int main() {

    std::tuple<int, std::string, float> t1(10, "Test", 3.14);
    std::list<std::string> lt1 = print(t1);
    for(auto &l : lt1) std::cout << l << ", ";
}
Dobiasd commented 1 year ago

Yes, exactly! :partying_face:

And then, one could use std::cout << fplus::show_cont(lt1); instead of for(auto &l : lt1) std::cout << l << ", ";.

Dobiasd commented 1 year ago

Would you like to create a pull request, adding this to show.hpp, and, if you like, your test case from above to show_test.cpp?