
Is there a method in the boost library to iterate a vector of boost::tuple objects, comparing the 1st element in the tuple of each tuple to a value that I specify? My tuple is setup like so: typedef boost::tuple<int, int, char const*> Tuple; typedef std::vector<Tuple> ErrorStringMap; ErrorStringMap mystrings = tuple_list_of (10, "10", "ten") (20, "20", "twenty") (30, "30", "thirty") (10, "10", "ten"); I want to search the vector of tuples and do something with every tuple that has the number 10 as the first element in the tuple.

On Wed, Apr 11, 2012 at 11:33 PM, Robert Dailey <rcdailey.lists@gmail.com>wrote:
Is there a method in the boost library to iterate a vector of boost::tuple objects, comparing the 1st element in the tuple of each tuple to a value that I specify? My tuple is setup like so:
typedef boost::tuple<int, int, char const*> Tuple; typedef std::vector<Tuple> ErrorStringMap;
ErrorStringMap mystrings = tuple_list_of (10, "10", "ten") (20, "20", "twenty") (30, "30", "thirty") (10, "10", "ten");
I want to search the vector of tuples and do something with every tuple that has the number 10 as the first element in the tuple.
*** Not Tested or Compiled *** #include <boost/range.hpp> #include <boost/range/adaptors/filtered.hpp> // ... and maybe some other range headers #include <boost/bind.hpp> for_each( mystrings | boost::adaptors::filtered( boost::bind( get<0>, _1 ) == 10 ), yourAction ); Just off the top of my head, no idea if that will really work. HTH - Rob.

On 04/12/2012 10:36 AM, Robert Jones wrote:
On Wed, Apr 11, 2012 at 11:33 PM, Robert Dailey<rcdailey.lists@gmail.com>wrote:
Is there a method in the boost library to iterate a vector of boost::tuple objects, comparing the 1st element in the tuple of each tuple to a value that I specify? My tuple is setup like so:
typedef boost::tuple<int, int, char const*> Tuple; typedef std::vector<Tuple> ErrorStringMap;
ErrorStringMap mystrings = tuple_list_of (10, "10", "ten") (20, "20", "twenty") (30, "30", "thirty") (10, "10", "ten");
I want to search the vector of tuples and do something with every tuple that has the number 10 as the first element in the tuple.
*** Not Tested or Compiled ***
#include<boost/range.hpp> #include<boost/range/adaptors/filtered.hpp> // ... and maybe some other range headers #include<boost/bind.hpp>
for_each( mystrings | boost::adaptors::filtered( boost::bind( get<0>, _1 ) == 10 ), yourAction );
The Phoenix solution would look like the following: #include<boost/range.hpp> #include<boost/range/adaptors/filtered.hpp> // ... and maybe some other range headers #include<boost/phoenix.hpp> #include<boost/fusion/adapted/tuple.hpp> for_each( mystrings | boost::adaptors::filtered( boost::phoenix::at_c<0>(_1) == 10 ), yourAction ); or: for_each( mystrings, if_(boost::phoenix::at_c<0>(_1) == 10)[yourAction]);
Just off the top of my head, no idea if that will really work.
HTH
- Rob.
_______________________________________________ Unsubscribe& other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 12/04/12 10:36, Robert Jones wrote:
On Wed, Apr 11, 2012 at 11:33 PM, Robert Dailey<rcdailey.lists@gmail.com>wrote:
Is there a method in the boost library to iterate a vector of boost::tuple objects, comparing the 1st element in the tuple of each tuple to a value that I specify? My tuple is setup like so:
typedef boost::tuple<int, int, char const*> Tuple; typedef std::vector<Tuple> ErrorStringMap;
ErrorStringMap mystrings = tuple_list_of (10, "10", "ten") (20, "20", "twenty") (30, "30", "thirty") (10, "10", "ten");
I want to search the vector of tuples and do something with every tuple that has the number 10 as the first element in the tuple.
*** Not Tested or Compiled ***
#include<boost/range.hpp> #include<boost/range/adaptors/filtered.hpp> // ... and maybe some other range headers #include<boost/bind.hpp>
for_each( mystrings | boost::adaptors::filtered( boost::bind( get<0>, _1 ) == 10 ), yourAction );
You probably can't take the address of get<0>. Also, you could remove the dependence on filtered by using find_if instead of for_each.

On Thu, Apr 12, 2012 at 6:13 AM, Mathias Gaunard < mathias.gaunard@ens-lyon.org> wrote:
On 12/04/12 10:36, Robert Jones wrote:
On Wed, Apr 11, 2012 at 11:33 PM, Robert Dailey<rcdailey.lists@gmail.** com <rcdailey.lists@gmail.com>>wrote:
Is there a method in the boost library to iterate a vector of
boost::tuple objects, comparing the 1st element in the tuple of each tuple to a value that I specify? My tuple is setup like so:
typedef boost::tuple<int, int, char const*> Tuple; typedef std::vector<Tuple> ErrorStringMap;
ErrorStringMap mystrings = tuple_list_of (10, "10", "ten") (20, "20", "twenty") (30, "30", "thirty") (10, "10", "ten");
I want to search the vector of tuples and do something with every tuple that has the number 10 as the first element in the tuple.
*** Not Tested or Compiled ***
#include<boost/range.hpp> #include<boost/range/adaptors/**filtered.hpp> // ... and maybe some other range headers #include<boost/bind.hpp>
for_each( mystrings | boost::adaptors::filtered( boost::bind( get<0>, _1 ) == 10 ), yourAction );
You probably can't take the address of get<0>.
Also, you could remove the dependence on filtered by using find_if instead of for_each.
I can't use phoenix, I'm still on boost 1.46.1. I try the following with boost::lambda: using namespace boost::lambda; using boost::lambda::_1; using boost::lambda::bind; ErrorStringMap::const_iterator it = std::find_if( mystrings.begin(), mystrings.end(), bind(&Tuple::get<0>, _1) == error_code ); if( it != mystrings.end() ) { return *it; } However I keep getting compiler error C2780, saying it's expecting N number of arguments. I'm on MSVC9. Why can't I get lambda to work??

On Mon, Apr 23, 2012 at 4:25 PM, Nathan Ridge <zeratul976@hotmail.com>wrote:
I can't use phoenix, I'm still on boost 1.46.1.
Phoenix is present in boost 1.46, in a subdirectory of Spirit.
Oh thanks. What namespace is it in? I tried boost::spirit::phoenix, and boost::phoenix... nothing works.

On 4/23/2012 2:34 PM, Robert Dailey wrote:
On Mon, Apr 23, 2012 at 4:25 PM, Nathan Ridge <zeratul976@hotmail.com>wrote:
I can't use phoenix, I'm still on boost 1.46.1.
Phoenix is present in boost 1.46, in a subdirectory of Spirit.
Oh thanks. What namespace is it in? I tried boost::spirit::phoenix, and boost::phoenix... nothing works.
Here's a link to the docs: http://www.boost.org/doc/libs/1_46_1/libs/spirit/phoenix/doc/html/index.html -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Mon, Apr 23, 2012 at 4:45 PM, Eric Niebler <eric@boostpro.com> wrote:
Here's a link to the docs:
http://www.boost.org/doc/libs/1_46_1/libs/spirit/phoenix/doc/html/index.html
I read that... thanks. I did not see anything in there indicating the namespace to use.

On Mon, Apr 23, 2012 at 4:34 PM, Robert Dailey <rcdailey.lists@gmail.com>wrote:
On Mon, Apr 23, 2012 at 4:25 PM, Nathan Ridge <zeratul976@hotmail.com>wrote:
I can't use phoenix, I'm still on boost 1.46.1.
Phoenix is present in boost 1.46, in a subdirectory of Spirit.
Oh thanks. What namespace is it in? I tried boost::spirit::phoenix, and boost::phoenix... nothing works.
Looks like the namespace is just 'phoenix'. There is no phoenix::placeholders namespace in 1.46 apparently, I'm including <boost/spirit/include/phoenix1.hpp>. I hope that's right. My code still isn't working: std::find_if( mystrings.begin(), mystrings.end(), bind(&Tuple::get<0>, arg1) == error_code ); I changed _1 to arg1 per the documentation (argN seems to be the phoenix-way). I only have a 'using namespace phoenix;' above that.

On Mon, Apr 23, 2012 at 4:50 PM, Nathan Ridge <zeratul976@hotmail.com>wrote:
I'm including <boost/spirit/include/phoenix1.hpp>. I hope that's right.
That's an old version of phoenix (phoenix v1).
Try <boost/spirit/include/phoenix.hpp>, which includes phoenix v2.
I included that one first, but it said it was deprecated and to use the v1 header. I took a lucky guess and included <boost/spirit/home/phoenix.hpp> and that one works as expected, and the phoenix namespace is inside of boost namespace like I expect. I'm assuming this is the correct one to use.

On 23 April 2012 22:55, Robert Dailey <rcdailey.lists@gmail.com> wrote:
On Mon, Apr 23, 2012 at 4:50 PM, Nathan Ridge <zeratul976@hotmail.com>wrote:
I'm including <boost/spirit/include/phoenix1.hpp>. I hope that's right.
That's an old version of phoenix (phoenix v1).
Try <boost/spirit/include/phoenix.hpp>, which includes phoenix v2.
I included that one first, but it said it was deprecated and to use the v1 header.
You probably used <boost/spirit/phoenix.hpp>, which was the deprecated v1 header. It suggested using <boost/spirit/include/phoenix1.hpp> instead, but that message was intended for existing v1 code. <boost/spirit/include/phoenix.hpp> is the correct v2 header. It was a bit confusing during the transition to the new directory structure. Here's the page from the spirit documentation which describes the header structure: http://www.boost.org/libs/spirit/doc/html/spirit/structure/include.html

I can't use phoenix, I'm still on boost 1.46.1.
Phoenix is present in boost 1.46, in a subdirectory of Spirit.
Oh thanks. What namespace is it in? I tried boost::spirit::phoenix, and boost::phoenix... nothing works.
It should be boost::phoenix. Take a look at e.g. libs/spirit/phoenix/example/users_manual/factorial.cpp Regards, Nate

On Thu, Apr 12, 2012 at 6:13 AM, Mathias Gaunard < mathias.gaunard@ens-lyon.org> wrote:
On 12/04/12 10:36, Robert Jones wrote:
*** Not Tested or Compiled ***
#include<boost/range.hpp> #include<boost/range/adaptors/**filtered.hpp> // ... and maybe some other range headers #include<boost/bind.hpp>
for_each( mystrings | boost::adaptors::filtered( boost::bind( get<0>, _1 ) == 10 ), yourAction );
You probably can't take the address of get<0>.
Also, you could remove the dependence on filtered by using find_if instead of for_each.
How would I use find_if() for this? I tried this: using namespace boost::phoenix; using namespace boost::phoenix::arg_names; using namespace boost::range; ErrorStringMap::const_iterator it = find_if( g_error_info, at_c<0>(_1) == error_code ); if( it != g_error_info.end() ) { return *it; } However I haven't used Boost.Range before and I don't see any documentation in Boost.Range about the binary-or operator being used with the algorithms. My above code won't compile, apparently find_if() won't take an actor as a predicate. No idea how to convert it though.

*** Not Tested or Compiled ***
#include<boost/range.hpp> #include<boost/range/adaptors/**filtered.hpp> // ... and maybe some other range headers #include<boost/bind.hpp>
for_each( mystrings | boost::adaptors::filtered( boost::bind( get<0>, _1 ) == 10 ), yourAction );
You probably can't take the address of get<0>.
Also, you could remove the dependence on filtered by using find_if instead of for_each.
How would I use find_if() for this? I tried this:
using namespace boost::phoenix; using namespace boost::phoenix::arg_names; using namespace boost::range;
ErrorStringMap::const_iterator it = find_if( g_error_info, at_c<0>(_1) == error_code );
if( it != g_error_info.end() ) { return *it; }
However I haven't used Boost.Range before and I don't see any documentation in Boost.Range about the binary-or operator being used with the algorithms. My above code won't compile, apparently find_if() won't take an actor as a predicate. No idea how to convert it though.
find_if() can take an actor as a predicate. You have a different problem. My guess would be that you need to include <boost/fusion/adapted/boost_tuple.hpp> in order for Fusion (which is used by phoenix's at_c) to recognize Boost.Tuple. If that doesn't fix the problem, please post a complete example that fails to compile for us to be able to help you further. Regards, Nate
participants (7)
-
Daniel James
-
Eric Niebler
-
Mathias Gaunard
-
Nathan Ridge
-
Robert Dailey
-
Robert Jones
-
Thomas Heller