Boost logo

Boost :

From: Rob Stewart (stewart_at_[hidden])
Date: 2005-07-28 11:32:31


From: FlSt_at_[hidden]
> >
> >>>>[...]

Don't forget attributions for the text you quote.

> >If that is a useful expression, it's more of a set operation than
> >a junction operation (as exemplified by Perl's junctions) anyway,
> >
> http://www.linux-magazine.com/issue/38/Perl_BlackJack.pdf.
> This is the article from where my idea comes to have something similar
> in C++ (I read the German translation in Linux Magazin 12/2003)

I see. That elucidates the duality concept you've been
discussing.

> >right? Besides, normal algorithms can be used to express that
> >quite succinctly. Do you need a new type for it? Maybe. I
> >don't think it should be merged with the simpler ideas from Perl
> >junctions. I think they are orthogonal behaviors, and the
> >complexity argues against one type doing both tasks.
> >
> The Perl junctions aren't simpler, in Perl you can call functions either
> in a scalar context or in a list context. The called function can
> determine in which context it is called and return a scalar or a list. I
> think my mistake was, I tried to bring this concept into C++ for
> junctions, but it doesn't fit into the C++ type system. And there was no
> example for this in the article I denoted in my first message.

OK. You did mislead me with the initial references, but I now
understand what you were trying to do.

> A junction without junction result type and arithmetic operations is
> something completely different I had in mind at the beginning of this
> discussion. What remains now at the view point of the client are the

I think the creation of a new container with elements from
another container that match a criteria is already well
supported. It may yet be that some syntactic sugar can be
overlaid to simplify it, however, so do keep that in mind.

So, I think we're agreed that we're discussing four things that
can be compared to each other as well as to single values. The
supported comparisons are ==, !=, <, >, <=, and >=. If we're
agreed, then we can discuss design.

> four functions any_of<T>, all_of<T>, one_of<T> and none_of<T> and the
> comparison operators. The XXX_of functions should operate on ranges or
> containers. I aggree.

For the extraction of elements matching some criteria, you would
likely use function templates. For the functionality we've
whittled down junctions (or whatever name still fits) to include,
you need types plus namespace scope operators:

   template <typename T>
   struct junction
   {
      range<T> range_; // for exposition only
   };

   template <typename T>
   struct all_of : junction<T>
   {
   };

   template <typename T>
   struct any_of : junction<T>
   {
   };

   template <typename T>
   struct none_of : junction<T>
   {
   };

   template <typename T>
   struct one_of : junction<T>
   {
   };

   template <typename LHS, typename T>
   bool
   operator ==(call_traits<LHS>::param_type lhs_i,
      any_of<T> rhs_i); // maybe by reference to const

   template <typename LHS, typename T>
   bool
   operator !=(call_traits<LHS>::param_type lhs_i,
      any_of<T> rhs_i); // maybe by reference to const

   template <typename LHS, typename T>
   bool
   operator <(call_traits<LHS>::param_type lhs_i,
      any_of<T> rhs_i); // maybe by reference to const

   template <typename LHS, typename T>
   bool
   operator >(call_traits<LHS>::param_type lhs_i,
      any_of<T> rhs_i); // maybe by reference to const

   template <typename LHS, typename T>
   bool
   operator <=(call_traits<LHS>::param_type lhs_i,
      any_of<T> rhs_i); // maybe by reference to const

   template <typename LHS, typename T>
   bool
   operator >=(call_traits<LHS>::param_type lhs_i,
      any_of<T> rhs_i); // maybe by reference to const

   template < typename T, typename RHS>
   bool
   operator ==(any_of<T> rhs_i, // maybe by reference to const
      call_traits<RHS>::param_type rhs_i);

   etc.

   template <typename LHS, typename T>
   bool
   operator ==(call_traits<LHS>::param_type lhs_i,
      all_of<T> rhs_i); // maybe by reference to const

   etc., including those to compare any_of with all_of, all_of
   with one_of, and so on.

Many of these operators will be defined in terms of others. For
example, once you have the (lhs_i, any_of) operators, the
(any_of, rhs_i) operators can be defined in terms of the
former. Also, you can define the (lhs_i, all_of) operators in
terms of the (lhs_i, any_of) operators, provided you can create
an any_of<T> from an all_of<T>:

   template <typename T>
   struct any_of : junction<T>
   {
      explicit any_of(junction<T> junction_i); // maybe by reference to const
   };

Indeed, most cases can be handled once you implement the any_of
and one_of variants.

A better approach is probably for the operators to be implemented
in terms of a number of implementation function templates that
work only on junction<T>'s. Then, there's no conversion needed;
the operators just need to call the right implementation
function. That leaves the four derived types as just selectors
for the right operator.

Ideally, junction<T> will hide its range and the implementation
function templates will be made friends.

Using namespace scope operators, with the four derived types as
selectors, we can support any combination of x op all_of(s),
x op any_of(x), x op none_of(s), x op one_of(s), where x is a
type convertible to the range's value type or another all_of,
any_of, none_of, or one_of.

What do you think of these ideas for the design?

There's still the issue of naming. Should these be called
junctions since they don't do all that Perl's junctions do?
Besides, I think "junction" somehow fits better the notion of
producing a result container that includes those elements of the
range that satisfy the criteria.

Quantum physics' superposition concept doesn't fit very well,
because we're not talking about particles that can be in various
places. That suggests "supervalue," but one might then ask, what
makes the value so super?

A common theme suggests "smart value," but that's not really
helpful. At least the one-word "supervalue" is somehow
indicative of "superposition."

So, when someone is looking for a library to do what this one
does, what name(s) would they think to look for? I'm at a loss
for a good name.

-- 
Rob Stewart                           stewart_at_[hidden]
Software Engineer                     http://www.sig.com
Susquehanna International Group, LLP  using std::disclaimer;

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