Fusion adapted std_tuple views, conversion to another tuple

Boost Fusion was designed so that most transformations are β€œlazy” in the sense that they all generate β€œviews” but not actual (Fusion) containers ( http://www.boost.org/doc/libs/1_58_0/libs /fusion/doc/html/fusion/algorithm.html ). So, for example, to actually flip a vector, you need to use the conversion function as_vector( http://www.boost.org/doc/libs/1_58_0/libs/fusion/doc/html/fusion/container/conversion/functions.html ).

boost::fusion::vector<int, double, std::string> vec;
auto view_rev = boost::fusion::reverse(vec); // view object
auto vec_rev = boost::fusion::as_vector(view_rev);

Now I want to do this using adapted std::tuple:

#include<boost/fusion/adapted/std_tuple.hpp>
...
std::tuple<int, double, std::string> tup;
auto view_rev = boost::fusion::reverse(tup);
auto tup_rev = boost::fusion::???(view_rev); // type should be of type std::tuple<std::string, double, int>

How to convert the result back to a tuple?

, ??? as_std_tuple ( boost::fusion::as_vector, (?).

, , Boost Fusion.

+4
1

- Boost Fusion std::tuple, :

template <std::size_t... Is>
struct indices {};

template <std::size_t N, std::size_t... Is>
struct build_indices
  : build_indices<N-1, N-1, Is...> {};

template <std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...> {};

template<typename Sequence, std::size_t ...Is>
auto as_std_tuple_impl(const Sequence& s, indices<Is...>&&) -> decltype(std::tie(boost::fusion::at_c<Is>(s)...))
{
    return std::tie(boost::fusion::at_c<Is>(s)...);
}

template <typename Sequence, typename Indices = build_indices<boost::fusion::result_of::size<Sequence>::value>>
auto as_std_tuple(const Sequence& s) -> decltype(as_std_tuple_impl(s, Indices()))
{
    return as_std_tuple_impl(s, Indices());
}

, std::tuple boost::fusion::reverse std::tuple :

#include <tuple>
#include <utility>

#include<boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/algorithm/transformation/reverse.hpp>
#include <boost/fusion/include/reverse.hpp>

#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/include/size.hpp>

#include <iostream>

template <std::size_t... Is>
struct indices {};

template <std::size_t N, std::size_t... Is>
struct build_indices
  : build_indices<N-1, N-1, Is...> {};

template <std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...> {};

template<typename Sequence, std::size_t ...Is>
auto as_std_tuple_impl(const Sequence& s, indices<Is...>&&) -> decltype(std::tie(boost::fusion::at_c<Is>(s)...))
{
    return std::tie(boost::fusion::at_c<Is>(s)...);
}

template <typename Sequence, typename Indices = build_indices<boost::fusion::result_of::size<Sequence>::value>>
auto as_std_tuple(const Sequence& s) -> decltype(as_std_tuple_impl(s, Indices()))
{
    return as_std_tuple_impl(s, Indices());
}


template<class Tuple, std::size_t N>
struct TuplePrinter
{
    static void print(const Tuple& t) 
    {
        TuplePrinter<Tuple, N-1>::print(t);
        std::cout << ", " << std::get<N-1>(t);
    }
};

template<class Tuple>
struct TuplePrinter<Tuple, 1> 
{
    static void print(const Tuple& t) 
    {
        std::cout << std::get<0>(t);
    }
};

template<class... Args>
void print(const std::tuple<Args...>& t) 
{
    std::cout << "(";
    TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
    std::cout << ")\n";
}

int main()
{
    std::tuple<int, double, std::string> tup(1,2.5,"hello");
    auto view_rev = boost::fusion::reverse(tup);
    auto reversed_tup = as_std_tuple(view_rev);

    print(tup);
    print(reversed_tup);
    return 0;
}

:

(1, 2.5, hello)
(hello, 2.5, 1)

ideone

+2

Source: https://habr.com/ru/post/1599755/


All Articles