[TypeErasure] Composing Concepts & some notes

Hi Steven, I am going through the documentation and simultaneously try out some things that weren't immediately obvious to me. When I came to the paragraph about composing concepts the last sentence "We can even specialize concept_interface for it." tripped me up. My thought was "but do I have to? and how do composed concepts interact with manually composed any's?" so I gave it a try: I used your push_back concept and defined a size concept like this: template<class C> struct size { static size_t apply(C& cont) { return cont.size(); } }; namespace boost { namespace type_erasure { template<class C, class Base> struct concept_interface< ::size<C>, Base, C> : Base { size_t size() { return call(::size<C>(), *this); } }; } } which works fine: std::vector<int> vec; typedef any<push_back<_self, int>, _self&> any_push_back; any_push_back pb(vec); pb.push_back(10); pb.push_back(2); typedef any<size<_self>, _self&> any_size; any_size s(vec); std::cout << "Size = " << s.size() << std::endl; Now I wanted to try composition first manually: typedef any< mpl::vector< push_back<_self, int>, size<_self> >, _self& > any_manual_vecconcept; any_manual_vecconcept alvec(vec); alvec.push_back(13); alvec.push_back(11); std::cout << "Size = " << alvec.size() << std::endl; and then via "named composition": template<class T, class C> struct vecconcept : mpl::vector< push_back<T, C>, size<T> > {}; typedef any<vecconcept<_self, int>, _self&> any_vecconcept; any_vecconcept acvec(vec); acvec.push_back(15); acvec.push_back(17); std::cout << "Size = " << acvec.size() << std::endl; great everything works as expected, and no, I did not have to define a concept_interface for the composite interface. Now the first question is why would I want to? now the main reason for the exercise was how do these interact with each other and while I am at it how do they interact with the concepts they are composed of? Well I can freely interact as I hoped: any_vecconcept acvec2(alvec); any_manual_vecconcept alvec2(acvec); any_push_back pb3(alvec); any_push_back pb4(acvec); any_size s2(alvec); any_size s3(acvec); This is great! I might have missed it in the documentation, but I think this is really an important feature that deserves special mention. Now I gather that there is no way to do the opposite, something along the lines of any_vecconcept acvec3 = dynamic_any_cast<any_vecconcept>(s3); Well over the next days I will dive a bit deeper into the internals to see if implementing such a feature would be feasible. (because I need it before I could replace my current solution with type erasure) Steven, let me finish by saying thank you for the great work. regards Fabio

AMDG On 07/19/2012 03:35 PM, Fabio Fracassi wrote:
Hi Steven,
I am going through the documentation and simultaneously try out some things that weren't immediately obvious to me. When I came to the paragraph about composing concepts the last sentence "We can even specialize concept_interface for it." tripped me up. My thought was "but do I have to?
No. It is only needed if you want to add extra functionality in the composite concept.
and how do composed concepts interact with manually composed any's?" so I gave it a try:
<snip>
great everything works as expected, and no, I did not have to define a concept_interface for the composite interface. Now the first question is why would I want to?
Take a look at the iterator concepts. forward_iterator is a composite of several operators. The specialization of concept_interface adds typedef std::forward_iterator_tag iterator_category;
now the main reason for the exercise was how do these interact with each other and while I am at it how do they interact with the concepts they are composed of? Well I can freely interact as I hoped:
any_vecconcept acvec2(alvec); any_manual_vecconcept alvec2(acvec);
any_push_back pb3(alvec); any_push_back pb4(acvec);
any_size s2(alvec); any_size s3(acvec);
This is great! I might have missed it in the documentation, but I think this is really an important feature that deserves special mention.
It is documented in the reference. I agree that conversions deserve a separate section. (There is a subsection of Design Notes detailing the different constructors)
Now I gather that there is no way to do the opposite, something along the lines of any_vecconcept acvec3 = dynamic_any_cast<any_vecconcept>(s3); Well over the next days I will dive a bit deeper into the internals to see if implementing such a feature would be feasible. (because I need it before I could replace my current solution with type erasure)
It's possible in principle, but it would require extra global tables, some extensions to the binding interface, and some kind of registration mechanism. In Christ, Steven Watanabe

On 7/20/12 1:02 AM, Steven Watanabe wrote:
AMDG
On 07/19/2012 03:35 PM, Fabio Fracassi wrote:
I did not have to define a concept_interface for the composite interface. Now the first question is why would I want to?
Take a look at the iterator concepts. forward_iterator is a composite of several operators. The specialization of concept_interface adds typedef std::forward_iterator_tag iterator_category;
This is the kind of information is exactly what should be added to the docu (close to the compositing example)
It is documented in the reference. I agree that conversions deserve a separate section. (There is a subsection of Design Notes detailing the different constructors)
Only speaking for myself, but the most important section in any documentation (pun not intended but gladly taken :D) is the tutorial section. I hardly ever use reference docu, because it is only useful to find out that last detail in a library you are already proficient in. The tutorial is the advertising and beginners section, which tells me what the library can do for me and how it does so. Also most reference docus only show me the dots and leave connecting to me, which can still be difficult if you don't know what the picture is supposed to look like. The best documentations I have seen have a "mini tutorial" for each class (and sometimes even each member) in their reference section. It shows a minimal, compilable, useful example on how the given entity is used.
Now I gather that there is no way to do the opposite, something along the lines of any_vecconcept acvec3 = dynamic_any_cast<any_vecconcept>(s3); Well over the next days I will dive a bit deeper into the internals to see if implementing such a feature would be feasible. (because I need it before I could replace my current solution with type erasure)
It's possible in principle, but it would require extra global tables, some extensions to the binding interface, and some kind of registration mechanism.
Yes, I do understand this, and this is basically what I have in place, so I have to see what extensions to the binding interface it would take and If such an extension (or hooks for it) could be added to your library. I'll dive into this today. regards Fabio
participants (2)
-
Fabio Fracassi
-
Steven Watanabe