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::has_resize_method<T>, // T::resize(N) works
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)
{
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::negation<detail::has_resize_method<T>>, // no T::resize() exists
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)
{
using value_type = typename T::value_type;
@@ -195,7 +195,7 @@ T get(const value& v)
// std::pair.
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)
{
using first_type = typename T::first_type;
@@ -228,7 +228,7 @@ T get_tuple_impl(const toml::Array& a, index_sequence<I...>)
} // detail
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)
{
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<
detail::is_map<T>, // T is map
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)
{
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<0x7F>>>;
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<'\\'>,
character<'/'>, character<'b'>,
character<'f'>, character<'n'>,
character<'r'>, character<'t'>,
sequence<character<'u'>,
repeat<lex_hex_dig, exactly<4>>>,
sequence<character<'U'>,
repeat<lex_hex_dig, exactly<8>>>
lex_escape_unicode_short,
lex_escape_unicode_long
>;
using lex_escaped = sequence<lex_escape, lex_escape_seq_char>;
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"}));
}
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::istringstream iss(str);
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
{
std::cerr << "WARNING: input codepoint " << str << " is too large "
<< "to decode as a unicode character. It should be in "
<< "range [0x00 .. 0x10FFFF]. The result may not be able "
<< "to be rendered to your screen." << std::endl;
std::cerr << format_underline(concat_to_string("[warning] "
"input codepoint (", str, ") is too large to decode as "
"a unicode character. The result may not be able to render "
"to your screen."), reg, "should be in [0x00..0x10FFFF]")
<< std::endl;
}
// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx
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
{
throw std::range_error("toml::read_utf8_codepoint: input codepoint `" +
str + "` is too large to decode as utf-8. It should be in range"
" 0x00 ... 0x1FFFFF.");
throw std::range_error(format_underline(concat_to_string("[error] "
"input codepoint (", str, ") is too large to encode as utf-8."),
reg, "should be in [0x00..0x10FFFF]"));
}
return character;
}
@@ -278,7 +281,7 @@ template<typename Container>
result<std::string, std::string> parse_escape_sequence(location<Container>& loc)
{
const auto first = loc.iter();
if(*first != '\\')
if(first == loc.end() || *first != '\\')
{
return err(format_underline("[error]: "
"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 'u' :
{
++loc.iter();
if(const auto token = repeat<lex_hex_dig, exactly<4>>::invoke(loc))
if(const auto token = lex_escape_unicode_short::invoke(loc))
{
return ok(read_utf8_codepoint(token.unwrap().str()));
return ok(read_utf8_codepoint(token.unwrap()));
}
else
{
@@ -310,10 +312,9 @@ result<std::string, std::string> parse_escape_sequence(location<Container>& loc)
}
case 'U':
{
++loc.iter();
if(const auto token = repeat<lex_hex_dig, exactly<8>>::invoke(loc))
if(const auto token = lex_escape_unicode_long::invoke(loc))
{
return ok(read_utf8_codepoint(token.unwrap().str()));
return ok(read_utf8_codepoint(token.unwrap()));
}
else
{
@@ -340,10 +341,11 @@ parse_ml_basic_string(location<Container>& loc)
const auto first = loc.iter();
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;
retval.reserve(inner_loc.source()->size());
retval.reserve(token.unwrap().size());
auto delim = lex_ml_basic_string_delim::invoke(inner_loc);
if(!delim)
@@ -396,7 +398,8 @@ parse_basic_string(location<Container>& loc)
const auto first = loc.iter();
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);
if(!quot)
@@ -406,7 +409,7 @@ parse_basic_string(location<Container>& loc)
}
std::string retval;
retval.reserve(inner_loc.source()->size());
retval.reserve(token.unwrap().size());
quot = err("tmp");
while(!quot)