[fusion] making an inner struct boost fusion compatible?
Hi list, I have the following problem: template<class T, class U, class V> 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? Greetings, Oswin
On Sep 20, 2012, at 4:29 AM, "Oswin Krause" <Oswin.Krause@ruhr-uni-bochum.de> wrote:
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<class T, class U, class V> 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<class T, class U, class V> 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...
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<class T, class U, class V> 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<class T, class U, class V> 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_<is_reference<ELEM>, ELEM, typename add_const<typename remove_reference<ELEM>::type>::type& >::type (if ELEM is a reference use ELEM as argument type, else try to get a const reference in a safe way) Anyways, Keep up the good work! Fusion is great :) Gretings, Oswin Krause 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, 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<type, value_type, reference > iterator; typedef ProxyIterator<const type, value_type, const_reference > const_iterator; iterator begin(){...}//naming collision :( const_iterator begin()const{...}//naming collision :( iterator end(){...}//naming collision :( const_iterator end()const{...}//naming collision :( }; .... }; so what would be a good solution for my problem? 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, 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/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