1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-08-03 12:49:50 +00:00

fix char literal implementation

This commit is contained in:
bolero-MURAKAMI 2014-10-27 10:16:49 +09:00
parent 773855410b
commit 897d1e25b6
18 changed files with 325 additions and 95 deletions

View file

@ -13,38 +13,48 @@
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/ctype/ascii.hpp>
#include <sprout/assert.hpp>
#include <sprout/static_assert.hpp>
#include <sprout/detail/char_literal.hpp>
#include <sprout/detail/char_type_of_consecutive.hpp>
namespace sprout {
namespace detail {
template<typename Elem, typename IntType>
inline SPROUT_CONSTEXPR Elem
int_to_char(IntType val, int base) {
SPROUT_STATIC_ASSERT(sprout::detail::is_char_type_of_consecutive_digits<Elem>::value);
SPROUT_STATIC_ASSERT(sprout::detail::is_char_type_of_consecutive_lower_alphabet<Elem>::value);
return SPROUT_ASSERT(2 <= base && base <= 36), SPROUT_ASSERT(IntType(0) <= val && val < static_cast<IntType>(base)),
val < 10 ? static_cast<Elem>('0') + val
: static_cast<Elem>('a') + (val - 10)
val < 10 ? SPROUT_CHAR_LITERAL('0', Elem) + val
: SPROUT_CHAR_LITERAL('a', Elem) + (val - 10)
;
}
template<typename Elem, typename IntType>
inline SPROUT_CONSTEXPR Elem
int_to_char(IntType val) {
SPROUT_STATIC_ASSERT(sprout::detail::is_char_type_of_consecutive_digits<Elem>::value);
return SPROUT_ASSERT(IntType(0) <= val && val < IntType(10)),
static_cast<Elem>('0') + val
SPROUT_CHAR_LITERAL('0', Elem) + val
;
}
template<typename IntType, typename Elem>
inline SPROUT_CONSTEXPR IntType
char_to_int(Elem c, int base) {
return sprout::ascii::isdigit(c) && c - static_cast<Elem>('0') < base ? c - static_cast<Elem>('0')
: sprout::ascii::islower(c) && c - static_cast<Elem>('a') + 10 < base ? c - static_cast<Elem>('a') + 10
: sprout::ascii::isupper(c) && c - static_cast<Elem>('A') + 10 < base ? c - static_cast<Elem>('A') + 10
SPROUT_STATIC_ASSERT(sprout::detail::is_char_type_of_consecutive_digits<Elem>::value);
SPROUT_STATIC_ASSERT(sprout::detail::is_char_type_of_consecutive_lower_alphabet<Elem>::value);
SPROUT_STATIC_ASSERT(sprout::detail::is_char_type_of_consecutive_upper_alphabet<Elem>::value);
return sprout::ascii::isdigit(c) && c - SPROUT_CHAR_LITERAL('0', Elem) < base ? c - SPROUT_CHAR_LITERAL('0', Elem)
: sprout::ascii::islower(c) && c - SPROUT_CHAR_LITERAL('a', Elem) + 10 < base ? c - SPROUT_CHAR_LITERAL('a', Elem) + 10
: sprout::ascii::isupper(c) && c - SPROUT_CHAR_LITERAL('A', Elem) + 10 < base ? c - SPROUT_CHAR_LITERAL('A', Elem) + 10
: static_cast<IntType>(-1)
;
}
template<typename IntType, typename Elem>
inline SPROUT_CONSTEXPR IntType
char_to_int(Elem c) {
return sprout::ascii::isdigit(c) ? c - static_cast<Elem>('0')
SPROUT_STATIC_ASSERT(sprout::detail::is_char_type_of_consecutive_digits<Elem>::value);
return sprout::ascii::isdigit(c) ? c - SPROUT_CHAR_LITERAL('0', Elem)
: static_cast<IntType>(-1)
;
}

View file

@ -0,0 +1,62 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_DETAIL_CHAR_LITERAL_HPP
#define SPROUT_DETAIL_CHAR_LITERAL_HPP
#include <sprout/config.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/preprocessor/cat.hpp>
namespace sprout {
namespace detail {
#if SPROUT_USE_UNICODE_LITERALS
template<typename Elem, char C, wchar_t WC, char16_t C16, char32_t C32>
struct char_literal_of;
template<char C, wchar_t WC, char16_t C16, char32_t C32>
struct char_literal_of<char, C, WC, C16, C32>
: public sprout::integral_constant<char, C>
{};
template<char C, wchar_t WC, char16_t C16, char32_t C32>
struct char_literal_of<wchar_t, C, WC, C16, C32>
: public sprout::integral_constant<wchar_t, WC>
{};
template<char C, wchar_t WC, char16_t C16, char32_t C32>
struct char_literal_of<char16_t, C, WC, C16, C32>
: public sprout::integral_constant<char16_t, C16>
{};
template<char C, wchar_t WC, char16_t C16, char32_t C32>
struct char_literal_of<char32_t, C, WC, C16, C32>
: public sprout::integral_constant<char32_t, C32>
{};
#else
template<typename Elem, char C, wchar_t WC>
struct char_literal_of;
template<char C, wchar_t WC>
struct char_literal_of<char, C, WC>
: public sprout::integral_constant<char, C>
{};
template<char C, wchar_t WC>
struct char_literal_of<wchar_t, C, WC>
: public sprout::integral_constant<wchar_t, WC>
{};
#endif
} // namespace detail
} // namespace sprout
//
// SPROUT_CHAR_LITERAL
//
#if SPROUT_USE_UNICODE_LITERALS
# define SPROUT_CHAR_LITERAL(CHAR, TYPE) \
(sprout::detail::char_literal_of<TYPE, CHAR, SPROUT_PP_CAT(L, CHAR), SPROUT_PP_CAT(u, CHAR), SPROUT_PP_CAT(U, CHAR)>::value)
#else
# define SPROUT_CHAR_LITERAL(CHAR, TYPE) \
(sprout::detail::char_literal_of<TYPE, CHAR, SPROUT_PP_CAT(L, CHAR)>::value)
#endif
#endif // #ifndef SPROUT_DETAIL_CHAR_LITERAL_HPP

View file

@ -0,0 +1,135 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_DETAIL_CHAR_TYPE_OF_CONSECUTIVE_HPP
#define SPROUT_DETAIL_CHAR_TYPE_OF_CONSECUTIVE_HPP
#include <sprout/config.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/detail/char_literal.hpp>
namespace sprout {
namespace detail {
template<typename CharType>
struct is_char_type_of_consecutive_digits
: public sprout::integral_constant<
bool,
SPROUT_CHAR_LITERAL('0', CharType) + 1 == SPROUT_CHAR_LITERAL('1', CharType)
&& SPROUT_CHAR_LITERAL('1', CharType) + 1 == SPROUT_CHAR_LITERAL('2', CharType)
&& SPROUT_CHAR_LITERAL('2', CharType) + 1 == SPROUT_CHAR_LITERAL('3', CharType)
&& SPROUT_CHAR_LITERAL('3', CharType) + 1 == SPROUT_CHAR_LITERAL('4', CharType)
&& SPROUT_CHAR_LITERAL('4', CharType) + 1 == SPROUT_CHAR_LITERAL('5', CharType)
&& SPROUT_CHAR_LITERAL('5', CharType) + 1 == SPROUT_CHAR_LITERAL('6', CharType)
&& SPROUT_CHAR_LITERAL('6', CharType) + 1 == SPROUT_CHAR_LITERAL('7', CharType)
&& SPROUT_CHAR_LITERAL('7', CharType) + 1 == SPROUT_CHAR_LITERAL('8', CharType)
&& SPROUT_CHAR_LITERAL('8', CharType) + 1 == SPROUT_CHAR_LITERAL('9', CharType)
>
{};
template<typename CharType>
struct is_char_type_of_consecutive_digits<CharType const>
: public sprout::detail::is_char_type_of_consecutive_digits<CharType>
{};
template<typename CharType>
struct is_char_type_of_consecutive_digits<CharType volatile>
: public sprout::detail::is_char_type_of_consecutive_digits<CharType>
{};
template<typename CharType>
struct is_char_type_of_consecutive_digits<CharType const volatile>
: public sprout::detail::is_char_type_of_consecutive_digits<CharType>
{};
template<typename CharType>
struct is_char_type_of_consecutive_lower_alphabet
: public sprout::integral_constant<
bool,
SPROUT_CHAR_LITERAL('a', CharType) + 1 == SPROUT_CHAR_LITERAL('b', CharType)
&& SPROUT_CHAR_LITERAL('b', CharType) + 1 == SPROUT_CHAR_LITERAL('c', CharType)
&& SPROUT_CHAR_LITERAL('c', CharType) + 1 == SPROUT_CHAR_LITERAL('d', CharType)
&& SPROUT_CHAR_LITERAL('d', CharType) + 1 == SPROUT_CHAR_LITERAL('e', CharType)
&& SPROUT_CHAR_LITERAL('e', CharType) + 1 == SPROUT_CHAR_LITERAL('f', CharType)
&& SPROUT_CHAR_LITERAL('f', CharType) + 1 == SPROUT_CHAR_LITERAL('g', CharType)
&& SPROUT_CHAR_LITERAL('g', CharType) + 1 == SPROUT_CHAR_LITERAL('h', CharType)
&& SPROUT_CHAR_LITERAL('h', CharType) + 1 == SPROUT_CHAR_LITERAL('i', CharType)
&& SPROUT_CHAR_LITERAL('i', CharType) + 1 == SPROUT_CHAR_LITERAL('j', CharType)
&& SPROUT_CHAR_LITERAL('j', CharType) + 1 == SPROUT_CHAR_LITERAL('k', CharType)
&& SPROUT_CHAR_LITERAL('k', CharType) + 1 == SPROUT_CHAR_LITERAL('l', CharType)
&& SPROUT_CHAR_LITERAL('l', CharType) + 1 == SPROUT_CHAR_LITERAL('m', CharType)
&& SPROUT_CHAR_LITERAL('m', CharType) + 1 == SPROUT_CHAR_LITERAL('n', CharType)
&& SPROUT_CHAR_LITERAL('n', CharType) + 1 == SPROUT_CHAR_LITERAL('o', CharType)
&& SPROUT_CHAR_LITERAL('o', CharType) + 1 == SPROUT_CHAR_LITERAL('p', CharType)
&& SPROUT_CHAR_LITERAL('p', CharType) + 1 == SPROUT_CHAR_LITERAL('q', CharType)
&& SPROUT_CHAR_LITERAL('q', CharType) + 1 == SPROUT_CHAR_LITERAL('r', CharType)
&& SPROUT_CHAR_LITERAL('r', CharType) + 1 == SPROUT_CHAR_LITERAL('s', CharType)
&& SPROUT_CHAR_LITERAL('s', CharType) + 1 == SPROUT_CHAR_LITERAL('t', CharType)
&& SPROUT_CHAR_LITERAL('t', CharType) + 1 == SPROUT_CHAR_LITERAL('u', CharType)
&& SPROUT_CHAR_LITERAL('u', CharType) + 1 == SPROUT_CHAR_LITERAL('v', CharType)
&& SPROUT_CHAR_LITERAL('v', CharType) + 1 == SPROUT_CHAR_LITERAL('w', CharType)
&& SPROUT_CHAR_LITERAL('w', CharType) + 1 == SPROUT_CHAR_LITERAL('x', CharType)
&& SPROUT_CHAR_LITERAL('x', CharType) + 1 == SPROUT_CHAR_LITERAL('y', CharType)
&& SPROUT_CHAR_LITERAL('y', CharType) + 1 == SPROUT_CHAR_LITERAL('z', CharType)
>
{};
template<typename CharType>
struct is_char_type_of_consecutive_lower_alphabet<CharType const>
: public sprout::detail::is_char_type_of_consecutive_lower_alphabet<CharType>
{};
template<typename CharType>
struct is_char_type_of_consecutive_lower_alphabet<CharType volatile>
: public sprout::detail::is_char_type_of_consecutive_lower_alphabet<CharType>
{};
template<typename CharType>
struct is_char_type_of_consecutive_lower_alphabet<CharType const volatile>
: public sprout::detail::is_char_type_of_consecutive_lower_alphabet<CharType>
{};
template<typename CharType>
struct is_char_type_of_consecutive_upper_alphabet
: public sprout::integral_constant<
bool,
SPROUT_CHAR_LITERAL('A', CharType) + 1 == SPROUT_CHAR_LITERAL('B', CharType)
&& SPROUT_CHAR_LITERAL('B', CharType) + 1 == SPROUT_CHAR_LITERAL('C', CharType)
&& SPROUT_CHAR_LITERAL('C', CharType) + 1 == SPROUT_CHAR_LITERAL('D', CharType)
&& SPROUT_CHAR_LITERAL('D', CharType) + 1 == SPROUT_CHAR_LITERAL('E', CharType)
&& SPROUT_CHAR_LITERAL('E', CharType) + 1 == SPROUT_CHAR_LITERAL('F', CharType)
&& SPROUT_CHAR_LITERAL('F', CharType) + 1 == SPROUT_CHAR_LITERAL('G', CharType)
&& SPROUT_CHAR_LITERAL('G', CharType) + 1 == SPROUT_CHAR_LITERAL('H', CharType)
&& SPROUT_CHAR_LITERAL('H', CharType) + 1 == SPROUT_CHAR_LITERAL('I', CharType)
&& SPROUT_CHAR_LITERAL('I', CharType) + 1 == SPROUT_CHAR_LITERAL('J', CharType)
&& SPROUT_CHAR_LITERAL('J', CharType) + 1 == SPROUT_CHAR_LITERAL('K', CharType)
&& SPROUT_CHAR_LITERAL('K', CharType) + 1 == SPROUT_CHAR_LITERAL('L', CharType)
&& SPROUT_CHAR_LITERAL('L', CharType) + 1 == SPROUT_CHAR_LITERAL('M', CharType)
&& SPROUT_CHAR_LITERAL('M', CharType) + 1 == SPROUT_CHAR_LITERAL('N', CharType)
&& SPROUT_CHAR_LITERAL('N', CharType) + 1 == SPROUT_CHAR_LITERAL('O', CharType)
&& SPROUT_CHAR_LITERAL('O', CharType) + 1 == SPROUT_CHAR_LITERAL('P', CharType)
&& SPROUT_CHAR_LITERAL('P', CharType) + 1 == SPROUT_CHAR_LITERAL('Q', CharType)
&& SPROUT_CHAR_LITERAL('Q', CharType) + 1 == SPROUT_CHAR_LITERAL('R', CharType)
&& SPROUT_CHAR_LITERAL('R', CharType) + 1 == SPROUT_CHAR_LITERAL('S', CharType)
&& SPROUT_CHAR_LITERAL('S', CharType) + 1 == SPROUT_CHAR_LITERAL('T', CharType)
&& SPROUT_CHAR_LITERAL('T', CharType) + 1 == SPROUT_CHAR_LITERAL('U', CharType)
&& SPROUT_CHAR_LITERAL('U', CharType) + 1 == SPROUT_CHAR_LITERAL('V', CharType)
&& SPROUT_CHAR_LITERAL('V', CharType) + 1 == SPROUT_CHAR_LITERAL('W', CharType)
&& SPROUT_CHAR_LITERAL('W', CharType) + 1 == SPROUT_CHAR_LITERAL('X', CharType)
&& SPROUT_CHAR_LITERAL('X', CharType) + 1 == SPROUT_CHAR_LITERAL('Y', CharType)
&& SPROUT_CHAR_LITERAL('Y', CharType) + 1 == SPROUT_CHAR_LITERAL('Z', CharType)
>
{};
template<typename CharType>
struct is_char_type_of_consecutive_upper_alphabet<CharType const>
: public sprout::detail::is_char_type_of_consecutive_upper_alphabet<CharType>
{};
template<typename CharType>
struct is_char_type_of_consecutive_upper_alphabet<CharType volatile>
: public sprout::detail::is_char_type_of_consecutive_upper_alphabet<CharType>
{};
template<typename CharType>
struct is_char_type_of_consecutive_upper_alphabet<CharType const volatile>
: public sprout::detail::is_char_type_of_consecutive_upper_alphabet<CharType>
{};
} // namespace detail
} // namespace sprout
#endif // #ifndef SPROUT_DETAIL_CHAR_TYPE_OF_CONSECUTIVE_HPP

View file

@ -10,6 +10,7 @@
#include <sprout/config.hpp>
#include <sprout/string.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/preprocessor/cat.hpp>
//
@ -69,10 +70,8 @@
#endif
#define SPROUT_LITERAL_CHAR_DEF_IMPL(NAME, CHAR, ELEM) \
template<> \
struct NAME<ELEM> { \
public: \
SPROUT_STATIC_CONSTEXPR ELEM value = CHAR; \
}; \
SPROUT_CONSTEXPR_OR_CONST ELEM NAME<ELEM>::value
struct NAME<ELEM> \
: public sprout::integral_constant<ELEM, CHAR> \
{}
#endif // #ifndef SPROUT_DETAIL_LITERAL_DEF_HPP