This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Online Docs Chapter 22: Correct Transformations


All,

I was recently looking into string transformations and I came across the
libstdc++ docs on C++ localization. I was pleased to find a clean, portable
example that I could use in my project, but I was bothered by the need for
wrapper structs to access the global function templates toupper and tolower.

The author refered to a final version using bind2nd that he was unable to
get working in any available compiler. Further research uncovered
an email from Philip Martin on gcc-bugs
<http://gcc.gnu.org/ml/gcc-bugs/2001-12/msg00698.html> that implies that
using bind2nd is either not possible because of C++ idiosyncracies or very
tricky to get right. The difficulty seemed to be in using the global
function templates, so I set about looking at using the ctype facet
directly, and came up with the following:

#include <iterator>
#include <locale>
#include <string>
#include <algorithm>
#include <functional>

int main()
{
  std::string  s ("Some Kind Of Initial Input Goes Here");

  // Select the ctype facet of the default locale
  const std::ctype<char> *ct =
    & std::use_facet<std::ctype<char> >(std::locale());

  // Change everything into upper case
  std::transform (s.begin(), s.end(), s.begin(),
      std::bind1st(std::mem_fun(&std::ctype<char>::toupper),ct));

  // Change everything into lower case
  std::transform (s.begin(), s.end(), s.begin(),
      std::bind1st(std::mem_fun(&std::ctype<char>::tolower),ct));

  // Change everything back into upper case, but store the
  // result in a different string
  std::string  capital_s;
  std::transform (s.begin(), s.end(), std::back_inserter(capital_s),
      std::bind1st(std::mem_fun(&std::ctype<char>::toupper),ct));

  return 0;
}

This seems to work pretty well, although it's a bit cumbersome to read, and
it doesn't have the convenience of being a template function (the character
type must be specified explicitly). I'd be interested in comparing it to the
version that's supposed to used bind2nd and the global tolower function
template, if anyone has the details on how that's supposed to work.

Portablilty note: This code has the disadvantage of being less portable than
the code in the documentation, even though it adheres to the standard.
Compilers without support for template return parameters (notably, the Sun
Workshop 6 compiler) need to use a different version of use_facet:

const std::ctype<char> *ct =
  & std::use_facet<std::ctype<char> > (std::locale(), (std::ctype<char>*)0);

Any comments or critiques are welcome.

Christopher


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]