Cryptic C++ Code of the Day

I’m working on implementing some new evolutionary alignment models into my recently published alignment program Ngila. In the process I’m rearranging Ngila’s code based on lessons I’ve learned on more recent projects, including using x-macros and the Boost libraries.

One task that I needed to program today was to take a string of sequence data that may contain gaps and copy it to another string removing any gap characters. Now I could use the following routine:

std::string ss_gaps = "-+="; // chars to remove
std::string s = "aaa---ggtgct"; // the sequence data
std::string t; // the destination sequence
for(size_t i=0;i<s.size();++i)
{
	if(ss_gaps.find(s[i]) == std::string::npos)
		t.push_back(s[i]);
}

But that for loop is boring. Instead I decided to employ the standard template library and the boost libraries to craft a much cooler ‘single’ line of code to do the same thing:

std::remove_copy_if(s.begin(), s.end(), std::back_inserter(t),
    boost::bind(boost::mem_fn<std::string::size_type,std::string, 
    std::string::value_type, std::string::size_type>(&std::string::find),
    ss_gaps, _1, 0) != std::string::npos );

This line is more complicated that it should be because std::string::find is an overloaded function, requiring additional complexity in the code that a non overloaded function wouldn’t needed, e.g.

std::remove_copy_if(s.begin(), s.end(), std::back_inserter(t),
    boost::bind(strchr, ss_gaps.c_str(), _1) != (char*)NULL);

or even

std::remove_copy_if(s.begin(), s.end(), std::back_inserter(t), stl::bind2nd(equal_to<char>(), '-'));

or even

using boost::lambda;
std::remove_copy_if(s.begin(), s.end(), std::back_inserter(t), _1 == '-');

Now, isn’t that more interesting than a boring for loop?

TrackBack URL for this entry: http://scit.us/cgi-bin/mt/mt-tb.fcgi/972.

Use KwickXML Formatting to markup your comments, acceptable tags: <b> <blockquote> <br> <code> <em> <email> <h1> <h2> <h3> <h4> <h5> <h6> <i> <li> <list> <ol> <p> <qref> <quote> <s> <strong> <sub> <sup> <u> <ul> <url>. You may need to refresh before you will see your comment.




Remember personal info?

  


Posted by ACW on August 8, 2007 6:20 PM

In Lisp, it’s

(remove-if #'(lambda (char) (find char "-+=")) s)