String Trimmer and trimmed Input routine As I thought about this question on SO, I realized that I wanted to implement either a string trimmer or a trimmed string inputter. 

This is what I came up with, but I have a nagging feeling I could have done better.

Would you critique this, please?

#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;cassert&gt;

template &lt;typename Ch, typename Tr, typename Alloc&gt;
void
trim(std::basic_string&lt;Ch, Tr, Alloc&gt;&amp; str, const std::locale&amp; loc)
{
  // (b,e)=ltrim(str)
  typename std::basic_string&lt;Ch, Tr, Alloc&gt;::const_iterator b = str.begin();
  typename std::basic_string&lt;Ch, Tr, Alloc&gt;::const_iterator e = str.end();
  while( b != e &amp;&amp; std::isspace(*b, loc) )
    b++;

  // (b,e)=rtrim(b,e)
  // Query: this loop looks u-g-l-y. Can it be less ugly?
  while( b != e ) {
    e--;
    if(!std::isspace(*e, loc)) {
      e++;
      break;
    }
  }

  // str=(b,e)
  // Query: this string self-assigns (sort of). Is this UB?
  str.assign(b, e);
}

template &lt;typename Ch, typename Tr, typename Alloc&gt;
std::basic_istream&lt;Ch,Tr&gt;&amp;
getTrimmedLine(std::basic_istream&lt;Ch,Tr&gt;&amp; is,
  std::basic_string&lt;Ch, Tr, Alloc&gt;&amp; str)
{

  // Get raw data from input
  std::getline(is, str);

  // And trim it
  trim(str, is.getloc());

  return is;
}

#define TEST
#ifdef TEST
template&lt;typename T, std::size_t N&gt;
std::size_t countof( T (&amp; a)[N] ) { return N; }

int main () {
  const char * const inputs[] = {
    "simple", " front", "back ", " both ",
    "  front2", "back2  ", "  both2  ",
    "\n", "", "\n\n\n",
    "  \n", "  ", "  \n\n\n"
  };
  const char * const outputs[] = {
    "simple", "front", "back", "both",
    "front2", "back2", "both2",
    "", "", "",
    "", "", ""
  };

  assert(countof(inputs) == countof(outputs));

  for(std::size_t i = 0; i &lt; countof(inputs); i++) {
    std::istringstream is(inputs[i]);
    std::string result;
    getTrimmedLine(is, result);
    assert(result == outputs[i]);
  }
}
#endif
typename std::basic_string&lt;Ch, Tr, Alloc&gt;::const_iterator e = str.end();
...

// Query: this loop looks u-g-l-y. Can it be less ugly?
  while( b != e ) {
    e--;
    if(!std::isspace(*e, loc)) {
      e++;
      break;
    }
  }


This looks weird and tends to go UB.

1) e = str.end();

2) e--; /* it's better to use --e in this case */ you move one more far position after end()!!!

3) std::isspace(*e, loc) &lt;--- UB, accessing the memory that haven't been allocated

If you need to find the first and the last spaces in the string, use this:

b = find_if(str.begin(),  str.end(),  isspace_predicate);
e = find_if(str.rbegin(), str.rend(), isspace_predicate);