|
Boost Users : |
Subject: Re: [Boost-users] [fusion] making an inner struct boost fusion compatible?
From: Oswin Krause (Oswin.Krause_at_[hidden])
Date: 2012-10-17 16:49:32
HI,
it is m again. I thought a week (or2?) ago that i found a solution.
However, it only worked on gcc. i feel that there is only som epsilon
missing and i hope that someone else has an solution.
So to repeat my problem:
i have a fusion compatible struct like this:
struct TestStruct{
RealVector v1;
std::size_t v2;
RealVector v3;
};
BOOST_FUSION_ADAPT_STRUCT(
TestStruct,
(shark::RealVector, v1)(std::size_t, v2)(shark::RealVector, v3)
)
now i want to transform it into something like:
template<>
struct Batch<TestStruct1>{
struct type{
Batch<RealVector>::type v1;//->Matrix type
Batch<std::size_t>::type v2;//->Vector type
Batch<RealVector> v3;//->Matrix type
typedef ... iterator;
iterator begin();
iterator end();
std::size_t size();
//more
};
};
BOOST_FUSION_ADAPT_STRUCT(
Batch<TestStruct1>::type,
(Batch<RealVector>::type, v1)(Batch<std::size_t>::type,
v2)(Batch<RealVector>::type, v3)
)
only that this solution does not work to my knowledge. So I want the
type to behave like a tuple AND like a stl range(iterating over the
matrix rows/entries of the second vector). I have got working macros for
this without fusion support and need to add fusion support to get some
other use cases working.
My working solution with gcc and fusion support was a macro invoked
like this:
template<>
struct Batch< TestStruct1 >{
CREATE_BATCH_INTERFACE(
TestStruct1,
(RealVector, v1)(std::size_t, v2)(RealVector, v3)
)
};
and which looks like:
#define CREATE_BATCH_INTERFACE(NAME,ATTRIBUTES)\
private:\
BOOST_FUSION_DEFINE_STRUCT_INLINE(FusionSequence,
TRANSFORM_BATCH_ATTRIBUTES(type,ATTRIBUTES))\
public:\
struct type:public FusionSequence{\
CREATE_BATCH_ITERATORS()\
std::size_t size()const{\
return boost::size(boost::fusion::at_c<0>(*this));\
}\
[snip]
};\
where CREATE_BATCH_ITERATORS generate begin() end() and the required
typedefs, while TRANSFORM_BATCH_ATTRIUBUTES creates the transformation
T-> Batch<T>::type. As i said, this works fine on gcc. Clang however
doesn't like this, because it still confuses the structs begin/end/size
defined by BOOST_FUSION_DEFINE_STRUCT_INLINE in FusionSequnce with my
begin()/end()/size() of the range. My initial guess was, that since the
FusionSequence is drived from
boost::fusion::sequence_facade<FusionSequence> there would be a cast to
FusionSequence inside fusion which resolves the issue. At least this is
why i thought this works on gcc. I cna proof that this is different on
clang because a static_cast<FusionSequence const&>(*this) resolves the
issue in size. but the caller can't do this if he wants to use the
defined type as sequence.
So any idas for the last epsilon fix?
On 2012-09-21 09:52, Nathan Ridge wrote:
>> thanks for the reply.
>> Is it possible to just copy and rename the macro, or does it depend
>> on
>> newer features of fusion? I need to be compatible with boost 1.45 so
>> i
>> can't use it directly (also i need to add a few more functions to
>> the
>> structure later on)
>
> BOOST_FUSION_DEFINE_STRUCT_INLINE is implemented using the
> sequence_facade
> and iterator_facade extension mechanisms, which were present in Boost
> 1.45
> [1] [2]. So, it should be straightforward to back-port the macro to
> 1.45.
>
> Regards,
> Nate
>
> [1]
>
> http://www.boost.org/doc/libs/1_45_0/libs/fusion/doc/html/fusion/extension/sequence_facade.html
> [2]
>
> http://www.boost.org/doc/libs/1_45_0/libs/fusion/doc/html/fusion/extension/iterator_facade.html
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net