Deprecated Header ≪Codecvt≫ Replacement

Deprecated header <codecvt> replacement

std::codecvt template from <locale> itself isn't deprecated. For UTF-8 to UTF-16, there is still std::codecvt<char16_t, char, std::mbstate_t> specialization.

However, since std::wstring_convert and std::wbuffer_convert are deprecated along with the standard conversion facets, there isn't any easy way to convert strings using the facets.

So, as Bolas already answered: Implement it yourself (or you can use a third party library, as always) or keep using the deprecated API.

Codecvt doesn't work in gcc

Only file streams are required to use std::codecvt<...> and there is no requirement that any of the standard stream objects is implemented in terms of file streams. There are reasons for the implementers of either choice. Dinkumware's implementation uses <stdio.h> for most of its operations and it makes sense to use the same implementation under the hood in this case. libstdc++ avoids some overheads and directly accesses a buffer shared between the standard C and C++ streams and, thus, uses a different stream implementation.

When using file streams use of the std::codecvt<...> facets should be consistent.

UTF-16 codecvt facet

I'm not sure if by "resources on the Web" you meant available free of cost, but there is the Dinkumware Conversions Library that sounds like it will fit your needs—provided that the library can be integrated into your compiler suite.

The codecvt types are described in the section Code Conversions.

Wrong codecvt result in ViualStudio 2010

 mbstate_t state;

You forgot to initialize that. Fix:

 mbstate_t state = { 0 };

How to get C++ std::string from Little-Endian UTF-16 encoded bytes

For the sake of completeness, here's the simplest iconv based conversion I came up with

#include <iconv.h>

auto iconv_eng = ::iconv_open("UTF-8", "UTF-16LE");
if (reinterpret_cast<::iconv_t>(-1) == iconv_eng)
{
std::cerr << "Unable to create ICONV engine: " << strerror(errno) << std::endl;
}
else
{
// src a char * to utf16 bytes
// src_size the maximum number of bytes to convert
// dest a char * to utf8 bytes to generate
// dest_size the maximum number of bytes to write
if (static_cast<std::size_t>(-1) == ::iconv(iconv_eng, &src, &src_size, &dest, &dest_size))
{
std::cerr << "Unable to convert from UTF16: " << strerror(errno) << std::endl;
}
else
{
std::string utf8_str(src);
::iconv_close(iconv_eng);
}
}

How can I deprecate a C++ header?

Here is a possible (albeit perhaps not too elegant) solution.

Insert in the header a code like that

// badheader.hpp
namespace {
[[deprecated("This header is deprecated")]]
constexpr static int badheader_hpp_is_deprecated = 0;
constexpr static int please_dont_use_badheader_hpp = badheader_hpp_is_deprecated;
}

This creates a deprecated variable badheader_hpp_is_deprecated. The initialization of please_dont_use_badheader_hpp triggers the deprecated warning. Notice that I put both variables inside an anonymous namespace, to avoid possible name conflicts.
Still, as noted in the comment, a name clash could still happen if, in the same compilation unit, a variable with the same name is declared inside the anonymous namespace. For this reason, as suggested in the comments, variables in the code above have a descriptive name, rendering name clash high improbable.



Related Topics



Leave a reply



Submit