升压噶 - 非消费predicate [英] Boost Karma - non consuming predicate

查看:217
本文介绍了升压噶 - 非消费predicate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要打印一个std ::复杂的,但忽略虚部,如果是等于零。所以,我有两个产生的规则:

I need to print a std::complex but omitting imaginary part if it's equal zero. So I have a rule with two productions:

karma::rule<OutputIterator, std::complex<double>()> complexRule = 
    '(' << double_ << ", " double_ << ')'
    | double_ << omit[double_];

这样噶总会选择第一条生产,所以我需要某种predicate的这将使decission。 <一href=\"http://www.boost.org/doc/libs/1_55_0/libs/spirit/doc/html/spirit/karma/tutorials/karma_adapted_complex.html\"相对=nofollow>升压噶教程附带了一个解决方案,需要适应的std ::复杂的三元素元组。

This way Karma will always choose the first production, so I need some kind of predicate which will make a decission. Boost Karma tutorial comes with that solution which requires adapting std::complex as a three element tuple.

BOOST_FUSION_ADAPT_ADT(
    std::complex<double>,
    (bool, bool, obj.imag() != 0, /**/)
    (double, double, obj.real(), /**/)
    (double, double, obj.imag(), /**/)
)

但遗憾的是我不能这样做,因为其他code使用的std ::复杂改编为两个元素的元组。有没有办法解决这个问题,而不增加predicate直冲融合适配器的方式?

but unfortunately I cannot do that since other code is using std::complex adapted as two element tuple. Is there a way to solve that problem without adding predicate straight into Fusion adapter?

我试图用<一个href=\"http://www.boost.org/doc/libs/1_55_0/libs/spirit/doc/html/spirit/karma/reference/auxiliary/eps.html\"相对=nofollow>因缘:: EPS发电机的为predicate

I was trying to use karma::eps generator as a predicate

auto rule = eps( ... ) << '(' << double_ << ", " << double_ << ')'
          | double_ << omit[double_];

但我不知道是什么凤凰前pression我应该把里面的EPS(...),并作为小量发电机不消耗任何属性,我不知道是否有可能访问STD: :?从它复杂的

but I don't know what Phoenix expression should I put inside eps( ... ), and as Epsilon Generator doesn't consume any attribute I'm not sure if it is possible to access std::complex from it?

推荐答案

我个人呆在远离适应这个作为序列(我不知道你如何适应其作为首位两元素融合序列)。

I'd personally stay away from adapting this as a sequence (I'm not sure how you adapted it as a two-element fusion sequence in the first place).

但它的完成,也不会是一般的(所以你必须针对不同类型的参数使用单独的改编(浮动长双的boost ::多precision ::号&LT;提高::多precision: :。cpp_dec_float&LT; 50 GT;&GT; 等)

However it's done, it won't be generic (so you'll have use separate adaptations for different type arguments (float, double, long double, boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>> etc.).

这似乎是对精神的自定义点

namespace boost { namespace spirit { namespace traits {

    template <typename T>
        struct extract_from_attribute<typename std::complex<T>, boost::fusion::vector2<T, T>, void>
        {
            typedef boost::fusion::vector2<T,T> type;

            template <typename Context>
                static type call(std::complex<T> const& attr, Context& context)
                {
                    return { attr.real(), attr.imag() };
                }
        };

} } }

现在你可以使用的任何的std ::复杂&LT; T&GT; 与规则/ EX pression期待融合序列:

Now you can just use any std::complex<T> with a rule/expression expecting fusion sequence:

 rule = 
        '(' << karma::double_ << ", " << karma::duplicate [ !karma::double_(0.0) << karma::double_ ] << ')' 
      | karma::double_ << karma::omit [ karma::double_ ];

请注意如何


  • 我用复制[] 来的测试的为 0.0 前发出的输出

  • 在我使用忽略,而不显示任何消耗虚部
  • 其他分支
  • I used duplicate[] to test for 0.0 before emitting the output
  • On the other branch I used omit to consume the imaginary part without displaying anything

下面是一个完整的演示, 住在Coliru

Here's a full demo, Live On Coliru

#include <boost/spirit/include/karma.hpp>
#include <complex>

namespace boost { namespace spirit { namespace traits {

    template <typename T>
        struct extract_from_attribute<typename std::complex<T>, boost::fusion::vector2<T, T>, void>
        {
            typedef boost::fusion::vector2<T,T> type;

            template <typename Context>
                static type call(std::complex<T> const& attr, Context& context)
                {
                    return { attr.real(), attr.imag() };
                }
        };

} } }

namespace karma = boost::spirit::karma;

int main()
{
    karma::rule<boost::spirit::ostream_iterator, boost::fusion::vector2<double, double>()> 
        static const rule = 
                            '(' << karma::double_ << ", " << karma::duplicate [ !karma::double_(0.0) << karma::double_ ] << ')' 
                          | karma::double_ << karma::omit [ karma::double_ ];

    std::vector<std::complex<double>> const values {
                { 123, 4 },
                { 123, 0 },
                { 123, std::numeric_limits<double>::infinity() },
                { std::numeric_limits<double>::quiet_NaN(), 0 },
                { 123, -1 },
            };

    std::cout << karma::format_delimited(*rule, '\n', values);
}

输出:

(123.0, 4.0)
123.0
(123.0, inf)
nan
(123.0, -1.0)

这篇关于升压噶 - 非消费predicate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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