Boost logo

Boost Users :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2008-01-05 05:06:00


Tobias Schwinger wrote:
> dariomt_at_[hidden] wrote:
>> class Base {...};
>> class Factory {...};
>> template <typename T> struct Helper {...}; // constructor registers
>> creation function for template parameter
>>
>> Now we have a template defining a family of derived classes:
>> template <typename U, typename V, typename W> class DerivedUVW :
>> public Base {...};
>>
>
> ...
>
>>
>> And all possible U V and W classes in the combination game:
>> struct A1 {}; struct A2 {}; // for U
>> struct B1 {}; struct B2 {}; // for V
>> struct C1 {}; struct C2 {}; // for W
>
> ...
>
>
>> And now the six million dollar question:
>> Is there a way in which MPL and fusion can automatically do the
>> registration?
>
> I think so (see attachment)!
>
> Here's an MPL-based solution. It does not require any preprocessor code
> and compiles with GCC4.

With a bug. It successfully determines whether there is nothing to do -
but also does nothing if there's almost nothing to do, that is only one
combination. It also won't work if one of the input sequences is empty.

The attached patches remove the entry condition. So the precondition is
"the sequences yield at least one combination" now. Checking it is left
an exercise to the reader :).

Regards,
Tobias


--- combinations.cpp.bak 2008-01-05 10:55:37.000000000 +0100
+++ combinations.cpp 2008-01-05 10:56:04.000000000 +0100
@@ -206,12 +206,7 @@
 inline void register_factories()
 {
     typedef typename mpl::transform<Sequences, make_cursor<_1> >::type cursors;
-
- typedef typename mpl::fold<cursors, nested_loops_fold_op::initial_state,
- nested_loops_fold_op>::type next_state;
- typedef typename mpl::first<next_state>::type done;
-
- register_factories_impl<cursors,done>::call();
+ register_factories_impl<cursors,mpl::false_>::call();
 }
 
 int main()


--- combinations_rt.cpp.bak 2008-01-05 10:55:47.000000000 +0100
+++ combinations_rt.cpp 2008-01-05 10:56:22.000000000 +0100
@@ -63,20 +63,12 @@
 
     cursor_vector cursors; cursors += cursor(l1), cursor(l2), cursor(l3);
 
- // Note: We use the algorithm to determine whether there is something
- // to do in the first place (just like the compile time version).
- // However, the runtime version works directly on mutable cursors, so
- // we copy the sequence to ignore its effect on the cursors.
- cursor_vector disposable_copy_of_cursors(cursors);
- if (! nested_loops_step(disposable_copy_of_cursors))
+ do
     {
- do
- {
- std::cout << cursors[0].deref() << ',' << cursors[1].deref() << ','
- << cursors[2].deref() << std::endl;
+ std::cout << cursors[0].deref() << ',' << cursors[1].deref() << ','
+ << cursors[2].deref() << std::endl;
 
- } while (! nested_loops_step(cursors));
- }
+ } while (! nested_loops_step(cursors));
 }
 
 


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net