$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: [boost] [TypeErasure] Composing Concepts & some notes
From: Fabio Fracassi (f.fracassi_at_[hidden])
Date: 2012-07-19 18:35:46
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