Подробности
[В начало]
Проблема в реализации № S0675
Краткое описание
codecvt
Подробное описание
Функции-члены класса codecvt<wchar_t, char, mbstate_t>
result in(stateT& state, const externT* from, const externT* from_end, const externT*& from_next, internT* to, internT* to_limit, internT*& to_next) const
и
result out(stateT& state, const internT* from, const internT* from_end, const internT*& from_next, externT* to, externT* to_limit, externT*& to_next) const
возвращают "ok" в случае, когда (to==to_limit), но (from < from_end), иными словами, когда выходная последовательность не вмещает ни одного элемента, а входная непустая.
Тем не менее, из описания возвращаемого значения этих функций (ISO/IEC 14882, раздел 22.2.1.5.2.4) следует, что должен возвращаться "partial":
ok - completed the conversionpartial - not all source characters converted
error - encountered a character in [from,from_end) that it could not convert
noconv - internT and externT are the same type, and input sequence is identical to converted sequence
Эти функции в действительности возвращают "partial", когда выходная последовательность непуста, но не может вместить все преобразованные символы из входной последовательности:
0< (to_limit - to) < (from_end - from).
Раздел стандарта
Linux Standard Base C++ Specification 3.2, Chapter 9. Libraries, 9.1. Interfaces for libstdcxx, который ссылается на ISO/IEC 14882: 2003 Programming languages --C++, section 18.6.4
Пример
#include <locale>
using namespace std;
/*
* Derives from codecvt<> class for make destructor
* and target functions public (instead of protected).
*/
class codecvt_my : public codecvt<wchar_t, char, mbstate_t>
{
public:
using codecvt<wchar_t, char, mbstate_t>::do_in;
using codecvt<wchar_t, char, mbstate_t>::do_out;
virtual ~codecvt_my(){};
};
/*
* Converts integral value of codecvt_base::result
* to string representation.
*/
const char* result_to_str(codecvt_base::result result)
{
switch(result)
{
case codecvt_base::ok:
return "ok";
case codecvt_base::error:
return "error";
case codecvt_base::noconv:
return "noconv";
case codecvt_base::partial:
return "partial";
default:
return "(unknown result)";
}
}
/*
* Test for do_out() function
* with different sizes of input and ouput sequences.
*/
template<size_t input_size, size_t output_size>
void test_out()
{
wchar_t from[input_size];
for(wchar_t *tmp = from; tmp < from + input_size; tmp++)
*tmp = L'a';
const wchar_t *from_next;
char to[output_size];
char *to_next;
codecvt_my obj;
mbstate_t state = mbstate_t();
printf("Calls do_out() function when size of input sequence "
"is %zu, output - %zu:\n",
input_size, output_size);
codecvt_base::result result = obj.do_out(state,
from, from + input_size, from_next,
to, to + output_size, to_next);
printf("do_out() returns %s.\n",
result_to_str(result));
}
/*
* Test for do_in() function
* with different sizes of input and ouput sequences.
*/
template<size_t input_size, size_t output_size>
void test_in()
{
char from[input_size];
for(char *tmp = from; tmp < from + input_size; tmp++)
*tmp = 'a';
const char *from_next;
wchar_t to[output_size];
wchar_t *to_next;
codecvt_my obj;
mbstate_t state = mbstate_t();
printf("Calls do_in() function when size of input sequence"
"is %zu, output - %zu:\n",
input_size, output_size);
codecvt_base::result result = obj.do_in(state,
from, from + input_size, from_next,
to, to + output_size, to_next);
printf("do_in() returns %s.\n",
result_to_str(result));
}
int main()
{
test_out<2,1>();
test_out<2,0>();
test_in<2,1>();
test_in<2,0>();
return 0;
}
Компонент
libstdc++
Принято
GCC Bugzilla 37475
[В начало]