Mereged from r74355

Basic support for char16_t and char32_t

[SVN r74361]
This commit is contained in:
Antony Polukhin
2011-09-12 18:15:31 +00:00
parent 8480a6d083
commit e1caac418c
2 changed files with 166 additions and 91 deletions

View File

@@ -133,60 +133,102 @@ namespace boost
namespace detail // selectors for choosing stream character type namespace detail // selectors for choosing stream character type
{ {
template<typename Type> template<typename Type>
struct stream_char struct stream_char
{ {
typedef char type; typedef char type;
}; };
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<class CharT, class Traits, class Alloc> template<class CharT, class Traits, class Alloc>
struct stream_char< std::basic_string<CharT,Traits,Alloc> > struct stream_char< std::basic_string<CharT,Traits,Alloc> >
{ {
typedef CharT type; typedef CharT type;
}; };
#endif #endif
#ifndef BOOST_LCAST_NO_WCHAR_T #ifndef BOOST_LCAST_NO_WCHAR_T
#ifndef BOOST_NO_INTRINSIC_WCHAR_T #ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<> template<>
struct stream_char<wchar_t> struct stream_char<wchar_t>
{ {
typedef wchar_t type; typedef wchar_t type;
}; };
#endif #endif
template<> template<>
struct stream_char<wchar_t *> struct stream_char<wchar_t *>
{ {
typedef wchar_t type; typedef wchar_t type;
}; };
template<> template<>
struct stream_char<const wchar_t *> struct stream_char<const wchar_t *>
{ {
typedef wchar_t type; typedef wchar_t type;
}; };
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<> template<>
struct stream_char<std::wstring> struct stream_char<std::wstring>
{ {
typedef wchar_t type; typedef wchar_t type;
}; };
#endif #endif
#endif #endif
#ifndef BOOST_NO_CHAR16_T
template<>
struct stream_char<char16_t>
{
typedef char16_t type;
};
template<>
struct stream_char<char16_t *>
{
typedef char16_t type;
};
template<>
struct stream_char<const char16_t *>
{
typedef char16_t type;
};
#endif
#ifndef BOOST_NO_CHAR32_T
template<>
struct stream_char<char32_t>
{
typedef char32_t type;
};
template<>
struct stream_char<char32_t *>
{
typedef char32_t type;
};
template<>
struct stream_char<const char32_t *>
{
typedef char32_t type;
};
#endif
template<typename TargetChar, typename SourceChar> template<typename TargetChar, typename SourceChar>
struct widest_char struct widest_char
{ {
typedef TargetChar type; typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
}; (sizeof(TargetChar) > sizeof(SourceChar))
, TargetChar
template<> , SourceChar >::type type;
struct widest_char<char, wchar_t>
{
typedef wchar_t type;
}; };
} }
@@ -231,8 +273,7 @@ namespace boost
namespace detail // lcast_src_length namespace detail // lcast_src_length
{ {
// Return max. length of string representation of Source; // Return max. length of string representation of Source;
template< class CharT // A result of widest_char transformation. template< class Source // Source type of lexical_cast.
, class Source // Source type of lexical_cast.
> >
struct lcast_src_length struct lcast_src_length
{ {
@@ -269,20 +310,12 @@ namespace boost
BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256); BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256);
#endif #endif
}; };
// TODO: FIX for char16_t, char32_t, we can ignore CharT
#define BOOST_LCAST_DEF1(CharT, T) \ #define BOOST_LCAST_DEF(T) \
template<> struct lcast_src_length<CharT, T> \ template<> struct lcast_src_length<T> \
: lcast_src_length_integral<T> \ : lcast_src_length_integral<T> \
{ static void check_coverage() {} }; { static void check_coverage() {} };
#ifdef BOOST_LCAST_NO_WCHAR_T
#define BOOST_LCAST_DEF(T) BOOST_LCAST_DEF1(char, T)
#else
#define BOOST_LCAST_DEF(T) \
BOOST_LCAST_DEF1(char, T) \
BOOST_LCAST_DEF1(wchar_t, T)
#endif
BOOST_LCAST_DEF(short) BOOST_LCAST_DEF(short)
BOOST_LCAST_DEF(unsigned short) BOOST_LCAST_DEF(unsigned short)
BOOST_LCAST_DEF(int) BOOST_LCAST_DEF(int)
@@ -298,7 +331,6 @@ namespace boost
#endif #endif
#undef BOOST_LCAST_DEF #undef BOOST_LCAST_DEF
#undef BOOST_LCAST_DEF1
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
// Helper for floating point types. // Helper for floating point types.
@@ -324,49 +356,26 @@ namespace boost
}; };
template<> template<>
struct lcast_src_length<char,float> struct lcast_src_length<float>
: lcast_src_length_floating<float> : lcast_src_length_floating<float>
{ {
static void check_coverage() {} static void check_coverage() {}
}; };
template<> template<>
struct lcast_src_length<char,double> struct lcast_src_length<double>
: lcast_src_length_floating<double> : lcast_src_length_floating<double>
{ {
static void check_coverage() {} static void check_coverage() {}
}; };
template<> template<>
struct lcast_src_length<char,long double> struct lcast_src_length<long double>
: lcast_src_length_floating<long double> : lcast_src_length_floating<long double>
{ {
static void check_coverage() {} static void check_coverage() {}
}; };
#ifndef BOOST_LCAST_NO_WCHAR_T
template<>
struct lcast_src_length<wchar_t,float>
: lcast_src_length_floating<float>
{
static void check_coverage() {}
};
template<>
struct lcast_src_length<wchar_t,double>
: lcast_src_length_floating<double>
{
static void check_coverage() {}
};
template<>
struct lcast_src_length<wchar_t,long double>
: lcast_src_length_floating<long double>
{
static void check_coverage() {}
};
#endif // #ifndef BOOST_LCAST_NO_WCHAR_T
#endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION #endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
} }
@@ -397,6 +406,32 @@ namespace boost
BOOST_STATIC_CONSTANT(wchar_t, c_decimal_separator = L'.'); BOOST_STATIC_CONSTANT(wchar_t, c_decimal_separator = L'.');
}; };
#endif #endif
#ifndef BOOST_NO_CHAR16_T
template<>
struct lcast_char_constants<char16_t>
{
BOOST_STATIC_CONSTANT(char16_t, zero = u'0');
BOOST_STATIC_CONSTANT(char16_t, minus = u'-');
BOOST_STATIC_CONSTANT(char16_t, plus = u'+');
BOOST_STATIC_CONSTANT(char16_t, lowercase_e = u'e');
BOOST_STATIC_CONSTANT(char16_t, capital_e = u'E');
BOOST_STATIC_CONSTANT(char16_t, c_decimal_separator = u'.');
};
#endif
#ifndef BOOST_NO_CHAR32_T
template<>
struct lcast_char_constants<char32_t>
{
BOOST_STATIC_CONSTANT(char32_t, zero = U'0');
BOOST_STATIC_CONSTANT(char32_t, minus = U'-');
BOOST_STATIC_CONSTANT(char32_t, plus = U'+');
BOOST_STATIC_CONSTANT(char32_t, lowercase_e = U'e');
BOOST_STATIC_CONSTANT(char32_t, capital_e = U'E');
BOOST_STATIC_CONSTANT(char32_t, c_decimal_separator = U'.');
};
#endif
} }
namespace detail // lcast_to_unsigned namespace detail // lcast_to_unsigned
@@ -1553,28 +1588,38 @@ namespace boost
template<typename T> template<typename T>
struct is_char_or_wchar struct is_char_or_wchar
{ {
private:
#ifndef BOOST_LCAST_NO_WCHAR_T #ifndef BOOST_LCAST_NO_WCHAR_T
BOOST_STATIC_CONSTANT(bool, value = typedef wchar_t wchar_t_if_supported;
(
::boost::type_traits::ice_or<
is_same< T, char >::value,
is_same< T, wchar_t >::value,
is_same< T, unsigned char >::value,
is_same< T, signed char >::value
>::value
)
);
#else #else
typedef char wchar_t_if_supported;
#endif
#ifndef BOOST_NO_CHAR16_T
typedef char16_t char16_t_if_supported;
#else
typedef char char16_t_if_supported;
#endif
#ifndef BOOST_NO_CHAR32_T
typedef char32_t char32_t_if_supported;
#else
typedef char char32_t_if_supported;
#endif
public:
BOOST_STATIC_CONSTANT(bool, value = BOOST_STATIC_CONSTANT(bool, value =
( (
::boost::type_traits::ice_or< ::boost::type_traits::ice_or<
is_same< T, char >::value, is_same< T, char >::value,
is_same< T, wchar_t_if_supported >::value,
is_same< T, char16_t_if_supported >::value,
is_same< T, char32_t_if_supported >::value,
is_same< T, unsigned char >::value, is_same< T, unsigned char >::value,
is_same< T, signed char >::value is_same< T, signed char >::value
>::value >::value
) )
); );
#endif
}; };
template<typename Target, typename Source> template<typename Target, typename Source>
@@ -1658,7 +1703,7 @@ namespace boost
, BOOST_DEDUCED_TYPENAME detail::stream_char<src>::type , BOOST_DEDUCED_TYPENAME detail::stream_char<src>::type
>::type char_type; >::type char_type;
typedef detail::lcast_src_length<char_type, src> lcast_src_length; typedef detail::lcast_src_length<src> lcast_src_length;
std::size_t const src_len = lcast_src_length::value; std::size_t const src_len = lcast_src_length::value;
char_type buf[src_len + 1]; char_type buf[src_len + 1];
lcast_src_length::check_coverage(); lcast_src_length::check_coverage();

View File

@@ -100,6 +100,13 @@ void test_wallocator();
#endif #endif
void test_char_types_conversions(); void test_char_types_conversions();
void operators_overload_test(); void operators_overload_test();
#ifndef BOOST_NO_CHAR16_T
void test_char16_conversions();
#endif
#ifndef BOOST_NO_CHAR32_T
void test_char32_conversions();
#endif
unit_test::test_suite *init_unit_test_suite(int, char *[]) unit_test::test_suite *init_unit_test_suite(int, char *[])
{ {
@@ -142,6 +149,12 @@ unit_test::test_suite *init_unit_test_suite(int, char *[])
suite->add(BOOST_TEST_CASE(&test_char_types_conversions)); suite->add(BOOST_TEST_CASE(&test_char_types_conversions));
suite->add(BOOST_TEST_CASE(&operators_overload_test)); suite->add(BOOST_TEST_CASE(&operators_overload_test));
#ifndef BOOST_NO_CHAR16_T
suite->add(BOOST_TEST_CASE(&test_char16_conversions));
#endif
#ifndef BOOST_NO_CHAR32_T
suite->add(BOOST_TEST_CASE(&test_char32_conversions));
#endif
return suite; return suite;
} }
@@ -582,7 +595,7 @@ void test_conversion_from_integral_to_string(CharT)
// Test values around zero: // Test values around zero:
if(limits::is_signed) if(limits::is_signed)
for(t = -counter; t < static_cast<T>(counter); ++t) for(t = static_cast<T>(-counter); t < static_cast<T>(counter); ++t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t)); BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
// Test values around 100, 1000, 10000, ... // Test values around 100, 1000, 10000, ...
@@ -679,7 +692,7 @@ void test_conversion_from_string_to_integral(CharT)
// Test values around zero: // Test values around zero:
if(limits::is_signed) if(limits::is_signed)
for(t = -counter; t < static_cast<T>(counter); ++t) for(t = static_cast<T>(-counter); t < static_cast<T>(counter); ++t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t); BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
// Test values around 100, 1000, 10000, ... // Test values around 100, 1000, 10000, ...
@@ -990,3 +1003,20 @@ void operators_overload_test()
(void)boost::lexical_cast<foo_operators_test>(foo); (void)boost::lexical_cast<foo_operators_test>(foo);
} }
#ifndef BOOST_NO_CHAR16_T
void test_char16_conversions()
{
BOOST_CHECK(u"100" == lexical_cast<std::u16string>(u"100"));
BOOST_CHECK(u"1" == lexical_cast<std::u16string>(u'1'));
}
#endif
#ifndef BOOST_NO_CHAR32_T
void test_char32_conversions()
{
BOOST_CHECK(U"100" == lexical_cast<std::u32string>(U"100"));
BOOST_CHECK(U"1" == lexical_cast<std::u32string>(U'1'));
}
#endif