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
_File_, _Line_, and _Function_ Usage in C++
How to Find the Index of Current Object in Range-Based For Loop
Dynamical Two Dimension Array According to Input
Order of Calling Constructors/Destructors in Inheritance
Calling Pthread_Cond_Signal Without Locking Mutex
Sin and Cos Give Unexpected Results For Well-Known Angles
Function With Missing Return Value, Behavior At Runtime
How to Output Coloured Text to a Linux Terminal
Type of Integer Literals Not Int by Default
Visual C++ Equivalent of Gcc'S _Attribute_ ((_Packed_))
Defining Static Const Integer Members in Class Definition
Undefined Behavior and Sequence Points Reloaded
What Open Source C++ Static Analysis Tools Are Available