[fusion] making an inner struct boost fusion compatible?
Hi list,
I have the following problem:
template
On Sep 20, 2012, at 4:29 AM, "Oswin Krause"
this inner struct must be a boost fusion compatible random access sequence. The examples cover only structs on namespace lvel, how can i handle this way? i don't want to clatter the namespace by pulling nested outside of the class.
Maybe forward-declare the inner struct within the outer, then define the inner struct outside as outer::inner?
Hi list,
I have the following problem:
template
struct MyType{ struct nested{ typename MetaFunc<T>::type a; typename MetaFunc<U>::type b; typename MetaFunc<V>::type c; }; }; now this inner struct must be a boost fusion compatible random access sequence. The examples cover only structs on namespace lvel, how can i handle this way? Later these classes will be generated by a macro automatically so even dirty hacks are allowed :). But i don't want to clatter the namespace by pulling nested outside of the class.
Is there an easy way or do i have to write the necessary mtafunctions to make this possible?
You should be able to use BOOST_FUSION_DEFINE_STRUCT_INLINE [1]
as follows:
template
HI, 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) Greetings, Oswin On 2012-09-20 21:53, Nathan Ridge wrote:
Hi list,
I have the following problem:
template
struct MyType{ struct nested{ typename MetaFunc<T>::type a; typename MetaFunc<U>::type b; typename MetaFunc<V>::type c; }; }; now this inner struct must be a boost fusion compatible random access sequence. The examples cover only structs on namespace lvel, how can i handle this way? Later these classes will be generated by a macro automatically so even dirty hacks are allowed :). But i don't want to clatter the namespace by pulling nested outside of the class.
Is there an easy way or do i have to write the necessary mtafunctions to make this possible?
You should be able to use BOOST_FUSION_DEFINE_STRUCT_INLINE [1] as follows:
template
struct MyType{ BOOST_FUSION_DEFINE_STRUCT_INLINE( nested, (typename MetaFunc<T>::type, a) (typename MetaFunc<U>::type, b) (typename MetaFunc<V>::type, c) ) }; Note however that BOOST_FUSION_DEFINE_STRUCT_INLINE is new in Boost 1.51.
Regards, Nate
[1]
http://www.boost.org/doc/libs/1_51_0/libs/fusion/doc/html/fusion/adapted/def...
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
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/s... [2] http://www.boost.org/doc/libs/1_45_0/libs/fusion/doc/html/fusion/extension/i...
Hi, Again thanks a lot! I allready got my first small success after scanning the file. I figured that what i needed was BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS Now i can write: struct MyType{ struct type : boost::fusion::sequence_facade< type, boost::fusion::random_access_traversal_tag
{ #define attributes (vector<T>,a)(vector<U>,b)(vector<V>,c) BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(type, attributes) //add own methods here...
//however, does this work?
struct reference{
#define refAttributes (T&,a)(U&,b)(V&,c)
BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(reference,
refAttributes)
};
};
};
I am not sure whether i can put reference types into the structure.
because in the macro there is a ctor created as:
#define BOOST_FUSION_MAKE_COPY_CONSTRUCTOR(NAME, ATTRIBUTES_SEQ)
\
NAME(BOOST_PP_SEQ_FOR_EACH_I(
\
BOOST_FUSION_MAKE_CONST_REF_PARAM,
\
~,
\
ATTRIBUTES_SEQ))
\
...
\
#define BOOST_FUSION_MAKE_CONST_REF_PARAM(R, DATA, N, ATTRIBUTE)
\
BOOST_PP_COMMA_IF(N)
\
BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) const&
\
BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)
so there is an assumption that ATTRIBUTE is not a reference type.
Is there a reason why it is implemented that way? If not, i would like
to change the argument type to something like(not compiled):
(with ELEM = BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE))
typename mpl::if_
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/s... [2]
http://www.boost.org/doc/libs/1_45_0/libs/fusion/doc/html/fusion/extension/i...
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi, I have to correct my previous mail and call it a day. Long story short: I need to implement a begin() and end() inside this struct method offering standard iterators over the elements of the containers. Unluckily they collide with the structs created by the macro which are also unfortunately named "begin" and "end". I am basically out of options now, so it must be outside the class, or? 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/s... [2]
http://www.boost.org/doc/libs/1_45_0/libs/fusion/doc/html/fusion/extension/i...
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi, so after a weekend of thinking about this issue, i am still not much nearer to an solution. Everything begins with that i want to automatically adapt a structure to the needs of my library. which is: 1. it is fusion compatible such that it's elements form a fusion seqeunce(easy) 2. there exist a container type storing the structure such, that for every element of structure a container exists (also easy). 3. These containers now shall also be a fusion sequence (aparently hard). Th idea is, that one an algorithm can decide to only work on a small fraction of the heterogenous data having a nice memory layout at the same time. This is my approach which failed: //slightly simplified example struct SomeStruct{ int a; float b; }; //specialisation for my interface. Will be a macro. template<> struct SequenceType<SomeStruct>{//sequence type of the structure i want to create struct type: boost::fusion::sequence_facade< type, boost::fusion::random_access_traversal_tag
{ //create fusion sequence interface BOOST_FUSION_DEFINE_STRUCT_MEMBERS_IMPL(type, (std::vector<int>,a)(std::vector<float>b))
//sequence interface
typedef SomeStruct value_type;
struct reference{...};//reference to an element
struct const_reference{...};
typedef ProxyIterator
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/s... [2]
http://www.boost.org/doc/libs/1_45_0/libs/fusion/doc/html/fusion/extension/i...
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
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
Batchstd::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)(Batchstd::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
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/s... [2]
http://www.boost.org/doc/libs/1_45_0/libs/fusion/doc/html/fusion/extension/i...
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Nat Goodspeed
-
Nathan Ridge
-
Oswin Krause