Tuesday, June 22, 2010

Dealing with "deprecated" std::copy()

Although the issue of Microsoft having chosen, by the agency of its so-called "safe string" library, to deprecate large parts of the standard library in general, and std::copy() in particular, is hardly new, there's still some confusion in the community about what to do about it, and how to work around it if that's what you choose to do.

If, as I do on occasion, you choose not to suppress the warnings (by ignoring 4996, or by defining _SCL_SECURE_NO_WARNINGS) but instead want to ignore specifically for std::copy(), you can do it as follows:

#include <stlsoft/algorithms/std/alt.hpp>
#include <stlsoft/internal/safestr.h>

#if defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) && \
    defined(STLSOFT_COMPILER_IS_MSVC)
namespace std
{
  using ::stlsoft::std_copy;
# define copy    std_copy
}
#endif // compiler

By all means it's breaking the rules and introducing names into the std namespace. Nonetheless, we can sleep easy, since, hey, we didn't start the undermining of the standard!

The other problem is that, currently, stlsoft::std_copy() has no specialisations. It always uses long-hand iteration; no memcpy()-based block copying for random access iterators to POD types.

I hope you know me well enough by now for this to not need to be said. But it's important enough for me to have to say it explicitly, just in case: do not use this technique in library headers!

Sunday, June 6, 2010

STLSoft 1.9.98 changes to stlsoft::split()

As of STLSoft 1.9.98, stlsoft::split() has been enhanced to be able to split into between two and six fragments. Previously you would have use intermediates to split into more fields, as in:


std::string line = "abc|def|ghi|jkl";
stlsoft::string_view dummy1;
stlsoft::string_view dummy2;
stlsoft::string_view field0;
stlsoft::string_view field1;
stlsoft::string_view field2;
stlsoft::string_view field3;

if(stlsoft::split(line, '|', field0, dummy1) &&
   stlsoft::split(dummy1, '|', field1, dummy2) &&
   stlsoft::split(dummy2, '|', field2, field3))
{
  . . . // use fields

Although there's no additional memory allocation here - because we're using string views as the intermediate and final fragment types - it's still hard to follow, and doing three separate split operations.

You can now split directly into up to six fields, as in:



std::string line = "abc|def|ghi|jkl";
stlsoft::string_view field0;
stlsoft::string_view field1;
stlsoft::string_view field2;
stlsoft::string_view field3;

if(stlsoft::split(line, '|', field0, field1, field2, field3))
{
  . . . // use fields

It's marginally more efficient when using string views, and substantially more efficient when using string value types (such as std::string and stlsoft::simple_string). In either cases, it's considerably more transparent.

STLSoft 1.9.98 changes to stlsoft::read_line()

As of STLSoft 1.9.98, stlsoft::read_line() can now read from an iterator range of arbitrary type. Where formerly it would only work with a C Stream (i.e. FILE*), as in:


std::string line;
while(stlsoft::read_line(stdin, line
     , stlsoft::read_line_flags::recogniseAll))
{
  . . . // process line
}

Now it will also work with an iterator range of arbitrary type, as in:

platformstl::memory_mapped_file f("file.txt");
char const* const begin = static_cast(f.memory());
char const* const end = begin + f.size();

std::string line;
while(stlsoft::read_line(begin, end, line
     , stlsoft::read_line_flags::recogniseAll))
{
  . . . // process line
}

STLSoft 1.9.98 released

STLSoft 1.9.98 is released, containing a bunch of enhancements for 64-bit compatibility, and in anticipation of STLSoft 1.10. The two particular additions of interest are: