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:
parent
773855410b
commit
897d1e25b6
18 changed files with 325 additions and 95 deletions
|
@ -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)
|
||||
;
|
||||
}
|
||||
|
|
62
sprout/detail/char_literal.hpp
Normal file
62
sprout/detail/char_literal.hpp
Normal 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
|
135
sprout/detail/char_type_of_consecutive.hpp
Normal file
135
sprout/detail/char_type_of_consecutive.hpp
Normal 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
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue