
AMDG Alexander Nasonov wrote:
Steven Watanabe wrote:
typedef any_tuple<_1, _1, _2, where_<random_access_iterator<_1>, callable<_2, bool(deref_result<_1>, deref_result<_1>)> > > sort_args; void sort_impl(mpl::at<sort_args, _1>::type&, mpl::at<sort_args, _1>::type&, mpl::at<sort_args, _2>::type&); template<class Iter, class F> void sort(Iter begin, Iter end, F f) { sort_args args(begin, end, f); sort_impl(get<0>(args), get<1>(args), get<2>(args)); }
I don't quite understand how it's connected to dynamic_any::any objects. Does object 1 stores an iterator to a beginning of a sequence while object 2 stores past-the-end of the sequence? Yes. In a cpp file sort_impl would just be void sort_impl( mpl::at<sort_args, _1>::type& begin, mpl::at<sort_args, _1>::type& end, mpl::at<sort_args, _2>::type& f) { std::sort(begin, end, f); }
The idea was the each element of the tuple would be like a dynamic_any::any object with operations on several elements like f(*begin, *next(begin)). So, in my example deref_result<_1> is a placeholder for the type of *begin. I think it would be defined something like: template<class> struct deref_result : placeholder {}; I'm not sure about the functions. Single functions should be defined almost like what you already have except that there would be many placeholder types. groups of functions like random_access_iterator need to be made possible. template<class T> struct random_access_iterator : compound_concept<...> {}; A similar effect could be achieved by simply putting a boost::tuple in a dynamic_any::any. The advantage of this method is to allow individual objects to be copied independently. I'm mostly wondering whether a significant proportion of the uses of multimethods could be handled in this way.
Would such a class be useful? Any better ideas for the interface?
The big problem is the amount of metaprograming needed. 10 operations were more than msvc 7.1 could handle with my version of dynamic_any::any<> and this is much worse.
Definitely. I think, it this case we should find a good balance between compile-time and runtime. I don't like an interface where functions for different arguments variantions are registred at runtime, but if there is no other solution, I can accept it. But in this case it would be better to start with multimethods library and then use it for dynamic_any. Originally, I wanted to get close to untyped languages where you can multiply numbers and strings and things like this. This means that you have a limited set of types (bool, integers, floats, chars, strings and references to objects). This set can be bigger in C++ because you may want to handle references to different base classes differently but it's still, I thought, can be enumerated in one place. All combinations of 20 types gives 400 variants. It's big for mpl::vector but I believe modern compilers can process typelists of this length if a library is carefully crafted. If the number of types is really fixed then variant would be a better solution, I would think.
The method I suggested before: template<class Operation, class T> struct overload; allows all the variations associated with T to be loaded the first time the constructor of dynamic_any::any runs. Probably to make the lookup efficient for large numbers of functions, some dynamic loading would be needed anyway (unless there is some trick I haven't heard of for getting a unique integer from a type at compile time). What I currently have is not very efficient. It takes about 60 ns. per dispatch for all possible combinations of a ternary function with 4 types (a total of 64). Compare that to the single dispatch case which only takes about 6 ns. In Christ, Steven Watanabe