boost::factory?

View: New views
19 Messages — Rating Filter:   Alert me  

boost::factory?

by Tobias Schwinger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dear Boost community,

do we have a function object template to wrap arbitrary constructor
calls / operator new expressions somewhere in Boost, already?

If not, is there any interest in such a thing?

Interface draft:
================

     factory<T>     // constructs X and returns it by value
     factory<T*>    // uses operator new, returns a pointer


Where operator() takes a variable number of arguments, forwarded to the
constructor.

Should there be an optional 'Allocator' template parameter?


Some use cases:
===============


o Transform through an explicit constructor, e.g:

     std::transform(from,to,out,factory<X>());

or a constructor that takes more than one argument, e.g:

     std::transform(from,to,out,
         boost::bind(factory<Y>(),12,_1));

o Generate data, e.g:

     std::generate_n(out,12,boost::bind(factory<Y>(),123,12));


o Creating homogeneous, polymorphic factories from heterogeneous
constructors, e.g:

     void register_factory( std::type_info const &,
         boost::function<void*()> const &);

     // ... at function scope:

     register_factory( typeid(X), factory<X>() );
     register_factory( typeid(Y), boost::bind(factory<Y>(),12,1) );


Implementation notes regarding the Forwarding Problem:
======================================================

For now (C++89) it might be good enough to just have operator() take its
arguments by non-const reference. As usually the call will be deferred
and as long as the arguments are L-Values they will be deduced even if
const qualified (this might break the code of the first use case above -
wrapping the factory specialization into a Boost.Bind function object
without actually binding anything will work around the problem, though).

Alternatively we could solve the forwarding problem (within the function
object itself) using a "hammer and crowbar utility" in Fusion
(overloading operator() with all combinations of templatized
const/non-const reference parameters) until we have better means to do
so. I personally prefer the former because it's more lightweight and
might allow us to be more portable than Fusion is, however.


Curiously awaiting your feedback,
Tobias


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

Re: boost::factory?

by Glyn Matthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Tobias,

On 17/06/07, Tobias Schwinger <tschwinger@...> wrote:
>
> Dear Boost community,
>
> do we have a function object template to wrap arbitrary constructor
> calls / operator new expressions somewhere in Boost, already?
>
> If not, is there any interest in such a thing?


Normally when I need a generic Factory facility, I turn to the Loki
library.  However, some of the use cases that you describe aren't really
possible with this, so I'd say yes, I'd be interested.

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

Re: boost::factory?

by Joel de Guzman-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Tobias Schwinger wrote:

[1]

> For now (C++89) it might be good enough to just have operator() take its
> arguments by non-const reference. As usually the call will be deferred
> and as long as the arguments are L-Values they will be deduced even if
> const qualified (this might break the code of the first use case above -
> wrapping the factory specialization into a Boost.Bind function object
> without actually binding anything will work around the problem, though).

[2]

> Alternatively we could solve the forwarding problem (within the function
> object itself) using a "hammer and crowbar utility" in Fusion
> (overloading operator() with all combinations of templatized
> const/non-const reference parameters) until we have better means to do
> so. I personally prefer the former because it's more lightweight and
> might allow us to be more portable than Fusion is, however.

Have [2] for a predefined limit (say 3) and do the rest [1] for
more (e.g. 3 or more). Isn't that how you did it with the
fusion functional stuff?

Anyway, yeah, I need such a utility, especially if it is lighweight.

Regards,
--
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

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

Re: boost::factory?

by Mathias Gaunard :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Tobias Schwinger wrote:
> Dear Boost community,
>
> do we have a function object template to wrap arbitrary constructor
> calls / operator new expressions somewhere in Boost, already?

Yes, it's in_place.
Used by optional, for example.

For some reason though it seems there is no definition for default
constructors, but that can be added trivially.

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

Re: boost::factory?

by Tobias Schwinger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Joel,

Joel de Guzman wrote:

> Tobias Schwinger wrote:
>
> [1]
>
>> For now (C++89) it might be good enough to just have operator() take its
>> arguments by non-const reference. As usually the call will be deferred
>> and as long as the arguments are L-Values they will be deduced even if
>> const qualified (this might break the code of the first use case above -
>> wrapping the factory specialization into a Boost.Bind function object
>> without actually binding anything will work around the problem, though).
>
> [2]
>
>> Alternatively we could solve the forwarding problem (within the function
>> object itself) using a "hammer and crowbar utility" in Fusion
>> (overloading operator() with all combinations of templatized
>> const/non-const reference parameters) until we have better means to do
>> so. I personally prefer the former because it's more lightweight and
>> might allow us to be more portable than Fusion is, however.

...and avoids circular dependencies if placed outside of and used by Fusion.

>
> Have [2] for a predefined limit (say 3) and do the rest [1] for
> more (e.g. 3 or more).

The first two will probably do, since AFAIK both standard and Fusion
algorithms will be happy with it.

OTOH, once there's a single "L/R-Value overload", users will probably
request more of them for manual use (which could be an argument not to
add them in the first place).

> Isn't that how you did it with the
> fusion functional stuff?

Well, unintentionally - it was a bug, not a feature :-|. It has recently
  been fixed (upon Eric Niebler's report) and now there are overloads
for all combinations for (default-wise) 6 parameters, now.

> Anyway, yeah, I need such a utility, especially if it is lightweight.

Wonderful (what a coincidence)! In fact, the recent discussion of a
"fused_ctor" brought it up and the utility also fits nicely into the
"Fusion infinity puzzle" (to be continued). It seems misplaced in
Fusion, however, because it is generally useful without having anything
to do with tuples.

Ideally the idea or even the implementation (that is, I'd provide one if
there's interest) gets adopted by the utility suite of an existing
library (such as Bind) or integrated into an existing set of utilities
(e.g. In-Place - which would become Factory then).

Otherwise we'd have an "ultra fast track candidate" for boost/utility
which would live in Fusion until it finds a better home.


Regards,
Tobias


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

Re: boost::factory?

by Tobias Schwinger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Mathias Gaunard wrote:
> Tobias Schwinger wrote:
>> Dear Boost community,
>>
>> do we have a function object template to wrap arbitrary constructor
>> calls / operator new expressions somewhere in Boost, already?
>
> Yes, it's in_place.

Well, that's not quite the same: The in_place stuff deals with in-place
construction (hence the name), which is a different pair of shoes.


It's not applicable to the use cases outlined in my previous post, since
it doesn't (and probably wouldn't make sense to) provide a function
object interface (since it has to know the memory location where the
object should be constructed).


Regards,
Tobias

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

Re: boost::factory?

by Marcus Lindblom :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Tobias Schwinger wrote:
> Dear Boost community,
>
> do we have a function object template to wrap arbitrary constructor
> calls / operator new expressions somewhere in Boost, already?
>  
lambda::new_ptr ?

/Marcus

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

[lambda] Re: boost::factory?

by Tobias Schwinger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Marcus Lindblom wrote:
> Tobias Schwinger wrote:
>> Dear Boost community,
>>
>> do we have a function object template to wrap arbitrary constructor
>> calls / operator new expressions somewhere in Boost, already?
>>  
> lambda::new_ptr ?

Yep, 'new_ptr' and 'constructor' are almost exactly what I want.

Those templates are missing a 'result_type' typedef to become usable as
"stand-alone function objects" (outside of Boost.Lambda expressions).

Further, the limits are a bit too low for constructing Fusion Sequences
and having them configurable would be nice to have, too...

Thanks,
Tobias

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

Re: [lambda] Re: boost::factory?

by Eric Niebler :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Tobias Schwinger wrote:

> Marcus Lindblom wrote:
>> Tobias Schwinger wrote:
>>> Dear Boost community,
>>>
>>> do we have a function object template to wrap arbitrary constructor
>>> calls / operator new expressions somewhere in Boost, already?
>>>  
>> lambda::new_ptr ?
>
> Yep, 'new_ptr' and 'constructor' are almost exactly what I want.
>
> Those templates are missing a 'result_type' typedef to become usable as
> "stand-alone function objects" (outside of Boost.Lambda expressions).
>
> Further, the limits are a bit too low for constructing Fusion Sequences
> and having them configurable would be nice to have, too...

Yes and IMO these things should be called new_ and construct.

--
Eric Niebler
Boost Consulting
www.boost-consulting.com
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: boost::factory?

by David Abrahams :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


on Sun Jun 17 2007, Tobias Schwinger <tschwinger-AT-isonews2.com> wrote:

> Dear Boost community,
>
> do we have a function object template to wrap arbitrary constructor
> calls / operator new expressions somewhere in Boost, already?
>
> If not, is there any interest in such a thing?
>
> Interface draft:
> ================
>
>      factory<T>     // constructs X and returns it by value
>      factory<T*>    // uses operator new, returns a pointer

auto_ptr, please.

>
>
> Where operator() takes a variable number of arguments, forwarded to the
> constructor.


Isn't in-place construction the most general case?

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

The Astoria Seminar ==> http://www.astoriaseminar.com

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

Re: [lambda] Re: boost::factory?

by Tobias Schwinger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Eric Niebler wrote:

> Tobias Schwinger wrote:
>> Marcus Lindblom wrote:
>>> Tobias Schwinger wrote:
>>>> Dear Boost community,
>>>>
>>>> do we have a function object template to wrap arbitrary constructor
>>>> calls / operator new expressions somewhere in Boost, already?
>>>>  
>>> lambda::new_ptr ?
>> Yep, 'new_ptr' and 'constructor' are almost exactly what I want.
>>
>> Those templates are missing a 'result_type' typedef to become usable as
>> "stand-alone function objects" (outside of Boost.Lambda expressions).
>>
>> Further, the limits are a bit too low for constructing Fusion Sequences
>> and having them configurable would be nice to have, too...
>
> Yes and IMO these things should be called new_ and construct.
>

Yep, 'new_ptr' is sorta strange ;-).

I'm not too convinced that 'construct' gives a better name than
'constructor', because looking at

    construct<T>()

I get the impression that something gets constructed, but in reality
it's just about capturing T's constructor in order to pass it around.


Regards,
Tobias

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

Re: [lambda] Re: boost::factory?

by Joel de Guzman-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Tobias Schwinger wrote:

> Eric Niebler wrote:
>> Tobias Schwinger wrote:
>>> Marcus Lindblom wrote:
>>>> Tobias Schwinger wrote:
>>>>> Dear Boost community,
>>>>>
>>>>> do we have a function object template to wrap arbitrary constructor
>>>>> calls / operator new expressions somewhere in Boost, already?
>>>>>  
>>>> lambda::new_ptr ?
>>> Yep, 'new_ptr' and 'constructor' are almost exactly what I want.
>>>
>>> Those templates are missing a 'result_type' typedef to become usable as
>>> "stand-alone function objects" (outside of Boost.Lambda expressions).
>>>
>>> Further, the limits are a bit too low for constructing Fusion Sequences
>>> and having them configurable would be nice to have, too...
>> Yes and IMO these things should be called new_ and construct.
>>
>
> Yep, 'new_ptr' is sorta strange ;-).
>
> I'm not too convinced that 'construct' gives a better name than
> 'constructor', because looking at
>
>     construct<T>()
>
> I get the impression that something gets constructed, but in reality
> it's just about capturing T's constructor in order to pass it around.

So what? They're just lazy!

I second Eric. "new_" and "construct" are better names.
Subjective, nonetheless, but that's how it's spelled in Phoenix
(ahem :) ahem). So, do I change all the names because phoenix
functions are lazy?

Regards,
--
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

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

Re: [lambda] Re: boost::factory?

by Tobias Schwinger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Joel de Guzman wrote:

> Tobias Schwinger wrote:
>> I'm not too convinced that 'construct' gives a better name than
>> 'constructor', because looking at
>>
>>     construct<T>()
>>
>> I get the impression that something gets constructed, but in reality
>> it's just about capturing T's constructor in order to pass it around.
>
> So what? They're just lazy!
>
> I second Eric. "new_" and "construct" are better names.
> Subjective, nonetheless, but that's how it's spelled in Phoenix
> (ahem :) ahem). So, do I change all the names because phoenix
> functions are lazy?
>

Phoenix is lazy per-se, so imperative names are perfectly OK for that
library.

For some general utility I'd prefer to emphasize the laziness. So what's
wrong with 'factory' in the first place?

Anyway, can those Phoenix tools be used as standard function objects
(with support for 'boost::result_of')?

If so, it's probably not worth the trouble writing something new...


Regards,
Tobias

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

Re: boost::factory?

by Tobias Schwinger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David Abrahams wrote:
> on Sun Jun 17 2007, Tobias Schwinger <tschwinger-AT-isonews2.com> wrote:
>> Interface draft:
>> ================
>>
>>      factory<T>     // constructs X and returns it by value
>>      factory<T*>    // uses operator new, returns a pointer
>
> auto_ptr, please.

Generic algorithms won't 'get' it.

In this light, it seems better to have a separate template for pointers,
so you clients can specify what they want, explicitly:

     new_< T* >
     new_< auto_ptr<T> >
     new_< special_smartie<T> >

(Seems tricky to deduce T but it might be doable).

>> Where operator() takes a variable number of arguments, forwarded to the
>> constructor.
>
>
> Isn't in-place construction the most general case?

It sure is, but not necessarily the most handy. How to tell e.g.
std::transform to allocate memory for the transformed elements?

Not sure I really got your point, here.

Regards,
Tobias

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

Re: boost::factory?

by Johan Torp :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'd love to have something like this in Boost.Utility!

I've run in to situations where it would have been useful many times.

Best Regards, Johan Torp


Re: boost::factory?

by David Abrahams :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


on Tue Jun 19 2007, Tobias Schwinger <tschwinger-AT-isonews2.com> wrote:

> David Abrahams wrote:
>> on Sun Jun 17 2007, Tobias Schwinger <tschwinger-AT-isonews2.com> wrote:
>>> Interface draft:
>>> ================
>>>
>>>      factory<T>     // constructs X and returns it by value
>>>      factory<T*>    // uses operator new, returns a pointer
>>
>> auto_ptr, please.
>
> Generic algorithms won't 'get' it.

You have generic algorithms that expect to get ownership of a
dynamically-allocated pointer?

> In this light, it seems better to have a separate template for pointers,
> so you clients can specify what they want, explicitly:
>
>      new_< T* >
>      new_< auto_ptr<T> >
>      new_< special_smartie<T> >
>
> (Seems tricky to deduce T but it might be doable).

  boost::pointee<X>::type

>>> Where operator() takes a variable number of arguments, forwarded to the
>>> constructor.
>>
>>
>> Isn't in-place construction the most general case?
>
> It sure is, but not necessarily the most handy. How to tell e.g.
> std::transform to allocate memory for the transformed elements?
>
> Not sure I really got your point, here.

Just that you might want to support the general case and build the
others on top... if possible.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

The Astoria Seminar ==> http://www.astoriaseminar.com

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

Re: boost::factory?

by Tobias Schwinger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David Abrahams wrote:

> on Tue Jun 19 2007, Tobias Schwinger <tschwinger-AT-isonews2.com> wrote:
>
>> David Abrahams wrote:
>>> on Sun Jun 17 2007, Tobias Schwinger <tschwinger-AT-isonews2.com> wrote:
>>>> Interface draft:
>>>> ================
>>>>
>>>>      factory<T>     // constructs X and returns it by value
>>>>      factory<T*>    // uses operator new, returns a pointer
>>> auto_ptr, please.
>> Generic algorithms won't 'get' it.
>
> You have generic algorithms that expect to get ownership of a
> dynamically-allocated pointer?
>

At least there are generic algorithms that might as well move pointers
to dynamic memory:

     instances.reserve(args.size()); // throws now, if out of memory
     transform(args.begin(),args.end(),back_inserter(instances),
         bind( factory<something*>(), 123, _1) );

One could argue that 'instances' should be a boost::ptr_vector - but it
isn't needed that badly in cases like this one.

>> In this light, it seems better to have a separate template for pointers,
>> so you clients can specify what they want, explicitly:
>>
>>      new_< T* >
>>      new_< auto_ptr<T> >
>>      new_< special_smartie<T> >
>>
>> (Seems tricky to deduce T but it might be doable).
>
>   boost::pointee<X>::type

Oh thanks (I remember the discussion but never noticed it actually
became reality :-) )!

>
>>>> Where operator() takes a variable number of arguments, forwarded to the
>>>> constructor.
>>>
>>> Isn't in-place construction the most general case?
>> It sure is, but not necessarily the most handy. How to tell e.g.
>> std::transform to allocate memory for the transformed elements?
>>
>> Not sure I really got your point, here.
>
> Just that you might want to support the general case and build the
> others on top... if possible.

That's essentially allocator support, isn't it? I doubt that STL-style
allocators are too well-suited for this purpose, however...

What's the interface you had in mind?

Regards,
Tobias

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

Re: boost::factory?

by Johan Torp :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I ran across a similar problem when I implemented my observable_value suggestion (http://lists.boost.org/Archives/boost/2007/06/123263.php) and wanted  to write a generic operator<T>= for all operators (+=, /=, %= and so on).

The problem with operators of built-in types seems a bit related to those of constructors; you can't treat them as ordinary function pointers.

It'd be great if this proposed library could solve this "operator problem" too. IMHO, a solution to the operator problem is not near as important but if there is a general and not much more complicated solution to both, it would be great.

Best Regards,
Johan Torp

Re: boost::factory?

by Tobias Schwinger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Johan Torp wrote:

> I ran across a similar problem when I implemented my observable_value
> suggestion (http://lists.boost.org/Archives/boost/2007/06/123263.php) and
> wanted  to write a generic operator<T>= for all operators (+=, /=, %= and so
> on).
>
> The problem with operators of built-in types seems a bit related to those of
> constructors; you can't treat them as ordinary function pointers.
>
> It'd be great if this proposed library could solve this "operator problem"
> too. IMHO, a solution to the operator problem is not near as important but
> if there is a general and not much more complicated solution to both, it
> would be great.

That would be something like

     DEFINE_FUNCTION_OBJECT_FOR_EXPRESSION(assign_op, 2, _1 += 2);

and it's indeed implementable with C++0x.


Regards,
Tobias

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