Quantcast

RFC: type erasure

classic Classic list List threaded Threaded
23 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RFC: type erasure

Steven Watanabe-4
AMDG

Over the last few months I've re-done my
type erasure library from scratch, fixing
a lot of the bad design decisions I made
originally.  Here's a basic sample of what
you can do with it:

simulate boost::any:

type_erasure::any<
  mpl::vector<copy_constructible<>, typeid_<> > >
x(10);

simulate boost::function<void(int)>:

type_erasure::any<
   mpl::vector<copy_constructible<>, typeid_<>, callable<void(int)> > >
f(foo);

The code is available from the Vault:
http://tinyurl.com/3z9jcwp

The library is nearly complete.  I've included
pre-built html documentation in the zip.  Questions,
comments, and criticism are welcome.

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

signature.asc (501 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Matt Calabrese
On Sun, May 22, 2011 at 6:18 PM, Steven Watanabe <[hidden email]>wrote:
>
> The code is available from the Vault:
> http://tinyurl.com/3z9jcwp
>
> The library is nearly complete.  I've included
> pre-built html documentation in the zip.  Questions,
> comments, and criticism are welcome.


This sounds great, I'll try to check it out in the upcoming week.

--
-Matt Calabrese
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Steven Watanabe-4
AMDG

On 05/22/2011 03:58 PM, Matt Calabrese wrote:

> On Sun, May 22, 2011 at 6:18 PM, Steven Watanabe <[hidden email]>wrote:
>>
>> The code is available from the Vault:
>> http://tinyurl.com/3z9jcwp
>>
>> The library is nearly complete.  I've included
>> pre-built html documentation in the zip.  Questions,
>> comments, and criticism are welcome.
>
>
> This sounds great, I'll try to check it out in the upcoming week.
>
Thanks.  It would be awesome if we could integrate
this with your Generic library, so a single concept
definition is sufficient for both.  I think I can
arrange it so defining a concept only requires a
few forward declarations from my library.

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

signature.asc (501 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Matt Calabrese
On Sun, May 22, 2011 at 7:27 PM, Steven Watanabe <[hidden email]>wrote:

> Thanks.  It would be awesome if we could integrate
> this with your Generic library, so a single concept
> definition is sufficient for both.


Yeah, that would be amazing. I bet we could get something workable with
simple concepts in not too much time, though right now I have other
priorities for the library (I want to first get all of the concepts of N2914
working and tested). The complicated parts of applying type erasure here
that I can think of are with associated types -- for instance, a type-erased
container should probably automatically be working with type-erased
iterators, right? So handling things correctly implies my library figuring
out all of the constraints that affect an associated type in any way, which
could be tricky, as constraints can be scattered around the encapsulating
concept. While I can check the constraints fine, at a high level I don't
really know which constraints affect which types, whether directly or
indirectly, if you get what I'm saying. All I know is whether a given
constraint is satisfied or not, but it's difficult to determine exactly
which associated types are affected by which constraints since they can be
referenced in any kind of arbitrary type expression.

Anyway, this would be awesome to accomplish, especially if we could figure
out a way to handle the general case, though, at least at my end, it's a
ways off. I feel like Sean Parent talked a little bit about similar
functionality with Poly. I'll check it out and try to keep all of this
somewhere in my mind as I make further progress with the Generic library.

--
-Matt Calabrese
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Akira Takahashi
In reply to this post by Steven Watanabe-4
Hi, Steven.

This update is GREAT!
Up to now, I had used the following idiom for Type Erasure:
http://d.hatena.ne.jp/faith_and_brave/20110215/1297755842

It is easy to use this library than my idiom.

2011/5/23 Steven Watanabe <[hidden email]>:
>
> Over the last few months I've re-done my
> type erasure library from scratch, fixing
> a lot of the bad design decisions I made
> originally.  Here's a basic sample of what
> you can do with it:
>

>>========================

Akira Takahashi
mailto:[hidden email]
blog : http://d.hatena.ne.jp/faith_and_brave/
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Steven Watanabe-4
In reply to this post by Matt Calabrese
AMDG

On 05/22/2011 04:58 PM, Matt Calabrese wrote:

> On Sun, May 22, 2011 at 7:27 PM, Steven Watanabe <[hidden email]>wrote:
>
>> Thanks.  It would be awesome if we could integrate
>> this with your Generic library, so a single concept
>> definition is sufficient for both.
>
>
> Yeah, that would be amazing. I bet we could get something workable with
> simple concepts in not too much time, though right now I have other
> priorities for the library (I want to first get all of the concepts of N2914
> working and tested). The complicated parts of applying type erasure here
> that I can think of are with associated types -- for instance, a type-erased
> container should probably automatically be working with type-erased
> iterators, right? So handling things correctly implies my library figuring
> out all of the constraints that affect an associated type in any way, which
> could be tricky, as constraints can be scattered around the encapsulating
> concept. While I can check the constraints fine, at a high level I don't
> really know which constraints affect which types, whether directly or
> indirectly, if you get what I'm saying.
Yeah.  I don't really have a good way to
handle associated types at all.  I suspect
that the way I'm using placeholders will
interact badly with associated types in your
macros.

> All I know is whether a given
> constraint is satisfied or not, but it's difficult to determine exactly
> which associated types are affected by which constraints since they can be
> referenced in any kind of arbitrary type expression.
>

If the constraint is of the form SomeConcept<A, B, C>,
I can use placeholders for the arguments, and pick it
apart with TMP.

> Anyway, this would be awesome to accomplish, especially if we could figure
> out a way to handle the general case, though, at least at my end, it's a
> ways off. I feel like Sean Parent talked a little bit about similar
> functionality with Poly. I'll check it out and try to keep all of this
> somewhere in my mind as I make further progress with the Generic library.
>

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

signature.asc (501 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Matt Calabrese
On Sun, May 22, 2011 at 8:32 PM, Steven Watanabe <[hidden email]>wrote:

> If the constraint is of the form SomeConcept<A, B, C>,
> I can use placeholders for the arguments, and pick it
> apart with TMP.


True. We should probably even be able to handle more complicated situations
such as

requires SomeConcept< OtherConcept< A >::value_type >;

if I make my concepts themselves aware of the placeholders and define their
associated types accordingly when those placeholders are used, though I
haven't given much thought to it yet.

--
-Matt Calabrese
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Vicente Botet
In reply to this post by Steven Watanabe-4
Steven Watanabe-4 wrote
AMDG

Over the last few months I've re-done my
type erasure library from scratch, fixing
a lot of the bad design decisions I made
originally.  Here's a basic sample of what
you can do with it:

simulate boost::any:

type_erasure::any<
  mpl::vector<copy_constructible<>, typeid_<> > >
x(10);

simulate boost::function<void(int)>:

type_erasure::any<
   mpl::vector<copy_constructible<>, typeid_<>, callable<void(int)> > >
f(foo);

The code is available from the Vault:
http://tinyurl.com/3z9jcwp

The library is nearly complete.  I've included
pre-built html documentation in the zip.  Questions,
comments, and criticism are welcome.

Hi,

I've just taken a diagonal read at the documentation and the library seems really promising.

I like how concepts are materialized using a template class that implements the default behavior of the concept and that can be specialized to map type to concepts. I understand that you need a second step to introduce the functions themselves specializing concept_interface.

What I don't understand is the overloading issues. Could you use a concrete example to try to clarify the problems you have addressed?

I would try to study more deeply your design in order to see the advantage it could provide to my library. While developing Boost.Opaque (available on the sandbox https://svn.boost.org/svn/boost/sandbox/opaque/libs/opaque/doc/html/index.html), I was confronted to a similar problem, that is,  how to add in a declarative way, more operations to the underlying class.  I have reached to manage with this using what I have called a meta-mixin.

A MetaMixin is a meta-function having as nested type a Mixin. The archetype of a MetaMixin is

struct MetaMixinArchetype {
    template (*typename Final, typename Base*)
    struct type : Base
    {
        ...
    };
};

Metamixins are is a similar way to your concepts, passing them in a mpl-sequence.

I will appreciate a lot if you can take a look and comment the design of Boost.Opaque.

Best,
Vicente
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Mathias Gaunard-2
In reply to this post by Steven Watanabe-4
On 23/05/2011 00:18, Steven Watanabe wrote:

> Over the last few months I've re-done my
> type erasure library from scratch, fixing
> a lot of the bad design decisions I made
> originally.  Here's a basic sample of what
> you can do with it:
>
> simulate boost::any:
>
> type_erasure::any<
>    mpl::vector<copy_constructible<>, typeid_<>  >  >
> x(10);
>
> simulate boost::function<void(int)>:
>
> type_erasure::any<
>     mpl::vector<copy_constructible<>, typeid_<>, callable<void(int)>  >  >
> f(foo);
>
> The code is available from the Vault:
> http://tinyurl.com/3z9jcwp
>
> The library is nearly complete.  I've included
> pre-built html documentation in the zip.  Questions,
> comments, and criticism are welcome.


How does it compare to Adobe.Poly?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Steven Watanabe-4
In reply to this post by Vicente Botet
AMDG

On 05/23/2011 02:34 PM, Vicente Botet wrote:
>
> I like how concepts are materialized using a template class that implements
> the default behavior of the concept and that can be specialized to map type
> to concepts. I understand that you need a second step to introduce the
> functions themselves specializing concept_interface.
>
> What I don't understand is the overloading issues. Could you use a concrete
> example to try to clarify the problems you have addressed?
>

Okay.  Problem 1: Name hiding for member functions.

typedef mpl::vector<
    callable<int(int)>,
    callable<double(double)>
> test_concept;

If we just use the basic definition of
concept_interface, the second overload
will hide the first since the inheritance
structure looks like:

struct callable1 {
    int operator()(int);
};

struct callable2 : callable1 {
    double operator()(double);
};

For free functions, I had a problem akin to name
hiding when I defined a single namespace scope
overload with concept_interface arguments.  Using
an inline friend function that takes the derived
type works with some care to avoid duplicate
definitions.

You can check the tests for details on what I expect
to work.  Most of the tests for specific concepts
have a test_overload test case.

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

signature.asc (501 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Steven Watanabe-4
In reply to this post by Mathias Gaunard-2
AMDG

On 05/23/2011 02:57 PM, Mathias Gaunard wrote:
> How does it compare to Adobe.Poly?
>

I'm not very familiar with Adobe.Poly, but from
a quick glance, the biggest differences are

a) My library is based on composing independent
   primitives.  Poly seems to be designed for
   a straight linear hierarchy.

b) I can capture constraints that affect multiple
   types.  There's an example of this in
   print_sequence.cpp.  I don't think Poly
   could handle this at all.

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

signature.asc (501 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Steven Watanabe-4
In reply to this post by Vicente Botet
AMDG

On 05/23/2011 02:34 PM, Vicente Botet wrote:

> I would try to study more deeply your design in order to see the advantage
> it could provide to my library. While developing Boost.Opaque (available on
> the sandbox
> https://svn.boost.org/svn/boost/sandbox/opaque/libs/opaque/doc/html/index.html),
> I was confronted to a similar problem, that is,  how to add in a declarative
> way, more operations to the underlying class.  I have reached to manage with
> this using what I have called a meta-mixin.
>
> A MetaMixin is a meta-function having as nested type a Mixin. The archetype
> of a MetaMixin is
>
> struct MetaMixinArchetype {
>     template (*typename Final, typename Base*)
>     struct type : Base
>     {
>         ...
>     };
> };
>
> Metamixins are is a similar way to your concepts, passing them in a
> mpl-sequence.
>
> I will appreciate a lot if you can take a look and comment the design of
> Boost.Opaque.
>
It looks like your MetaMixin is pretty much
equivalent to what I did with concept_interface.
For what you're trying to do, I don't see that it
can really be improved much.

I'd say that for the most part, you're better
off without the extra complexity in my design.
I have to generate both the interface and the
dispatching code from a single specification.
You only need to define forwarding functions.

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

signature.asc (501 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Vicente Botet
Steven Watanabe-4 wrote
AMDG

On 05/23/2011 02:34 PM, Vicente Botet wrote:
> I would try to study more deeply your design in order to see the advantage
> it could provide to my library. While developing Boost.Opaque (available on
> the sandbox
> https://svn.boost.org/svn/boost/sandbox/opaque/libs/opaque/doc/html/index.html),
> I was confronted to a similar problem, that is,  how to add in a declarative
> way, more operations to the underlying class.  I have reached to manage with
> this using what I have called a meta-mixin.
>
> A MetaMixin is a meta-function having as nested type a Mixin. The archetype
> of a MetaMixin is
>
> struct MetaMixinArchetype {
>     template (*typename Final, typename Base*)
>     struct type : Base
>     {
>         ...
>     };
> };
>
> Metamixins are is a similar way to your concepts, passing them in a
> mpl-sequence.
>
> I will appreciate a lot if you can take a look and comment the design of
> Boost.Opaque.
>

It looks like your MetaMixin is pretty much
equivalent to what I did with concept_interface.
For what you're trying to do, I don't see that it
can really be improved much.
Thanks for your advice.

I'd say that for the most part, you're better
off without the extra complexity in my design.
I have to generate both the interface and the
dispatching code from a single specification.
You only need to define forwarding functions.
Why do you needed to generate the interface and forwarding the call separately?
Is because you want in addition to be able to emulate concept maps?
Aren't type-erasure and concepts orthogonal?

What I mean is that your library is doing concept-erasure and that trying to solve just  type-erasure could maybe be simpler.

I'm wondering if type_erasure had a MPL sequence of something like my meta-mixins, the meta-mixing could always forward the call to a concept adapter if what we want is concept erasure.

Please note that I don't understand yet the whole design of Boost.TypeErasure.

Best,
Vicente
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Vicente Botet
In reply to this post by Steven Watanabe-4
Steven Watanabe-4 wrote
AMDG

On 05/23/2011 02:34 PM, Vicente Botet wrote:
>
> I like how concepts are materialized using a template class that implements
> the default behavior of the concept and that can be specialized to map type
> to concepts. I understand that you need a second step to introduce the
> functions themselves specializing concept_interface.
>
> What I don't understand is the overloading issues. Could you use a concrete
> example to try to clarify the problems you have addressed?
>

Okay.  Problem 1: Name hiding for member functions.

typedef mpl::vector<
    callable<int(int)>,
    callable<double(double)>
> test_concept;

If we just use the basic definition of
concept_interface, the second overload
will hide the first since the inheritance
structure looks like:

struct callable1 {
    int operator()(int);
};

struct callable2 : callable1 {
    double operator()(double);
};
I find this normal and expected behavior, so I don't see yet why do you need to avoid this hiding.

I don't understand the use case of the example: when a using declaration will be needed?

For free functions, I had a problem akin to name
hiding when I defined a single namespace scope
overload with concept_interface arguments.  Using
an inline friend function that takes the derived
type works with some care to avoid duplicate
definitions.
I'm sorry but I don't reach to see what is the real problem. I guess it is because I don't see the need of introducing the using sentence. Please could you present a real concrete case of overloading free functions that needs two different specializations of concept interface?

You can check the tests for details on what I expect
to work.  Most of the tests for specific concepts
have a test_overload test case.
I've read some of them. I guess I understand what you expect to work, but I don't see why you need to specialize twice the concept_interface class for the same concept.

Best,
Vicente
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Steven Watanabe-4
AMDG

On 05/24/2011 02:07 PM, Vicente Botet wrote:

>
> Steven Watanabe-4 wrote:
>> On 05/23/2011 02:34 PM, Vicente Botet wrote:
>>>
>>> I like how concepts are materialized using a template class that
>>> implements
>>> the default behavior of the concept and that can be specialized to map
>>> type
>>> to concepts. I understand that you need a second step to introduce the
>>> functions themselves specializing concept_interface.
>>>
>>> What I don't understand is the overloading issues. Could you use a
>>> concrete
>>> example to try to clarify the problems you have addressed?
>>>
>>
>> Okay.  Problem 1: Name hiding for member functions.
>>
>> typedef mpl::vector<
>>     callable&lt;int(int)&gt;,
>>     callable&lt;double(double)&gt;
>>> test_concept;
>>
>> If we just use the basic definition of
>> concept_interface, the second overload
>> will hide the first since the inheritance
>> structure looks like:
>>
>> struct callable1 {
>>     int operator()(int);
>> };
>>
>> struct callable2 : callable1 {
>>     double operator()(double);
>> };
>>
>
> I find this normal and expected behavior, so I don't see yet why do you need
> to avoid this hiding.
>
It's normal in the sense that it's what C++
does by default.  I don't see how it can possibly
be the expected behavior that:

struct func {
    template<class T>
    T operator()(T t) { return t; }
};

typedef mpl::vector<
    callable<int(int)>,
    callable<double(double)>
> test_concept;

func f1;
any<test_concept> f(f1);
f(1); // calls func::operator()<double>??

From the point of view of someone trying to
use the library, the two instances of callable
are equal.  Having one hide the other is surprising.

> I don't understand the use case of the example: when a using declaration
> will be needed?
>

I can't parse this sentence.

>> For free functions, I had a problem akin to name
>> hiding when I defined a single namespace scope
>> overload with concept_interface arguments.  Using
>> an inline friend function that takes the derived
>> type works with some care to avoid duplicate
>> definitions.
>>
>
> I'm sorry but I don't reach to see what is the real problem. I guess it is
> because I don't see the need of introducing the using sentence. Please could
> you present a real concrete case of overloading free functions that needs
> two different specializations of concept interface?
>
Consider operator+.  Either the first argument
or the second argument or both may be a
type_erasure::any.  I need two specializations,
because there are two arguments.  To use
friend function defined inline I have to
inject operator+ into exactly one of the
arguments.

I originally tried to handle free functions with
namespace scope overloads like this:

template<class Base, class T, class U, class R>
typename rebind_any<Base, R>::type
operator+(
  const concept_interface<addable<T, U, R>, Base, T>&, const U&);

template<class Base, class T, class U, class R>
typename rebind_any<Base, R>::type
operator+(
  const T&, const concept_interface<addable<T, U, R>, Base, U>&);

template<class Base1, class Base2, class T, class U, class R>
typename rebind_any<Base, R>::type
operator+(
  const concept_interface<addable<T, U, R>, Base1, T>&,
  const concept_interface<addable<T, U, R>, Base2, U>&);

Unfortunately, this failed with the example
print_sequence.cpp, because of
ostreamable<_os, const char*>, ostreamable<_os, _t>
Only one of these was being considered
for overload resolution.

>>> You can check the tests for details on what I expect
>>> to work.  Most of the tests for specific concepts
>>> have a test_overload test case.
>>>
>>>
> I've read some of them. I guess I understand what you expect to work, but I
> don't see why you need to specialize twice the concept_interface class for
> the same concept.

I couldn't get all the tests to pass with any other
solution I tried.  If you have a simpler way to
specialize concept_interface for ostreamable or
callable that passes all my tests I'd love to
hear about it, but I've tried and this is the
best I could come up with.

To summarize the reasons for multiple specializations:
- For member functions, the second and subsequent instances
  of a concept need to be treated differently from
  the first, because they need an extra using declaration
  (which would be ill-formed in the first occurrence).
- For non-member functions, one specialization is needed
  for each argument that can be a type_erasure::any to
  make sure that the function gets added to the overload
  set regardless of what subset of the arguments is erased.

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

signature.asc (501 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Giovanni Piero Deretta
In reply to this post by Steven Watanabe-4
On Mon, May 23, 2011 at 11:01 PM, Steven Watanabe <[hidden email]> wrote:

>
> Okay.  Problem 1: Name hiding for member functions.
>
> typedef mpl::vector<
>    callable<int(int)>,
>    callable<double(double)>
>> test_concept;
>
> If we just use the basic definition of
> concept_interface, the second overload
> will hide the first since the inheritance
> structure looks like:
>
> struct callable1 {
>    int operator()(int);
> };
>
> struct callable2 : callable1 {
>    double operator()(double);
> };
>

This can be solved by an "using callable1::operator();" . I just had
to solve a very similar problem 20 minutes ago, but in my case all the
elements in the inheritance chains only had operator() in need of
un-hiding.

I guess the problem in your case is that in general your callable2 is
not necessarily inheriting from something that is callable, that is,
you are using operator() as the name but it could be anything. A
solution is adding every possible name (but with special arguments so
that they won't actually partecipate in overload resolution) in the
most base class and adding an "using <every possible name> at every
level of the inheritance:


struct base {
   struct dont_call_me{}
    void operator()(dont_call_me);
    void operator+(dont_call_me);
    void construct(dont_call_me);
}

struct negable : base {
     using base::operator();
     using base::operator+;
     using base::construct;

    void operator-(); // can't be overloaded so no risk of hiding
}

struct addable : negable {
     using negable::operator();
     using negable::operator+;
     using negable::construct;

     whatever operator+(whatever);
};

struct callable2 : addable {
     using addable::operator();
     using addable::operator+;
     using addable::construct;
     whatever operator()(whatever);
};

struct callable1 : callable2 {
     using callable2::operator();
     using callable2::operator+;
     using callable2::construct;
     whateverelse operator()(whateverelse);

}

struct constructible : callable2 {
     using callable2::operator();
     using callable2::operator+;
     using callable2::construct;


     void construct(args..)

     template<class ...T>
     constructible(T... args) { construct(args...); } // calls this
construct or any in the base classes
}

Probably it will break in some cases I'm not foreseeing. Will
definitely not work for user specified foo-able.

HTH,

--
gpd
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Steven Watanabe-4
AMDG

On 05/24/2011 04:39 PM, Giovanni Piero Deretta wrote:

> On Mon, May 23, 2011 at 11:01 PM, Steven Watanabe <[hidden email]> wrote:
>> struct callable1 {
>>    int operator()(int);
>> };
>>
>> struct callable2 : callable1 {
>>    double operator()(double);
>> };
>>
>
> This can be solved by an "using callable1::operator();" . I just had
> to solve a very similar problem 20 minutes ago, but in my case all the
> elements in the inheritance chains only had operator() in need of
> un-hiding.
>
> I guess the problem in your case is that in general your callable2 is
> not necessarily inheriting from something that is callable, that is,
> you are using operator() as the name but it could be anything.
Exactly.

> A
> solution is adding every possible name (but with special arguments so
> that they won't actually partecipate in overload resolution) in the
> most base class and adding an "using <every possible name> at every
> level of the inheritance:
>

I've used this solution in the past.  Now, I think
it's better to detect the second and subsequent
instances and add a using declaration.  The advantage
is that there are no extra overloads, so &any<...>::operator()
is unambiguous if there's only a single overload.

> Probably it will break in some cases I'm not foreseeing. Will
> definitely not work for user specified foo-able.
>

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

signature.asc (501 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Vicente Botet
In reply to this post by Steven Watanabe-4
Steven Watanabe-4 wrote
AMDG

On 05/24/2011 02:07 PM, Vicente Botet wrote:
>
> Steven Watanabe-4 wrote:
>> On 05/23/2011 02:34 PM, Vicente Botet wrote:
>>>
>>> I like how concepts are materialized using a template class that
>>> implements
>>> the default behavior of the concept and that can be specialized to map
>>> type
>>> to concepts. I understand that you need a second step to introduce the
>>> functions themselves specializing concept_interface.
>>>
>>> What I don't understand is the overloading issues. Could you use a
>>> concrete
>>> example to try to clarify the problems you have addressed?
>>>
>>
>> Okay.  Problem 1: Name hiding for member functions.
>>
>> typedef mpl::vector<
>>     callable<int(int)>,
>>     callable<double(double)>
>>> test_concept;
>>
>> If we just use the basic definition of
>> concept_interface, the second overload
>> will hide the first since the inheritance
>> structure looks like:
>>
>> struct callable1 {
>>     int operator()(int);
>> };
>>
>> struct callable2 : callable1 {
>>     double operator()(double);
>> };
>>
>
> I find this normal and expected behavior, so I don't see yet why do you need
> to avoid this hiding.
>

It's normal in the sense that it's what C++
does by default.  I don't see how it can possibly
be the expected behavior that:

struct func {
    template<class T>
    T operator()(T t) { return t; }
};

typedef mpl::vector<
    callable<int(int)>,
    callable<double(double)>
> test_concept;

func f1;
any<test_concept> f(f1);
f(1); // calls func::operator()<double>??

From the point of view of someone trying to
use the library, the two instances of callable
are equal.  Having one hide the other is surprising.
 I understand it now. It seems that I have forgotten this case on Boost.Opaque.
Many many thanks.

>> For free functions, I had a problem akin to name
>> hiding when I defined a single namespace scope
>> overload with concept_interface arguments.  Using
>> an inline friend function that takes the derived
>> type works with some care to avoid duplicate
>> definitions.
>>
>
> I'm sorry but I don't reach to see what is the real problem. I guess it is
> because I don't see the need of introducing the using sentence. Please could
> you present a real concrete case of overloading free functions that needs
> two different specializations of concept interface?
>

Consider operator+.  Either the first argument
or the second argument or both may be a
type_erasure::any.  I need two specializations,
because there are two arguments.  To use
friend function defined inline I have to
inject operator+ into exactly one of the
arguments.
I don't see if I understood it now. I suspect that you mean that either the first argument
or the second argument or both may be a placeholder, isn't it?


I originally tried to handle free functions with
namespace scope overloads like this:

...

Unfortunately, this failed with the example
print_sequence.cpp, because of
ostreamable<_os, const char*>, ostreamable<_os, _t>
Only one of these was being considered
for overload resolution.

>>> You can check the tests for details on what I expect
>>> to work.  Most of the tests for specific concepts
>>> have a test_overload test case.
>>>
>>>
> I've read some of them. I guess I understand what you expect to work, but I
> don't see why you need to specialize twice the concept_interface class for
> the same concept.

I couldn't get all the tests to pass with any other
solution I tried.  If you have a simpler way to
specialize concept_interface for ostreamable or
callable that passes all my tests I'd love to
hear about it, but I've tried and this is the
best I could come up with.


I'm just trying to understand what kind of problems you have addressed to see if I can have the same in Boost.Opaque.


To summarize the reasons for multiple specializations:
- For member functions, the second and subsequent instances
  of a concept need to be treated differently from
  the first, because they need an extra using declaration
  (which would be ill-formed in the first occurrence).
- For non-member functions, one specialization is needed
  for each argument that can be a type_erasure::any to
  make sure that the function gets added to the overload
  set regardless of what subset of the arguments is erased.


Thanks again for the clearer explanations.

Best,
Vicente
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

fpelliccioni
In reply to this post by Steven Watanabe-4
On Sun, May 22, 2011 at 7:18 PM, Steven Watanabe <[hidden email]>wrote:

> AMDG
>
> Over the last few months I've re-done my
> type erasure library from scratch, fixing
> a lot of the bad design decisions I made
> originally.  Here's a basic sample of what
> you can do with it:
>
> simulate boost::any:
>
> type_erasure::any<
>  mpl::vector<copy_constructible<>, typeid_<> > >
> x(10);
>
> simulate boost::function<void(int)>:
>
> type_erasure::any<
>   mpl::vector<copy_constructible<>, typeid_<>, callable<void(int)> > >
> f(foo);
>
> The code is available from the Vault:
> http://tinyurl.com/3z9jcwp
>
>
Hi Steven,

The link is broken.
I want to test your library, is there somewhere else where I can download
it?

Regards,
Fernando.
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RFC: type erasure

Steven Watanabe-4
AMDG

On 07/20/2011 05:49 AM, Fernando Pelliccioni wrote:

> On Sun, May 22, 2011 at 7:18 PM, Steven Watanabe <[hidden email]>wrote:
>
>> The code is available from the Vault:
>> http://tinyurl.com/3z9jcwp
>>
>>
> The link is broken.
> I want to test your library, is there somewhere else where I can download
> it?
>
The vault no longer exists.  All the existing
content has been moved to github.  You can
get the file from:
https://github.com/boost-vault/Miscellaneous

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

signature.asc (501 bytes) Download Attachment
12
Loading...