是否可以从适应的结构生成融合图? [英] Is it possible to generate a fusion map from an adapted struct?

查看:79
本文介绍了是否可以从适应的结构生成融合图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

A 为:

struct A {
  int a;
  std::string b;
  struct keys {
    struct a;
    struct b;
  };
};

我想生成 fusion :: map 从结构中包含 fusion :: pair s: fusion :: pair< A :: keys :: a,int> fusion :: pair< A :: keys :: b,std :: string>

I would like to generate a fusion::map from the struct such that it contains the fusion::pairs: fusion::pair<A::keys::a, int> and fusion::pair<A::keys::b, std::string>. Something like

A a;
fusion::make_map<A>(a)

我尝试使用 BOOST_FUSION_ADAPT_ASSOC_STRUCT

BOOST_FUSION_ADAPT_ASSOC_STRUCT(
    A,
    (int,  a, A::keys::a)
    (std::string, b, A::keys::b)

这使A可以用作关联序列,但是我还没有找到一种方法来从它。特别是,如果我对其进行迭代,则只会得到值。如果我可以遍历对键真正有用的键,因为这样我就可以压缩值和键来构建地图,但是我还没有找到一种方法。

This adapts A to be used as an associative sequence, but I haven't found a way to construct a map from it. In particular, if I iterate over it I get only the values. If I could iterate over the keys that would be really helpful, because then I could zip the values and the keys to build a map, but I haven't found a way to do this yet.

推荐答案

您应使用 Associative Iterator 接口-它提供 result_of :: key_of< I> :: type 元功能。

You should use Associative Iterator interface - it provides result_of::key_of<I>::type metafunciton.

我在旧记录中找到了代码,并提取了相关部分。
我在实现 SoA向量的过程中使用了它(据我从聊天中了解到-您也在实现它),但最终切换为 fusion :: map 的明确定义。我想我这样做是为了拥有正常结构和引用结构的统一接口(即,两者都通过类型标记访问)。

I have found code in my old records, and extracted relevant part. I used it during implementation of SoA vector (as I understand from chat - you are implementing it too), but eventually switched to just explicit definition of fusion::map. I think I did that in order to have unified interface of normal structure and structure of references (i.e. both are accessed via type tag).

Coliru上的实时演示

namespace demo
{
    struct employee
    {
        std::string name;
        int age;
    };
}

namespace keys
{
    struct name;
    struct age;
}

BOOST_FUSION_ADAPT_ASSOC_STRUCT
(
    demo::employee,
    (std::string, name, keys::name)
    (int, age, keys::age)
)

template<typename> void type_is();

int main()
{
    type_is<as_fusion_map<demo::employee>::type>();
}

结果是:

main.cpp:(.text.startup+0x5): undefined reference to `void type_is<

boost::fusion::map
<
    boost::fusion::pair<keys::name, std::string>,
    boost::fusion::pair<keys::age, int>,
    boost::fusion::void_,
    boost::fusion::void_,
    boost::fusion::void_,
    boost::fusion::void_,
    boost::fusion::void_,
    boost::fusion::void_,
    boost::fusion::void_,
    boost::fusion::void_
>

>()'






此处已全面实施


Here is full implementation

//             Copyright Evgeny Panasyuk 2012.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)


// Reduced from larger case, some includes may not be needed

#include <boost/fusion/algorithm/transformation/transform.hpp>
#include <boost/fusion/sequence/intrinsic/value_at_key.hpp>
#include <boost/fusion/include/adapt_assoc_struct.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/view/transform_view.hpp>
#include <boost/fusion/view/zip_view.hpp>
#include <boost/fusion/container/map.hpp>
#include <boost/fusion/algorithm.hpp>

#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>

#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

#include <iostream>
#include <iterator>
#include <ostream>
#include <string>

#include <boost/mpl/push_front.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/iterator.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/iterator/key_of.hpp>
#include <boost/fusion/iterator/value_of.hpp>

using namespace boost;
using namespace std;

using fusion::at_key;
using fusion::at_c;

// ____________________________________________________________________________________ //

namespace res_of=boost::fusion::result_of;
using namespace boost::fusion;

template<typename Vector,typename First,typename Last,typename do_continue>
struct to_fusion_map_iter;

template<typename Vector,typename First,typename Last>
struct to_fusion_map_iter<Vector,First,Last,mpl::false_>
{
    typedef typename res_of::next<First>::type Next;
    typedef typename mpl::push_front
    <
        typename to_fusion_map_iter
        <
            Vector,
            Next,
            Last,
            typename res_of::equal_to<Next,Last>::type
        >::type,
        fusion::pair
        <
            typename res_of::key_of<First>::type,
            typename res_of::value_of_data<First>::type
        >
    >::type type;
};
template<typename Vector,typename First,typename Last>
struct to_fusion_map_iter<Vector,First,Last,mpl::true_>
{
    typedef Vector type;
};

template<typename FusionAssociativeSequence>
struct as_fusion_map
{
    typedef typename res_of::begin<FusionAssociativeSequence>::type First;
    typedef typename res_of::end<FusionAssociativeSequence>::type Last;
    typedef typename res_of::as_map
    <
        typename to_fusion_map_iter
        <
            mpl::vector<>,
            First,
            Last,
            typename res_of::equal_to<First,Last>::type
        >::type
    >::type type;
};

// ____________________________________________________________________________________ //

// Defenition of structure:

namespace demo
{
    struct employee
    {
        std::string name;
        int age;
    };
}

namespace keys
{
    struct name;
    struct age;
}

BOOST_FUSION_ADAPT_ASSOC_STRUCT
(
    demo::employee,
    (std::string, name, keys::name)
    (int, age, keys::age)
)

// ____________________________________________________________________________________ //
template<typename> void type_is();

int main()
{
    type_is<as_fusion_map<demo::employee>::type>();
}

这篇关于是否可以从适应的结构生成融合图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆