Boost logo

Boost :

Subject: Re: [boost] [type_erasure] Review started (July 18-27, 2012)
From: Fabio Fracassi (f.fracassi_at_[hidden])
Date: 2012-07-30 02:30:50

On 7/30/12 2:27 AM, Steven Watanabe wrote:
> If you have an abstract base for your legacy interface,
> you can do this:
> template<class T = _self>
> struct legacy_concept : mpl::vector<...> {};
> namespace boost { namespace type_erasure {
> template<class T, class Base>
> struct concept_interface<legacy_concept<T>, Base, T>
> : Base, legacy_base {
> // implement legacy_base methods
> };
> }}
> Now any<legacy_concept<> > is derived from legacy_base.
> Of course, once you've written all this out, you don't
> gain much over just using:
> template<class T>
> struct legacy_adapter : legacy_base {
> // constructors and forwarding
> T impl_;
> };
> which is probably easier to understand.
> The only thing you gain is the ability
> to compose with other concepts.

Which is a quite significant win imo.

>> b.2. I cannot define a concept that has more than one function directly,
>> i.e. I have to define concepts for push_back and size and then compose
>> them (in this case 35 lines of code). This is of course mainly an issue
>> of syntactic sugar, but in Stevens concept definition boiler plate and
>> interface information (member name, arguments, composition lists) are
>> intermixed.
>> I seem to recall that there was some discussion about having some macros
>> to simplify the boilerplate. I think something along the lines of
>> BOOST_CREATE_CONCEPT(container_concept, typename T,
>> (void (push_back, T),
>> void (size))
>> )
>> wouldn't be too bad.
> I rather dislike complex macros like this.

I am non to fond of them either. In this case though it makes the code
much cleaner, consider a syntax like above or similar (haven't checked
whether this is even possible, my PP foo is not to good) to this:

BOOST_CREATE_CONCEPT(push_back, typename T,
      MEMBER push_back (void (T))

concisely gives you all the information (concept name, member func name
and signature) a user of this concept needs. In contrast to spelling it out

template<class C, class T> // < Part I of the signature
struct push_back { // < Concept name here
    static void apply(C& cont, const T& arg) { cont.push_back(arg); }
        // the rest of the signature is hidden somewhere in the apply
         // but never explicitly spelled out

namespace boost {
    namespace type_erasure {

       // lots of duplicated information and unrelated details to
       // (mis)understand and get wrong
       template<class C, class T, class Base>
       struct concept_interface< ::push_back<C, T>, Base, C> : Base {
          void push_back(typename rebind_any<Base, const T&>::type arg)
             call(::push_back<C, T>(), *this, arg);

Writing this is not to onerous, but (quickly) reading code that uses it ...



Boost list run by bdawes at, gregod at, cpdaniel at, john at