
Joel de Guzman schrieb:
On 7/30/2010 6:35 AM, Stefan Strasser wrote:
Zitat von Hartmut Kaiser <hartmut.kaiser@gmail.com>:
1)
ADAPT_STRUCT can adapt public data members only.
with the modifications I uploaded here: http://svn.boost.org/svn/boost/sandbox/intro/boost/fusion/adapted/struct/
all data members can be adapted. for example:
class A{ private: friend class fusion::access; int a; };
BOOST_FUSION_ADAPT_STRUCT(A,(int,a) )
2)
adaption of a class including its base class members. for example:
struct A{ int a; }; struct B{ int b; }; struct C : A,B{ int c; }
BOOST_FUSION_ADAPT_STRUCT(A,(int,a) ) BOOST_FUSION_ADAPT_STRUCT(B,(int,b) ) BOOST_FUSION_ADAPT_DERIVED( C, (A)(B), (int,c) )
an instance of C is now a fusion sequence of size 3. http://svn.boost.org/svn/boost/sandbox/intro/boost/fusion/adapted/struct/a
dapt_derived.hpp
private inheritance is supported as above, virtual inheritance is not. I'm not sure if virtual inheritance can be supported.
Have you seen the new BOOST_FUSION_ADAPT_CLASS() family of utilities which allow using (member-) functions instead of direct access to the data members of a class/struct?
no I had not, I was using 1.41. where can I see those? can't seem to find them in 1.43 or the trunk.
The BOOST_FUSION_ADAPT_xxxCLASSxxx-macros are not documented yet. For more information, refer to the code and the testcases: https://svn.boost.org/trac/boost/browser/trunk/boost/fusion/adapted/class https://svn.boost.org/trac/boost/browser/trunk/libs/fusion/test/sequence https://svn.boost.org/trac/boost/browser/trunk/libs/fusion/test/sequence/ada...
do these solve one of the two issues above? in case you brought it up because then you could have public accessor functions to private members, I'd still propose to add a way to adapt private members as shown above. I'd like to use this for what is apparently known as the "scrap your boilerplate" pattern in the functional programming world (see the previous [intro] discussion), which requires adapting each member in every class used in such an algorithm. there obviously shouldn't be public accessors for all members.
I like it! I think this patch provides solutions not yet available. You should coordinate with Christopher Schmidt, he did the new adapt class macros and figure out how to make it all fit and have a consistent interface.
I patched the code in the trunk to enable the adaption of private attributes. The adaptee just needs to friend "struct boost::fusion::extension::access". See changeset 64490 (https://svn.boost.org/trac/boost/changeset/64490) for details. Regarding the second feature request: I am not in favor of adding yet another set of BOOST_FUSION_ADAPT_xxx-macros. Altogether we got 6 documented and 4 undocumented macros to adapt structs, 10 undocumented macros to adapt classes and another 4 macros to define structs. Any new adaption family will multiply the macro count, disfigure the common code base of the macros even more, bloat the documentation and most likely will not raise the learning curve for developers. I think, rather than introducing a new set of macros to adapt class hierarchies, this specific usecase may be covered in a convenient way using a composition of more primitive means. In particular the segmented sequences might come in handy. Any class hierarchy may be represented by a n-ary segmented fusion wrapper sequence. struct A{int x;}; struct B{int y;}; struct C : A,B{int z;}; BOOST_FUSION_ADAPT_STRUCT(A, (int,x)) BOOST_FUSION_ADAPT_STRUCT(B, (int,y)) BOOST_FUSION_ADAPT_STRUCT(C, (int,z)) struct adapted_C : fusion::tree<C&, A&, B&> { adapted_C(C& c) : fusion::tree<A&, B&, C&>(c,c,c){} }; int main() { C c;c.x=0;c.y=1;c.z=2; adapted_C adapted_c(c); std::cout << fusion::flatten(adapted_c) << std::endl; } To get native fusion support without a named wrapper, the tree-view may be constructed inplace whenever an intrinsic sequence operation is performed. Defining such functionality may be hidden behind a new macro. struct A{int x;}; struct B{int y;}; struct C : A,B{int z;}; BOOST_FUSION_ADAPT_STRUCT(A, (int,x)) BOOST_FUSION_ADAPT_STRUCT(B, (int,y)) BOOST_FUSION_ADAPT_STRUCT_NAMED_NS(C, BOOST_PP_EMPTY(), C_adpt, (int,z)) typedef fusion::tree<C_adpt, A&, B&> tree_type; BOOST_FUSION_ADAPT_INPLACE( //type to adapt C, //type to construct *inplace* whenever an intrinsic //sequence operation is performed tree_type, //initialization expression, with obj being C&, the instance of //C fusion::repeat<3>(fusion::single_view<C&>(obj))) ) int main() { C c;c.x=0;c.y=1;c.z=2; std::cout << fusion::flatten(c) << std::endl; } BOOST_FUSION_ADAPT_INPLACE is simple to implement - and it is just one new, independent macro. If compiled using a recent optimizing compiler, there will not be any runtime overhead at all. Unfortunately the segmented sequences are undocumented and pretty much broken at the moment. I will definitely work on them once I have time again. I think, whenever compile-time is not mandatory, new facilities should be aligned to the functional fundamental of Fusion that is: providing independent, primitive means that can be used to compose new, more expressive means. Does that make sense? -Christopher