Boost logo

Boost :

From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2002-09-25 04:56:53


I added some support for function calls to dynamic_any. There is no release
yet, only CVS access at:
https://sourceforge.net/projects/cpp-experiment
It still has some problems that should be resolved. They are reason of the
post.
Ok, first some words about usage. It's simple. At first step, one can create
unary or binary (generalized) function:

  struct dynamic_any_less : std::binary_function<_T_val, _T_val, bool>
  {
    template<typename T>
    bool operator()(const T & v1, const T & v2)
    {
      return std::less<T>()(v1, v2);
    }
  };

The _T_val type is used there to indicate that this function is accepting
range of types by value, not a single type. You can also uses _T_ref to
indicate passing agrument by reference.
I see here at least naming problem for _T_val and _T_ref. But I aslo feel
that I applied concept wrongly. After all, there are only 6 different
function types:
  std::unary_function<_T_val, Return>
  std::unary_function<_T_ref, Return>
  std::binary_function<_T_val, _T_val, Return>
  std::binary_function<_T_val, _T_ref, Return>
  std::binary_function<_T_ref, _T_val, Return>
  std::binary_function<_T_ref, _T_ref, Return>
and they can be replaced for example with:
  dynamic_any_function_v<Return>
  dynamic_any_function_r<Return>
  dynamic_any_function_vv<Return>
  dynamic_any_function_vr<Return>
  dynamic_any_function_rv<Return>
  dynamic_any_function_rr<Return>
I would like to hear opinion of someone who is strong in function concept.

Second step: define less_comparable_any.

  typedef dynamic_any< mpl::vector<dynamic_any_less> > less_comparable_any;

And then use it:

  less_comparable_any a(0), b(1);
  bool result = call(dynamic_any_less(), a, b);

The call is ordinary function that invokes used-defined function
(dynamic_any_less in our case) for two non-empty dynamic_any values of the
same type, otherwise it throws bad_call. The problem here is to find best
implementation of dynamic_any_less call for 'a' and 'b'. Should it be
ordinary function or may be some wrapper?

  // alternative:
  dynamic_any_function<dynamic_any_less> fun;
  less_comparable_any a(0), b(1);
  bool result = fun(a, b);

Addinionally, I would like to add convertion between dynamic_any<Sequence1>
and dynamic_any<Sequence2>:

  template<class DynAny, class Sequence2>
  DynAny convert(dynamic_any<Sequence2> & val);
  
  dynamic_any<Sequence1> a1 = /* ... */;
  dynamic_any<Sequence2> a2 = convert<dynamic_any<Sequence2> >(a1);
  
Implementation is simple. First, remove (at compile-time) all elements from
Sequence2 that are also belong to Sequence1. Let's call resulting sequence
Diff. In terms of mathematical sets, this operation can be written as Diff
= Sequence2 - Sequence1. Second, check presence of interface for every
element in Diff using dynamic_cast. It all interfaces found then convert
otherwise throws. Swap with convert would be fine to avoid temporary copy:

  swap_with_convert(a1, a2); // name it!

The most annoying problem is problem with compilers. I has four different
compilers and only one can be used. It's g++ 3.1. On Intel 6.0 free
compiler for Linux test compiles but crashes. On g++ 2.96 I got internal
compiler error. Compiler supplied with Kylix 3 is not a friend of mpl.

Solution is to keep existing boost::any and provide conversion between
boost::dynamic_any and boost::any.
Opinions?

--
Best regards,
Alexander Nasonov
e-mail account: alnsn
e-mail server:  mail.ru

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk