Boost logo

Boost Users :

From: Zeljko Vrba (zvrba_at_[hidden])
Date: 2008-08-22 02:19:45


On Fri, Aug 22, 2008 at 01:04:43PM +0800, Joel de Guzman wrote:
>
> Read on Boost.Result of and the TR1 result_of conventions.
> http://www.boost.org/doc/libs/1_36_0/libs/utility/utility.htm
> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html
>
> It's not a function call. It's a function declarator. This is first
> discussed and put into use in the Boost.Function library:
> http://www.boost.org/doc/libs/1_36_0/doc/html/function/tutorial.html#id2903300
>
It would be nice to have those links together with the transform_view
documentation, or in a separate section[*] if more components inside fusion use
it. (I *did* look through table of contents before I asked on the list, but I
couldn't find anything that looked like a matching section.)

[*] Suggestion: put these links in the "References" section, and add a sentence
after the example "See <hyperlink>references</hyperlink> for documentation
about result conventions." (or something similar)

>
> Are you sure the one above works? You need the result type,
> AFAICT.
>

Yes, I'm 100% sure that it works on Sun's C++ compiler, I have double-checked
it right now (this is so bizzarre that I've even computed checksum before
compilation just to make sure that I wasn't editing a wrong file). It spits
out a long error message with gcc (but it compiles OK also with gcc when the
result struct is in place). CC: Sun C++ 5.9 SunOS_i386 Patch 124864-03
2008/03/12

Below is a complete compileable program. I tried to combine transform_view
with boost::lambda and bind to sort the vector of maps. While it compiles,
the result of std::sort leaves an unchanged sequence! Here's the output:

(8 7)(8 6)(1 4)(3 6)(3 2)(1 7)(4 3)(2 5) <- original std::vector<Map>
01 <- proof that tx(a) < tx(b) works
(8 7)(8 6)(1 4)(3 6)(3 2)(1 7)(4 3)(2 5) <- "sorted" by custom functor
(1 4)(1 7)(2 5)(3 2)(3 6)(4 3)(8 6)(8 7) <- sorted by using operator<

The same thing happens also with gcc (after replacing #if 0 with #if 1 to make
it compileable there).

Compilation with Sun and gcc compilers:
CC -I ~/COMPILE/boost_1_36_0 -library=stlport4 -m64 z.cc
/usr/sfw/bin/gcc -m64 -I ~/COMPILE/boost_1_36_0 z.cc

The Sun's compiler is indifferent to #if 0 / #if 1 -> compiles always
gcc compiles the code only with #if 1

Anyway, I've figured out how to define operator< for fusion::pairs, so I'm
going down that route. But I'm curious about the anomalous std::sort behavior.
Why doesn't sort actually sort the std::vector (search for line marked XXX:)?
Should I watch out for more similar pitfalls?

===

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <boost/fusion/container/map/map.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/fusion/include/comparison.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/view/transform_view.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/type_traits/remove_reference.hpp>

struct net;
struct pin;

namespace bf = boost::fusion;
using std::cout;
using std::endl;

typedef bf::map<bf::pair<net, unsigned>, bf::pair<pin, unsigned> > Map;

template<typename T>
inline bool operator<(bf::pair<T, unsigned> a, bf::pair<T, unsigned> b)
{
        return a.second < b.second;
}

struct Map2Pair
{
#if 0
        template<typename T>
        struct result;

        template<typename T>
        struct result<Map2Pair(T)>
        {
                typedef typename boost::remove_reference<T>::type pair_type;
                typedef typename pair_type::second_type type;
        };
#endif
    template<typename T>
    typename T::second_type operator()(T t) const
    {
        return t.second;
    }
};

typedef bf::transform_view<Map, Map2Pair> Pair;

Pair tx(Map m)
{
    return Pair(m, Map2Pair());
}
 
int main()
{
    using namespace boost::fusion;
    using namespace boost::lambda;
    using namespace boost;

    std::vector<Map> v;

    v.push_back(Map(8, 7)); v.push_back(Map(8, 6)); v.push_back(Map(1, 4));
    v.push_back(Map(3, 6)); v.push_back(Map(3, 2)); v.push_back(Map(1, 7));
    v.push_back(Map(4, 3)); v.push_back(Map(2, 5));

    std::copy(v.begin(), v.end(), std::ostream_iterator<Map>(cout)); cout << endl;
        cout << (tx(v[0]) < tx(v[1])) << (tx(v[1]) < tx(v[0])) << endl;
    std::sort(v.begin(), v.end(), bind(&tx, _1) < bind(&tx, _2)); // XXX: no effect at all?!
    std::copy(v.begin(), v.end(), std::ostream_iterator<Map>(cout)); cout << endl;
        std::sort(v.begin(), v.end());
    std::copy(v.begin(), v.end(), std::ostream_iterator<Map>(cout)); cout << endl;

    return 0;
}


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