Merge branch 'toml-v050' of github.com:ToruNiina/toml11 into toml-v050

This commit is contained in:
ToruNiina
2018-12-12 19:33:13 +09:00
3 changed files with 33 additions and 28 deletions

View File

@@ -154,7 +154,7 @@ template<typename T, typename std::enable_if<detail::conjunction<
detail::is_container<T>, // T is container detail::is_container<T>, // T is container
detail::has_resize_method<T>, // T::resize(N) works detail::has_resize_method<T>, // T::resize(N) works
detail::negation<detail::is_exact_toml_type<T>> // but not toml::array detail::negation<detail::is_exact_toml_type<T>> // but not toml::array
>::value, std::nullptr_t>::type = nullptr> >::value, std::nullptr_t>::type>
T get(const value& v) T get(const value& v)
{ {
using value_type = typename T::value_type; using value_type = typename T::value_type;
@@ -173,7 +173,7 @@ template<typename T, typename std::enable_if<detail::conjunction<
detail::is_container<T>, // T is container detail::is_container<T>, // T is container
detail::negation<detail::has_resize_method<T>>, // no T::resize() exists detail::negation<detail::has_resize_method<T>>, // no T::resize() exists
detail::negation<detail::is_exact_toml_type<T>> // not toml::array detail::negation<detail::is_exact_toml_type<T>> // not toml::array
>::value, std::nullptr_t>::type = nullptr> >::value, std::nullptr_t>::type>
T get(const value& v) T get(const value& v)
{ {
using value_type = typename T::value_type; using value_type = typename T::value_type;
@@ -195,7 +195,7 @@ T get(const value& v)
// std::pair. // std::pair.
template<typename T, typename std::enable_if< template<typename T, typename std::enable_if<
detail::is_std_pair<T>::value, std::nullptr_t>::type = nullptr> detail::is_std_pair<T>::value, std::nullptr_t>::type>
T get(const value& v) T get(const value& v)
{ {
using first_type = typename T::first_type; using first_type = typename T::first_type;
@@ -228,7 +228,7 @@ T get_tuple_impl(const toml::Array& a, index_sequence<I...>)
} // detail } // detail
template<typename T, typename std::enable_if< template<typename T, typename std::enable_if<
detail::is_std_tuple<T>::value, std::nullptr_t>::type = nullptr> detail::is_std_tuple<T>::value, std::nullptr_t>::type>
T get(const value& v) T get(const value& v)
{ {
const auto& ar = v.cast<value_t::Array>(); const auto& ar = v.cast<value_t::Array>();
@@ -249,7 +249,7 @@ T get(const value& v)
template<typename T, typename std::enable_if<detail::conjunction< template<typename T, typename std::enable_if<detail::conjunction<
detail::is_map<T>, // T is map detail::is_map<T>, // T is map
detail::negation<detail::is_exact_toml_type<T>> // but not toml::table detail::negation<detail::is_exact_toml_type<T>> // but not toml::table
>::value, std::nullptr_t>::type = nullptr> >::value, std::nullptr_t>::type>
T get(const toml::value& v) T get(const toml::value& v)
{ {
using key_type = typename T::key_type; using key_type = typename T::key_type;

View File

@@ -117,14 +117,16 @@ using lex_basic_unescaped = exclude<either<in_range<0x00, 0x1F>,
character<0x22>, character<0x5C>, character<0x22>, character<0x5C>,
character<0x7F>>>; character<0x7F>>>;
using lex_escape = character<'\\'>; using lex_escape = character<'\\'>;
using lex_escape_unicode_short = sequence<character<'u'>,
repeat<lex_hex_dig, exactly<4>>>;
using lex_escape_unicode_long = sequence<character<'U'>,
repeat<lex_hex_dig, exactly<8>>>;
using lex_escape_seq_char = either<character<'"'>, character<'\\'>, using lex_escape_seq_char = either<character<'"'>, character<'\\'>,
character<'/'>, character<'b'>, character<'/'>, character<'b'>,
character<'f'>, character<'n'>, character<'f'>, character<'n'>,
character<'r'>, character<'t'>, character<'r'>, character<'t'>,
sequence<character<'u'>, lex_escape_unicode_short,
repeat<lex_hex_dig, exactly<4>>>, lex_escape_unicode_long
sequence<character<'U'>,
repeat<lex_hex_dig, exactly<8>>>
>; >;
using lex_escaped = sequence<lex_escape, lex_escape_seq_char>; using lex_escaped = sequence<lex_escape, lex_escape_seq_char>;
using lex_basic_char = either<lex_basic_unescaped, lex_escaped>; using lex_basic_char = either<lex_basic_unescaped, lex_escaped>;

View File

@@ -226,8 +226,10 @@ parse_floating(location<Container>& loc)
"token is not a float", {"floating point is like: -3.14e+1"})); "token is not a float", {"floating point is like: -3.14e+1"}));
} }
inline std::string read_utf8_codepoint(const std::string& str) template<typename Container>
std::string read_utf8_codepoint(const region<Container>& reg)
{ {
const auto str = reg.str().substr(1);
std::uint_least32_t codepoint; std::uint_least32_t codepoint;
std::istringstream iss(str); std::istringstream iss(str);
iss >> std::hex >> codepoint; iss >> std::hex >> codepoint;
@@ -254,10 +256,11 @@ inline std::string read_utf8_codepoint(const std::string& str)
{ {
if(0x10FFFF < codepoint) // out of Unicode region if(0x10FFFF < codepoint) // out of Unicode region
{ {
std::cerr << "WARNING: input codepoint " << str << " is too large " std::cerr << format_underline(concat_to_string("[warning] "
<< "to decode as a unicode character. It should be in " "input codepoint (", str, ") is too large to decode as "
<< "range [0x00 .. 0x10FFFF]. The result may not be able " "a unicode character. The result may not be able to render "
<< "to be rendered to your screen." << std::endl; "to your screen."), reg, "should be in [0x00..0x10FFFF]")
<< std::endl;
} }
// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx // 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx
character += static_cast<unsigned char>(0xF0| codepoint >> 18); character += static_cast<unsigned char>(0xF0| codepoint >> 18);
@@ -267,9 +270,9 @@ inline std::string read_utf8_codepoint(const std::string& str)
} }
else // out of UTF-8 region else // out of UTF-8 region
{ {
throw std::range_error("toml::read_utf8_codepoint: input codepoint `" + throw std::range_error(format_underline(concat_to_string("[error] "
str + "` is too large to decode as utf-8. It should be in range" "input codepoint (", str, ") is too large to encode as utf-8."),
" 0x00 ... 0x1FFFFF."); reg, "should be in [0x00..0x10FFFF]"));
} }
return character; return character;
} }
@@ -278,7 +281,7 @@ template<typename Container>
result<std::string, std::string> parse_escape_sequence(location<Container>& loc) result<std::string, std::string> parse_escape_sequence(location<Container>& loc)
{ {
const auto first = loc.iter(); const auto first = loc.iter();
if(*first != '\\') if(first == loc.end() || *first != '\\')
{ {
return err(format_underline("[error]: " return err(format_underline("[error]: "
"toml::parse_escape_sequence: location does not points \"\\\"", "toml::parse_escape_sequence: location does not points \"\\\"",
@@ -296,10 +299,9 @@ result<std::string, std::string> parse_escape_sequence(location<Container>& loc)
case 'r' :{++loc.iter(); return ok(std::string("\r"));} case 'r' :{++loc.iter(); return ok(std::string("\r"));}
case 'u' : case 'u' :
{ {
++loc.iter(); if(const auto token = lex_escape_unicode_short::invoke(loc))
if(const auto token = repeat<lex_hex_dig, exactly<4>>::invoke(loc))
{ {
return ok(read_utf8_codepoint(token.unwrap().str())); return ok(read_utf8_codepoint(token.unwrap()));
} }
else else
{ {
@@ -310,10 +312,9 @@ result<std::string, std::string> parse_escape_sequence(location<Container>& loc)
} }
case 'U': case 'U':
{ {
++loc.iter(); if(const auto token = lex_escape_unicode_long::invoke(loc))
if(const auto token = repeat<lex_hex_dig, exactly<8>>::invoke(loc))
{ {
return ok(read_utf8_codepoint(token.unwrap().str())); return ok(read_utf8_codepoint(token.unwrap()));
} }
else else
{ {
@@ -340,10 +341,11 @@ parse_ml_basic_string(location<Container>& loc)
const auto first = loc.iter(); const auto first = loc.iter();
if(const auto token = lex_ml_basic_string::invoke(loc)) if(const auto token = lex_ml_basic_string::invoke(loc))
{ {
location<std::string> inner_loc(loc.name(), token.unwrap().str()); auto inner_loc = loc;
inner_loc.iter() = first;
std::string retval; std::string retval;
retval.reserve(inner_loc.source()->size()); retval.reserve(token.unwrap().size());
auto delim = lex_ml_basic_string_delim::invoke(inner_loc); auto delim = lex_ml_basic_string_delim::invoke(inner_loc);
if(!delim) if(!delim)
@@ -396,7 +398,8 @@ parse_basic_string(location<Container>& loc)
const auto first = loc.iter(); const auto first = loc.iter();
if(const auto token = lex_basic_string::invoke(loc)) if(const auto token = lex_basic_string::invoke(loc))
{ {
location<std::string> inner_loc(loc.name(), token.unwrap().str()); auto inner_loc = loc;
inner_loc.iter() = first;
auto quot = lex_quotation_mark::invoke(inner_loc); auto quot = lex_quotation_mark::invoke(inner_loc);
if(!quot) if(!quot)
@@ -406,7 +409,7 @@ parse_basic_string(location<Container>& loc)
} }
std::string retval; std::string retval;
retval.reserve(inner_loc.source()->size()); retval.reserve(token.unwrap().size());
quot = err("tmp"); quot = err("tmp");
while(!quot) while(!quot)