Boost logo

Boost Users :

From: Mark Storer (mstorer_at_[hidden])
Date: 2002-09-24 18:21:33


Nope. Container-agnostic code is a red herring. Don't bother, you'll only
be waisting your time. "Effective STL" covers this in detail in Chapter 1,
item 2, far better than anything I could come up with.

You might be able to come up with 'map' and 'everything else' versions of
your code, but even that will have some unexpected side effects.

Now, having said all that, here's an idea (I seem to be developing a habit
of contradicting myself):

Accept as part of the enumerator template an 'accessor', one that would
default to returning the contents of the iterator, but could be replaced
with something that extracted "->second".

Your code would end up looking something like this:

// WARNING: This code hasn't been anywhere near a compiler.
template <typename T>
struct accessor
{
  typedef T::value_type accessee;
  accessee &operator()( T &t )
  {
    return *T;
  }

};

template <typename T>
struct map_accessor
{
  typedef T::value_type::second accessee;
  accessee &Map_Accessor( T &t )
  {
    return t->second;
  }

};
template <typename T, typename acc = Accessor<T>>
EnumCols( T &begin, T &end, acc accessor )
{
  T cur;
  if(begin == end) return;
  // get matrix width
  size_t rows = acc( begin ).size();
  for(int i = 0; i < rows; ++i)
  {
    cur = begin;
    while(cur != end)
    {
      // a useful EnumCols would have to take some
      // sort of function as a paramenter and use
      // it to replace DO_STUFF below
      DO_STUFF( acc(cur)[i] );
      ++cur;
    }
  }
}
EnumCols( matrix.begin(), matrix.end(), Map_Accessor<matrix's type> ); //
for maps
        or
EnumCols( matrix.begin(), matrix.end()); // for everything else

These function templates could either exist stand-alone, or as some sort of
'container-traits'.

The traits tact would force you to wrap all the containers you actually
wanted to use with templates that defined the appropriate traits, but would
allow the actual enumeration code to be considerably cleaner (through
default template params).

But all this involves rolling your own code, which would place this
conversation firmly in the "other" boost list.

--Mark Storer
  Software Engineer
  Cardiff Software

#include <disclaimer>
typedef std::disclaimer<Cardiff> Discard;

-----Original Message-----
From: Antonio Piccolboni [mailto:antonio_piccolboni_at_[hidden]]
Sent: Tuesday, September 24, 2002 12:01 PM
To: Boost-Users_at_[hidden]
Subject: [Boost-Users] (unknown)

Dear Boosters

Suppose you have a matrix represented raw-wise with a vector< vector
<float > > and you want to iterate over the coloumns. Easy with the
projection adaptor. But life is never so easy. My matrix is
represented raw wise by a map <vector <float> > and I need the same
kind of iterator. There is no way I can get my code to compile. I
think the problem is that vector iterators return values, map
iterators retun pairs <key,value> (that is, references to the above).
And this seems not only to doom my attempt at defining this n-th dim
projection iterator, but even more so and fundamentally, it seem to
preclude my ultimate goal of defining a projection for any container1
<containr2 < element_type > > where container2 two is random access.
Any help would be appreciated and if I make it to the larger goal, I
will return it to the community. Thanks

Antonio

Header

#ifndef GRAPH_H
#define GRAPH_H

#include <boost/config.hpp>
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/iterator_adaptors.hpp>

//typedef pair<long, vector<float> > graph_element;
typedef vector<float> graph_element;

template <int index>
struct select_component {
  typedef pair < long, graph_element > argument_type;
  typedef float result_type;
  const float & operator()(const graph_element & r) const {
    return r.second[index];
  }
  float & operator()(graph_element & r) const {
    return r.second[index];
  }
};

#endif

Would be test code

#include "graph.h"
#include <map>
#include<vector>

int main(int, char*[])
{
  typedef map < long, graph_element > graph;

  graph aGraph;

  aGraph[0].push_back(0.00);
  aGraph[0].push_back(0.01);
  aGraph[0].push_back(0.02);
  aGraph[1].push_back(0.10);
  aGraph[1].push_back(0.11);
  aGraph[1].push_back(0.12);
  aGraph[2].push_back(0.20);
  aGraph[2].push_back(0.21);
  aGraph[2].push_back(0.22);
  aGraph[3].push_back(0.30);
  aGraph[3].push_back(0.31);
  aGraph[3].push_back(0.32);

  boost::projection_iterator_generator < select_component < 0 >,
    graph::iterator >::type
    graph_first(aGraph.begin()),
    graph_last(aGraph.end());
  
  copy(graph_first, graph_last,
            ostream_iterator<float>(cout, "\n"));
  cout << endl;
}

Post-modern error message

cd /home/apicco/src/analysis/transcriptome/transmap/
g++ -g -I/home/apicco/install/boost_1_28_0 -o graph-test graph-test.C
/home/apicco/install/boost_1_28_0/boost/iterator_adaptors.hpp: In
method `typename
IteratorAdaptor::reference
boost::projection_iterator_policies<AdaptableUnaryFunction>::dereferen
ce
(const IteratorAdaptor &) const [with IteratorAdaptor =
boost::iterator_adaptor<_Rb_tree_iterator<pair<const long int,
graph_element>, pair<const long int,
graph_element> &, pair<const long int, graph_element> *>,
boost::projection_iterator_policies<select_component<0> >, float,
float &, float *,
boost::detail::default_argument, boost::detail::default_argument>,
AdaptableUnaryFunction =
select_component<0>]':
/home/apicco/install/boost_1_28_0/boost/iterator_adaptors.hpp:867:
instantiated from `boost::iterator_adaptor<Base, Policies, Value,
Reference, Pointer, Category, Distance>::operator* () const [with
Base = _Rb_tree_iterator<pair<const long int, graph_element>,
pair<const long int, graph_element> &, pair<const long int,
graph_element> *>, Policies =
boost::projection_iterator_policies<select_component<0> >, Value =
float, Reference = float &, Pointer = float *, Category =
boost::detail::default_argument, Distance =
boost::detail::default_argument]'
/usr/include/g++-3/stl_algobase.h:129: instantiated from `__copy
(_InputIter, _InputIter, _OutputIter, input_iterator_tag, _Distance
*) [with _InputIter =
boost::iterator_adaptor<_Rb_tree_iterator<pair<const long int,
graph_element>, pair<const long int, graph_element> &, pair<const
long int, graph_element> *>,
boost::projection_iterator_policies<select_component<0> >, float,
float &, float *, boost::detail::default_argument,
boost::detail::default_argument>, _OutputIter =
ostream_iterator<float>, _Distance = ptrdiff_t]'
/usr/include/g++-3/stl_algobase.h:161: instantiated from
`__copy_dispatch<_InputIter, _OutputIter, _BoolType>::copy
(_InputIter, _InputIter, _OutputIter) [with _InputIter =
boost::iterator_adaptor<_Rb_tree_iterator<pair<const long int,
graph_element>, pair<const long int, graph_element> &, pair<const
long int, graph_element> *>,
boost::projection_iterator_policies<select_component<0> >, float,
float &, float *, boost::detail::default_argument,
boost::detail::default_argument>, _OutputIter =
ostream_iterator<float>, _BoolType = __true_type]'
/usr/include/g++-3/stl_algobase.h:188: instantiated from `copy
(_InputIter, _InputIter, _OutputIter) [with _InputIter =
boost::iterator_adaptor<_Rb_tree_iterator<pair<const long int,
graph_element>, pair<const long int, graph_element> &, pair<const
long int, graph_element> *>,
boost::projection_iterator_policies<select_component<0> >, float,
float &, float *, boost::detail::default_argument,
boost::detail::default_argument>, _OutputIter =
ostream_iterator<float>]'
graph-test.C:30: instantiated from here
/home/apicco/install/boost_1_28_0/boost/iterator_adaptors.hpp:1247:
no match for call to `(const
select_component<0>) (pair<const long int, graph_element> &)'
graph.h:19: candidates are: const float
&select_component<index>::operator() (const graph_element &) const
[with int index = 0]
graph.h:22: float &select_component<index>::operator
()
(graph_element &) const [with int index = 0]

Compilation exited abnormally with code 1 at Tue Sep 24 11:14:11

Info: <http://www.boost.org>
Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl>
Unsubscribe: <mailto:boost-users-unsubscribe_at_[hidden]>
 

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/


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