Boost::Bimap equivalent of bidirectional multimap - c++

First part of the question is that I am trying to use boost::bimap, but from the documentation it is unclear to me how to define a bidirectional multimap.
The second part of the question is that I need it to be a map in one direction and a multimap in the other direction, can this be done using boost::bimap ?
Has anyone experience of this or can point me to the correct page ?

All is in documentation... http://www.boost.org/doc/libs/1_51_0/libs/bimap/doc/html/boost_bimap/the_tutorial/discovering_the_bimap_framework.html
typedef boost::bimap<bimaps::multiset_of<int>, bimaps::set_of<int>> bimap_t;
Example.
#include <iostream>
#include <boost/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
namespace bimaps = boost::bimaps;
int main()
{
typedef boost::bimap<bimaps::multiset_of<int>, bimaps::set_of<int>> bimap_t;
typedef bimap_t::value_type value_type;
bimap_t bimap;
bimap.insert(value_type(1, 1));
bimap.insert(value_type(1, 2));
auto& left = bimap.left;
auto it = left.find(1);
std::cout << "LEFT" << std::endl;
for (; it != left.end(); ++it)
{
std::cout << it->first << " " << it->second << std::endl;
}
auto& right = bimap.right;
auto r_it = right.find(2);
std::cout << "RIGHT" << std::endl;
for (; r_it != right.end(); ++r_it)
{
std::cout << r_it->first << " " << r_it->second << std::endl;
}
}

The answer from ForEverR is partially correct for the first part of your question (how to define a bidirectional multimap?).
For the second part (accessing a bimap which is a map in one direction and a multimap in the other direction) It is not correct.
A correct way to access would be [ http://rextester.com/BXBDHN12336 ]:
//bimap operations
#include <boost/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
int main()
{
typedef boost::bimap<boost::bimaps::multiset_of<int>, boost::bimaps::set_of<int>> bimap_t;
typedef bimap_t::value_type value_type;
bimap_t bimap;
bimap.insert(value_type(1, 1));
bimap.insert(value_type(10, 50));
bimap.insert(value_type(1, 2));
bimap.insert(value_type(9, 15));
typedef bimap_t::left_const_iterator l_itr_t;
typedef std::pair<l_itr_t,l_itr_t> l_itr_range_t;
l_itr_range_t ii = bimap.left.equal_range(1);
std::cout << "LEFT" << std::endl;
for(l_itr_t it = ii.first; it != ii.second; ++it)
{
std::cout << "Key = " << it->first << " Value = " << it->second << std::endl;
}
std::cout << "RIGHT" << std::endl;
std::cout << "Key = " << 1 << " Value = " << bimap.right.at(1) << std::endl;
}
stdout:
LEFT
Key = 1 Value = 1
Key = 1 Value = 2
RIGHT
Key = 1 Value = 1
The example from ForEverR 'seems' to work because of the order of the data inserted but check out the results when you insert another couple at the end bimap.insert(value_type(9, 15));:
#include <iostream>
#include <boost/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
namespace bimaps = boost::bimaps;
int main()
{
typedef boost::bimap<bimaps::multiset_of<int>, bimaps::set_of<int>> bimap_t;
typedef bimap_t::value_type value_type;
bimap_t bimap;
bimap.insert(value_type(1, 1));
bimap.insert(value_type(1, 2));
bimap.insert(value_type(9, 15));
auto& left = bimap.left;
auto it = left.find(1);
std::cout << "LEFT" << std::endl;
for (; it != left.end(); ++it)
{
std::cout << it->first << " " << it->second << std::endl;
}
auto& right = bimap.right;
auto r_it = right.find(2);
std::cout << "RIGHT" << std::endl;
for (; r_it != right.end(); ++r_it)
{
std::cout << r_it->first << " " << r_it->second << std::endl;
}
}
stdout:
LEFT
1 1
1 2
9 15
RIGHT
2 1
15 9

Related

Problem with visibility polygon computation in CGAL

I'm using CGAL (v. 4.14-2) to compute the visibility region (polygon) within a simple polygon from one of its vertices, using the Simple_polygon_visibility_2 class.
On a particular combination of polygon/vertex, I'm getting the following assertion error:
terminate called after throwing an instance of 'CGAL::Assertion_exception'
what(): CGAL ERROR: assertion violation!
Expr: k+1<vertices.size()
File: /usr/include/CGAL/Simple_polygon_visibility_2.h
Line: 678
This occurs in the method scan_edges of the class Simple_polygon_visibility_2, it seems like there should be some intersection with the given segment/ray, but none was found.
When I run the same code with the class Triangular_expansion_visibility_2, it seems to work, giving the output:
Regularized visibility region of q has 8 edges:
[7968 492 -> 7938 428]
[7884 408 -> 7968 492]
[8040 428 -> 7884 408]
[8090.99 428 -> 8040 428]
[8105.55 458.865 -> 8090.99 428]
[8090 456 -> 8105.55 458.865]
[7968 446 -> 8090 456]
[7938 428 -> 7968 446]
Here's a minimal working example:
#include <CGAL/Arr_naive_point_location.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Simple_polygon_visibility_2.h>
#include <CGAL/Triangular_expansion_visibility_2.h>
#include <fstream>
#include <iostream>
#include <string>
#include <list>
#include <vector>
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef Kernel::Segment_2 Segment_2;
typedef CGAL::Polygon_2<Kernel, std::list<Point_2>> Polygon_2;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Face_handle Face_handle;
typedef Arrangement_2::Vertex_handle ArrVertex_handle;
typedef Arrangement_2::Edge_const_iterator Edge_const_iterator;
typedef Arrangement_2::Ccb_halfedge_circulator Ccb_halfedge_circulator;
using namespace std;
vector<Point_2> readInput() {
vector<Point_2> Points;
ifstream File;
File.open("polygon");
string Line;
long int Idx, XCoord, YCoord;
while (getline(File, Line)) {
istringstream Iss(Line);
Iss >> Idx >> XCoord >> YCoord;
Points.push_back({XCoord, YCoord});
}
return Points;
}
int main() {
// create environment
std::vector<Segment_2> segments;
Arrangement_2 env;
Segment_2 CurrSegment;
Polygon_2 AuxPoly;
auto Points = readInput();
auto QueryPt = Points[0];
ArrVertex_handle CurrPtHandle =
env.insert_in_face_interior(QueryPt, env.unbounded_face());
AuxPoly.push_back(Points[0]);
ArrVertex_handle NextPtHandle = CurrPtHandle;
ArrVertex_handle QueryPtHandle = CurrPtHandle;
for (auto i = 1; i < Points.size(); ++i) {
NextPtHandle = env.insert_in_face_interior(Points[i], env.unbounded_face());
CurrSegment = Segment_2(CurrPtHandle->point(), NextPtHandle->point());
env.insert_at_vertices(CurrSegment, CurrPtHandle, NextPtHandle);
CurrPtHandle = NextPtHandle;
AuxPoly.push_back(Points[i]);
}
assert(AuxPoly.is_simple());
CurrSegment = Segment_2(CurrPtHandle->point(), QueryPtHandle->point());
auto HalfEHandle =
env.insert_at_vertices(CurrSegment, CurrPtHandle, QueryPtHandle);
if (HalfEHandle->face()->is_unbounded()) {
// there are exactly two incident halfedges in the query point
auto FirstHalfE = HalfEHandle->target()->incident_halfedges();
HalfEHandle = (FirstHalfE != HalfEHandle) ? FirstHalfE : next(FirstHalfE, 1);
}
// compute non regularized visibility area
// Define visibiliy object type that computes regularized visibility area
typedef CGAL::Simple_polygon_visibility_2<Arrangement_2, CGAL::Tag_true> RSPV;
// typedef CGAL::Triangular_expansion_visibility_2<Arrangement_2, CGAL::Tag_true> RSPV;
Arrangement_2 regular_output;
RSPV regular_visibility(env);
regular_visibility.compute_visibility(QueryPtHandle->point(), HalfEHandle, regular_output);
std::cout << "Regularized visibility region of q has "
<< regular_output.number_of_edges() << " edges:" << std::endl;
for (Edge_const_iterator eit = regular_output.edges_begin();
eit != regular_output.edges_end(); ++eit)
std::cout << "[" << eit->source()->point() << " -> "
<< eit->target()->point() << "]" << std::endl;
return 0;
}
an auxiliary file arr_print.h to print the arrangement:
#ifndef _PRINT_ARR_H_
#define _PRINT_ARR_H_
#include <iostream>
//-----------------------------------------------------------------------------
// Print all neighboring vertices to a given arrangement vertex.
//
template<class Arrangement>
void print_neighboring_vertices (typename Arrangement::Vertex_const_handle v)
{
if (v->is_isolated())
{
std::cout << "The vertex (" << v->point() << ") is isolated" << std::endl;
return;
}
typename Arrangement::Halfedge_around_vertex_const_circulator first, curr;
typename Arrangement::Vertex_const_handle u;
std::cout << "The neighbors of the vertex (" << v->point() << ") are:";
first = curr = v->incident_halfedges();
do
{
// Note that the current halfedge is (u -> v):
u = curr->source();
std::cout << " (" << u->point() << ")";
++curr;
} while (curr != first);
std::cout << std::endl;
return;
}
//-----------------------------------------------------------------------------
// Print all vertices (points) and edges (curves) along a connected component
// boundary.
//
template<class Arrangement>
void print_ccb (typename Arrangement::Ccb_halfedge_const_circulator circ)
{
typename Arrangement::Ccb_halfedge_const_circulator curr = circ;
typename Arrangement::Halfedge_const_handle he;
std::cout << "(" << curr->source()->point() << ")";
do
{
he = curr;
std::cout << " [" << he->curve() << "] "
<< "(" << he->target()->point() << ")";
++curr;
} while (curr != circ);
std::cout << std::endl;
return;
}
//-----------------------------------------------------------------------------
// Print the boundary description of an arrangement face.
//
template<class Arrangement>
void print_face (typename Arrangement::Face_const_handle f)
{
// Print the outer boundary.
if (f->is_unbounded())
{
std::cout << "Unbounded face. " << std::endl;
}
else
{
std::cout << "Outer boundary: ";
print_ccb<Arrangement> (f->outer_ccb());
}
// Print the boundary of each of the holes.
typename Arrangement::Hole_const_iterator hole;
int index = 1;
for (hole = f->holes_begin(); hole != f->holes_end(); ++hole, ++index)
{
std::cout << " Hole #" << index << ": ";
print_ccb<Arrangement> (*hole);
}
// Print the isolated vertices.
typename Arrangement::Isolated_vertex_const_iterator iv;
for (iv = f->isolated_vertices_begin(), index = 1;
iv != f->isolated_vertices_end(); ++iv, ++index)
{
std::cout << " Isolated vertex #" << index << ": "
<< "(" << iv->point() << ")" << std::endl;
}
return;
}
//-----------------------------------------------------------------------------
// Print the given arrangement.
//
template<class Arrangement>
void print_arrangement (const Arrangement& arr)
{
// CGAL_precondition (arr.is_valid());
// Print the arrangement vertices.
typename Arrangement::Vertex_const_iterator vit;
std::cout << arr.number_of_vertices() << " vertices:" << std::endl;
for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit)
{
std::cout << "(" << vit->point() << ")";
if (vit->is_isolated())
std::cout << " - Isolated." << std::endl;
else
std::cout << " - degree " << vit->degree() << std::endl;
}
// Print the arrangement edges.
typename Arrangement::Edge_const_iterator eit;
std::cout << arr.number_of_edges() << " edges:" << std::endl;
for (eit = arr.edges_begin(); eit != arr.edges_end(); ++eit)
std::cout << "[" << eit->curve() << "]" << std::endl;
// Print the arrangement faces.
typename Arrangement::Face_const_iterator fit;
std::cout << arr.number_of_faces() << " faces:" << std::endl;
for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit)
print_face<Arrangement> (fit);
return;
}
#endif
The input polygon:
input polygon
The input file has in each line the polygon vertex id, followed by its x- and-coordinates. The query point is the one with id 1716.
Could anyone help me with this issue?
Thank you all in advance.

Shortest solution to permute the elements of a std::vector using stl

Assume that you have an std::vector<T> of some type T and a selection of indices std::vector<int> of this vector. Now I'm looking for a function permute(const std::vector<T>& vector, const std::vector<int>& indices), that returns the permuted vector with respect to the given indices.
The problem is easily solved by writing a short function like depicted below:
template<typename T>
std::vector<T> permute(const std::vector<T>& matrix, const std::vector<int>& indices) {
std::vector<T> ret;
for (auto p : indices) {
ret.push_back(matrix[p]);
}
return ret;
}
int main(int, char**) {
std::vector<int> perm{ 1,2,0 };
std::vector<std::vector<double>> matrix = { {1.,2.,3.},{4.,5.,6.},{7.,8.,9.} };
auto matrixPerm=permute(matrix, perm);
std::cout << matrixPerm[0][0] << " == " << matrix[1][0] << std::endl;
std::cout << matrixPerm[1][0] << " == " << matrix[2][0] << std::endl;
std::cout << matrixPerm[2][0] << " == " << matrix[0][0] << std::endl;
}
I'm now wondering what might be most elegant version of this program, if we can use STL or even the Boost libraries. In STL for example we have shuffle(), but we cannot say in what way to shuffle.
Does anyone now, how to shorten the function?
Solution using std::transform()
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
int main(int, char**) {
std::vector<int> perm{ 1,2,0 };
std::vector<std::vector<double>> matrix = { {1.,2.,3.},{4.,5.,6.},{7.,8.,9.} };
std::vector<std::vector<double>> output;
std::transform(perm.begin(), perm.end(), std::back_inserter(output), [&](int i) { return matrix[i]; });
std::cout << output[0][0] << " == " << matrix[1][0] << std::endl;
std::cout << output[1][0] << " == " << matrix[2][0] << std::endl;
std::cout << output[2][0] << " == " << matrix[0][0] << std::endl;
}
You can transform the indices into iterators and then create an indirect range with Boost.Range.
#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/range/adaptor/indirected.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp>
int main(int, char**) {
using namespace boost::adaptors;
std::vector<int> perm{ 1,2,0 };
std::vector<std::vector<double>> matrix = { {1.,2.,3.},{4.,5.,6.},{7.,8.,9.} };
std::vector<std::vector<double>> output;
auto permutation = perm | transformed( [&matrix](int x) { return matrix.begin() + x; }) | indirected;
boost::copy(
permutation,
std::back_inserter(output));
std::cout << output[0][0] << " == " << matrix[1][0] << std::endl;
std::cout << output[1][0] << " == " << matrix[2][0] << std::endl;
std::cout << output[2][0] << " == " << matrix[0][0] << std::endl;
}
You could skip copying the elements and just process the range if you don't need a real vector.
The range adaptor uses the permutation iterator from the Boost.Iterator library. You can also use this directly, but you have to manually define begin and end:
auto begin = make_permutation_iterator( matrix.begin(), perm.begin() );
auto end = make_permutation_iterator( matrix.end(), perm.end() );
std::copy(begin, end, std::back_inserter(output) );

How to print Edges of Delaunay Graph?

Following this: How to print the faces of a Voronoi diagram?, I now have:
#include <iostream>
#include <fstream>
#include <cassert>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Segment_Delaunay_graph_2.h>
#include <CGAL/Segment_Delaunay_graph_adaptation_policies_2.h>
#include <CGAL/Segment_Delaunay_graph_traits_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Segment_Delaunay_graph_traits_2<K> Gt;
typedef CGAL::Segment_Delaunay_graph_2<Gt> DT;
int main() {
std::ifstream ifs("data.cin");
assert( ifs );
DT vd;
DT::Site_2 site;
// read the sites from the stream and insert them in the diagram
while ( ifs >> site ) { vd.insert( site ); }
ifs.close();
// validate the diagram
assert( vd.is_valid(true, 1) );
std::cout << std::endl << std::endl;
// Iterate over edges
DT::Finite_edges_iterator eit = vd.finite_edges_begin();
for (int k = 1; eit != vd.finite_edges_end(); ++eit, ++k) {
DT::Edge e = *eit;
//std::cout << e << std::endl;
}
}
However, an edge cannot be printed that simply (with cout). How to do it?
Here is the error from another attempt:
/home/gsamaras/CGAL-4.7/code/DelaunayTOvoronoi/delTovor.cpp:30:27: error: ‘CGAL::Triangulation_ds_edge_iterator_2<CGAL::Triangulation_data_structure_2<CGAL::Segment_Delaunay_graph_vertex_base_2<CGAL::Segment_Delaunay_graph_storage_traits_2<CGAL::Segment_Delaunay_graph_traits_2<CGAL::Epick> >, CGAL::Triangulation_ds_vertex_base_2<void> >, CGAL::Segment_Delaunay_graph_face_base_2<CGAL::Segment_Delaunay_graph_traits_2<CGAL::Epick>, CGAL::Triangulation_ds_face_base_2<void> > >, true>::Edge’ has no member named ‘site’
std::cout << eit->site() << std::endl;
^
You can print the sites forming the edge like this:
for (int k = 1; eit != vd.finite_edges_end(); ++eit, ++k) {
DT::Edge e = *eit;
std::cout << "k = " << k << std::endl;
if ( vd.is_infinite(e.first->vertex( vd.ccw(e.second) )) )
std::cout << "infinite\n";
else
std::cout << e.first->vertex( vd.ccw(e.second) )->site() << std::endl;
if ( vd.is_infinite(e.first->vertex( vd.cw(e.second) )) )
std::cout << "infinite\n";
else
std::cout << e.first->vertex( vd.cw(e.second) )->site() << std::endl;
if ( vd.is_infinite(e.first->vertex( e.second )) )
std::cout << "infinite\n";
else
std::cout << e.first->vertex( e.second )->site() << std::endl;
if ( vd.is_infinite(vd.tds().mirror_vertex(e.first, e.second) ) )
std::cout << "infinite\n";
else
std::cout << vd.tds().mirror_vertex(e.first, e.second)->site() << std::endl;
}

Replace BOOST_FOREACH with "pure" C++11 alternative?

Is it possible to replace the BOOST_FOREACH in this example with a "pure" C++11 equivalent?
#include <map>
#include <functional>
#include <boost/foreach.hpp>
#include <iostream>
int main() {
std::map<int, std::string> map = {std::make_pair(1,"one"), std::make_pair(2,"two")};
int k;
std::string v;
BOOST_FOREACH(std::tie(k, v), map) {
std::cout << "k=" << k << " - " << v << std::endl;
}
}
The key feature being keeping the key/value pair in the references to k and v.
I tried:
for(std::tie(k,v) : map)
{
std::cout << "k=" << k << " - " << v << std::endl;
}
and
auto i = std::tie(k,v);
for(i : map)
{
std::cout << "k=" << k << " - " << v << std::endl;
}
But none of the ranged based for loop ideas seemed to work. Presumably the ranged based for loop is required to have a declaration before the :, since even:
std::vector<int> test;
int i;
for (i : test);
Isn't valid.
The closest equivalent I can find is:
for (auto it = map.begin(); it!=map.end() && (std::tie(k,v)=*it,1); ++it)
{
std::cout << "k=" << k << " - " << v << std::endl;
}
which isn't quite as succinct as the BOOST_FOREACH version!
Is there a way to express the same thing succinctly without boost in C++11?
for (auto & i : map)
{
std::tie(k,v) = i;
// your code here
}
This produces the same output as the Boost macro
for( auto const& k : map ) {
std::cout << "k = " << k.first << " - " << k.second << std::endl;
}
With C++17 this can now be done using structured bindings, for instance:
#include <map>
#include <string>
#include <iostream>
int main() {
const std::map<std::string, std::string> map = {std::make_pair("hello", "world")};
for (auto& [k,v]: map) {
std::cout << "k=" << k << ", v=" << v << "\n";
}
}
This is certainly what I'd choose to do in newer projects.

multi_index composite_key replace with iterator

Is there anyway to loop through an index in a boost::multi_index and perform a replace?
#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
using namespace boost::multi_index;
using namespace std;
struct name_record
{
public:
name_record(string given_name_,string family_name_,string other_name_)
{
given_name=given_name_;
family_name=family_name_;
other_name=other_name_;
}
string given_name;
string family_name;
string other_name;
string get_name() const { return given_name + " " + family_name + " " + other_name; }
void setnew(string chg)
{
given_name = given_name + chg;
family_name = family_name + chg;
}
};
struct NameIndex{};
typedef multi_index_container<
name_record,
indexed_by<
ordered_non_unique<
tag<NameIndex>,
composite_key
<
name_record,
BOOST_MULTI_INDEX_MEMBER(name_record,string, name_record::given_name),
BOOST_MULTI_INDEX_MEMBER(name_record,string, name_record::family_name)
>
>
>
> name_record_set;
typedef boost::multi_index::index<name_record_set,NameIndex>::type::iterator IteratorType;
typedef boost::multi_index::index<name_record_set,NameIndex>::type NameIndexType;
void printContainer(name_record_set & ns)
{
cout << endl << "PrintContainer" << endl << "-------------" << endl;
IteratorType it1 = ns.begin();
IteratorType it2 = ns.end ();
while (it1 != it2)
{
cout<<it1->get_name()<<endl;
it1++;
}
cout << "--------------" << endl << endl;
}
void modifyContainer(name_record_set & ns)
{
cout << endl << "ModifyContainer" << endl << "-------------" << endl;
IteratorType it3;
IteratorType it4;
NameIndexType & idx1 = ns.get<NameIndex>();
IteratorType it1 = idx1.begin();
IteratorType it2 = idx1.end();
while (it1 != it2)
{
cout<<it1->get_name()<<endl;
name_record nr = *it1;
nr.setnew("_CHG");
bool res = idx1.replace(it1,nr);
cout << "result is: " << res << endl;
it1++;
}
cout << "--------------" << endl << endl;
}
int main()
{
name_record_set ns;
ns.insert( name_record("Joe","Smith","ENTRY1") );
ns.insert( name_record("Robert","Brown","ENTRY2") );
ns.insert( name_record("Robert","Nightingale","ENTRY3") );
ns.insert( name_record("Marc","Tuxedo","ENTRY4") );
printContainer (ns);
modifyContainer (ns);
printContainer (ns);
return 0;
}
PrintContainer
-------------
Joe Smith ENTRY1
Marc Tuxedo ENTRY4
Robert Brown ENTRY2
Robert Nightingale ENTRY3
--------------
ModifyContainer
-------------
Joe Smith ENTRY1
result is: 1
Marc Tuxedo ENTRY4
result is: 1
Robert Brown ENTRY2
result is: 1
--------------
PrintContainer
-------------
Joe_CHG Smith_CHG ENTRY1
Marc_CHG Tuxedo_CHG ENTRY4
Robert Nightingale ENTRY3
Robert_CHG Brown_CHG ENTRY2
--------------
while (it1 != it2)
{
cout<<it1->get_name()<<endl;
name_record nr = *it1;
nr.setnew("_CHG");
bool res = idx1.replace(it1,nr);
cout << "result is: " << res << endl;
it1++;
}
The problem with this code is that, once you've replaced an element x, this is automatically reordered to its new position, so that it1, which keeps pointing to x, "jumps" through the sequence and might skip or revisit elements.
The solution is to add a level of indirection and collect iterators to all the elements before beginning the replacements:
#include <vector>
#include <boost/iterator/counting_iterator.hpp>
void modifyContainer(name_record_set & ns)
{
cout << endl << "ModifyContainer" << endl << "-------------" << endl;
NameIndexType & idx1 = ns.get<NameIndex>();
std::vector<IteratorType> v(
boost::make_counting_iterator(idx1.begin()),
boost::make_counting_iterator(idx1.end()));
std::vector<IteratorType>::iterator it1=v.begin(),
it2=v.end();
while (it1 != it2)
{
cout<<(*it1)->get_name()<<endl;
name_record nr = **it1;
nr.setnew("_CHG");
bool res = idx1.replace(*it1,nr);
cout << "result is: " << res << endl;
it1++;
}
cout << "--------------" << endl << endl;
}
In case you didn't use it before, the make_counting_iterator bit is just a compact way to populate the vector with iterators to all the elements of ns.