@@ -17,26 +17,29 @@ turn on optimizations (`-O2 -DNDEBUG`) and to select the Boost library.
1717
1818## OpenMethod vs Boost.TypeErasure
1919
20- At first sight, OpenMethod and TypeErasure exist in the same space: runtime
21- polymorphic systems that offer a solution to the Expression Problem.
20+ OpenMethod and TypeErasure exist in the same space: runtime polymorphic systems
21+ that offer a solution to the Expression Problem.
2222
23- Thanks to BOOST_TYPE_ERASURE_FREE, one can add operations to existing classes,
24- without the need to modify them. And of course one can add new classes to
25- existing operations, by providing the required functions on them. However, one
26- quickly hits a wall, and this is related to the fact that in B.TE polymorphism
27- is imbued to a "magic" handle, ` any ` , whereas in OpenMethod, polymorphism is
28- attached to the object itself.
23+ Thanks to BOOST_TYPE_ERASURE_FREE, we can add operations to existing classes,
24+ without the need to modify them. And of course we can add new classes to
25+ existing operations, by providing the required functions on them.
2926
30- To make this more concrete, let's look at an example. Consider a matrix library,
31- which contains several matrix subtypes (let's limit ourselves to "ordinary" and
32- "symmetric") and operations (let's just focus on transposition).
27+ However, we quickly hits a wall, and this is related to the fact that in B.TE
28+ polymorphism is imbued to a "magic" handle, ` any ` , whereas in OpenMethod,
29+ polymorphism is attached to the object itself.
30+
31+ Let's look at an example. Consider a matrix library, which contains several
32+ matrix subtypes (let's limit ourselves to "ordinary" and "symmetric") and
33+ operations (let's just focus on transposition).
3334
3435Here is (what I believe is) a plausible design:
3536
3637``` c++
3738#include < boost/mpl/vector.hpp>
3839#include < boost/type_erasure/any.hpp>
3940#include < boost/type_erasure/free.hpp>
41+ #include < boost/type_erasure/typeid_of.hpp>
42+ #include < boost/core/demangle.hpp>
4043#include < iostream>
4144
4245namespace mpl = boost::mpl;
@@ -45,51 +48,62 @@ using namespace boost::type_erasure;
4548BOOST_TYPE_ERASURE_FREE(transpose);
4649
4750struct ordinary_matrix_impl {
48- ordinary_matrix_impl() {
49- std::cout << "ordinary_matrix_impl\n" ;
50- }
51+ virtual ~ ordinary_matrix_impl() { / * ... * / }
52+ std::size_t rows, cols ;
53+ std::vector< double > elements; // rows x cols doubles
5154};
5255
5356struct symmetric_matrix_impl {
54- symmetric_matrix_impl() {
55- std::cout << "symmetric_matrix_impl\n";
56- }
57+ virtual ~ symmetric_matrix_impl() { / * ... * / }
58+ std::size_t rows; // cols == rows
59+ std::vector< double > elements; // rows doubles
5760};
5861
5962struct matrix {
60- any< mpl::vector<copy_constructible< > , has_transpose<matrix(_ self&)>>> impl;
63+ any< mpl::vector<copy_constructible< > , has_transpose<matrix(_ self&)>, typeid _ <> >> impl;
6164};
6265
6366auto transpose(matrix m) {
6467 return transpose(m.impl);
6568}
6669
6770auto transpose(ordinary_matrix_impl& m) {
68- std::cout << "transpose ordinary matrix\n";
6971 return matrix{ordinary_matrix_impl()};
7072}
7173
7274auto transpose(symmetric_matrix_impl& m) {
73- std::cout << "transpose symmetric matrix\n";
7475 return matrix{m};
7576}
7677
7778auto main() -> int {
7879 {
7980 matrix m{ordinary_matrix_impl()};
8081 auto t = transpose(m);
82+ std::cout << boost::core::demangle(typeid_of(t.impl).name()) << "\n";
83+ // ordinary_matrix_impl
8184 }
8285
8386 {
8487 matrix m{symmetric_matrix_impl()};
8588 auto t = transpose(m);
89+ std::cout << boost::core::demangle(typeid_of(t.impl).name()) << "\n";
90+ // symmetric_matrix_impl
8691 }
8792
8893 return 0 ;
8994}
9095```
9196
92- ([ Compiler Explorer] ( https://godbolt.org/z/hWoM6jWdd ) )
97+ ([ Compiler Explorer] ( https://godbolt.org/z/613Eo5zGP )
98+
99+ We were able to add new behavior to existing classes (the "impl" classes)
100+ without needing to modify them. This is promising.
101+
102+ Here is the equivalent using open-methods:
103+
104+ ``` c++
105+ ```
106+
107+
93108
94- Now let's suppose that an application needs to serialize matrices to JSON. The
95- operation can be added to the matrix library in the same way as ` transpose ` :
109+ We can also add serialization to JSON:
0 commit comments