Merge branch 'v3' of github.com:ToruNiina/toml11 into v3

This commit is contained in:
ToruNiina
2019-06-21 14:31:52 +09:00
8 changed files with 102 additions and 64 deletions

View File

@@ -34,12 +34,15 @@ set(TEST_NAMES
) )
CHECK_CXX_COMPILER_FLAG("-Wall" COMPILER_SUPPORTS_WALL) CHECK_CXX_COMPILER_FLAG("-Wall" COMPILER_SUPPORTS_WALL)
CHECK_CXX_COMPILER_FLAG("-Wextra" COMPILER_SUPPORTS_WEXTRA)
CHECK_CXX_COMPILER_FLAG("-Wpedantic" COMPILER_SUPPORTS_WPEDANTIC) CHECK_CXX_COMPILER_FLAG("-Wpedantic" COMPILER_SUPPORTS_WPEDANTIC)
if(COMPILER_SUPPORTS_WALL) if(COMPILER_SUPPORTS_WALL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif() endif()
if(COMPILER_SUPPORTS_WEXTRA)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
endif()
if(COMPILER_SUPPORTS_WPEDANTIC) if(COMPILER_SUPPORTS_WPEDANTIC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
endif() endif()

View File

@@ -453,7 +453,7 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM)
// value will be "\r\r\n". To avoid the additional "\r", use binary // value will be "\r\r\n". To avoid the additional "\r", use binary
// mode. // mode.
std::ofstream ofs("tmp.toml", std::ios_base::binary); std::ofstream ofs("tmp.toml", std::ios_base::binary);
ofs.write(table.data(), table.size()); ofs.write(table.data(), static_cast<std::streamsize>(table.size()));
} }
const auto data = toml::parse("tmp.toml"); const auto data = toml::parse("tmp.toml");

View File

@@ -46,7 +46,7 @@ inline std::tm localtime_s(const std::time_t* src)
#endif #endif
} // detail } // detail
enum class month_t : std::int8_t enum class month_t : std::uint8_t
{ {
Jan = 0, Jan = 0,
Feb = 1, Feb = 1,
@@ -98,9 +98,9 @@ struct local_date
t.tm_sec = 0; t.tm_sec = 0;
t.tm_min = 0; t.tm_min = 0;
t.tm_hour = 0; t.tm_hour = 0;
t.tm_mday = this->day; t.tm_mday = static_cast<int>(this->day);
t.tm_mon = this->month; t.tm_mon = static_cast<int>(this->month);
t.tm_year = this->year - 1900; t.tm_year = static_cast<int>(this->year) - 1900;
t.tm_wday = 0; // the value will be ignored t.tm_wday = 0; // the value will be ignored
t.tm_yday = 0; // the value will be ignored t.tm_yday = 0; // the value will be ignored
t.tm_isdst = -1; t.tm_isdst = -1;
@@ -188,22 +188,22 @@ struct local_time
explicit local_time(const std::chrono::duration<Rep, Period>& t) explicit local_time(const std::chrono::duration<Rep, Period>& t)
{ {
const auto h = std::chrono::duration_cast<std::chrono::hours>(t); const auto h = std::chrono::duration_cast<std::chrono::hours>(t);
this->hour = h.count(); this->hour = static_cast<std::uint8_t>(h.count());
const auto t2 = t - h; const auto t2 = t - h;
const auto m = std::chrono::duration_cast<std::chrono::minutes>(t2); const auto m = std::chrono::duration_cast<std::chrono::minutes>(t2);
this->minute = m.count(); this->minute = static_cast<std::uint8_t>(m.count());
const auto t3 = t2 - m; const auto t3 = t2 - m;
const auto s = std::chrono::duration_cast<std::chrono::seconds>(t3); const auto s = std::chrono::duration_cast<std::chrono::seconds>(t3);
this->second = s.count(); this->second = static_cast<std::uint8_t>(s.count());
const auto t4 = t3 - s; const auto t4 = t3 - s;
const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t4); const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t4);
this->millisecond = ms.count(); this->millisecond = static_cast<std::uint16_t>(ms.count());
const auto t5 = t4 - ms; const auto t5 = t4 - ms;
const auto us = std::chrono::duration_cast<std::chrono::microseconds>(t5); const auto us = std::chrono::duration_cast<std::chrono::microseconds>(t5);
this->microsecond = us.count(); this->microsecond = static_cast<std::uint16_t>(us.count());
const auto t6 = t5 - us; const auto t6 = t5 - us;
const auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(t6); const auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(t6);
this->nanosecond = ns.count(); this->nanosecond = static_cast<std::uint16_t>(ns.count());
} }
operator std::chrono::nanoseconds() const operator std::chrono::nanoseconds() const

View File

@@ -253,6 +253,11 @@ std::string read_utf8_codepoint(const region<Container>& reg,
std::istringstream iss(str); std::istringstream iss(str);
iss >> std::hex >> codepoint; iss >> std::hex >> codepoint;
const auto to_char = [](const int i) noexcept -> char {
const auto uc = static_cast<unsigned char>(i);
return *reinterpret_cast<const char*>(std::addressof(uc));
};
std::string character; std::string character;
if(codepoint < 0x80) // U+0000 ... U+0079 ; just an ASCII. if(codepoint < 0x80) // U+0000 ... U+0079 ; just an ASCII.
{ {
@@ -261,8 +266,8 @@ std::string read_utf8_codepoint(const region<Container>& reg,
else if(codepoint < 0x800) //U+0080 ... U+07FF else if(codepoint < 0x800) //U+0080 ... U+07FF
{ {
// 110yyyyx 10xxxxxx; 0x3f == 0b0011'1111 // 110yyyyx 10xxxxxx; 0x3f == 0b0011'1111
character += static_cast<unsigned char>(0xC0| codepoint >> 6); character += to_char(0xC0| codepoint >> 6);
character += static_cast<unsigned char>(0x80|(codepoint & 0x3F)); character += to_char(0x80|(codepoint & 0x3F));
} }
else if(codepoint < 0x10000) // U+0800...U+FFFF else if(codepoint < 0x10000) // U+0800...U+FFFF
{ {
@@ -276,17 +281,17 @@ std::string read_utf8_codepoint(const region<Container>& reg,
} }
assert(codepoint < 0xD800 || 0xDFFF < codepoint); assert(codepoint < 0xD800 || 0xDFFF < codepoint);
// 1110yyyy 10yxxxxx 10xxxxxx // 1110yyyy 10yxxxxx 10xxxxxx
character += static_cast<unsigned char>(0xE0| codepoint >> 12); character += to_char(0xE0| codepoint >> 12);
character += static_cast<unsigned char>(0x80|(codepoint >> 6 & 0x3F)); character += to_char(0x80|(codepoint >> 6 & 0x3F));
character += static_cast<unsigned char>(0x80|(codepoint & 0x3F)); character += to_char(0x80|(codepoint & 0x3F));
} }
else if(codepoint < 0x110000) // U+010000 ... U+10FFFF else if(codepoint < 0x110000) // U+010000 ... U+10FFFF
{ {
// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx // 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx
character += static_cast<unsigned char>(0xF0| codepoint >> 18); character += to_char(0xF0| codepoint >> 18);
character += static_cast<unsigned char>(0x80|(codepoint >> 12 & 0x3F)); character += to_char(0x80|(codepoint >> 12 & 0x3F));
character += static_cast<unsigned char>(0x80|(codepoint >> 6 & 0x3F)); character += to_char(0x80|(codepoint >> 6 & 0x3F));
character += static_cast<unsigned char>(0x80|(codepoint & 0x3F)); character += to_char(0x80|(codepoint & 0x3F));
} }
else // out of UTF-8 region else // out of UTF-8 region
{ {
@@ -655,9 +660,9 @@ parse_local_time(location<Container>& loc)
{{std::addressof(inner_loc), "here"}})); {{std::addressof(inner_loc), "here"}}));
} }
local_time time( local_time time(
static_cast<std::int8_t>(from_string<int>(h.unwrap().str(), 0)), from_string<int>(h.unwrap().str(), 0),
static_cast<std::int8_t>(from_string<int>(m.unwrap().str(), 0)), from_string<int>(m.unwrap().str(), 0),
static_cast<std::int8_t>(from_string<int>(s.unwrap().str(), 0)), 0, 0); from_string<int>(s.unwrap().str(), 0), 0, 0);
const auto before_secfrac = inner_loc.iter(); const auto before_secfrac = inner_loc.iter();
if(const auto secfrac = lex_time_secfrac::invoke(inner_loc)) if(const auto secfrac = lex_time_secfrac::invoke(inner_loc))
@@ -673,13 +678,13 @@ parse_local_time(location<Container>& loc)
} }
if(sf.size() >= 6) if(sf.size() >= 6)
{ {
time.millisecond = from_string<std::int16_t>(sf.substr(0, 3), 0); time.millisecond = from_string<std::uint16_t>(sf.substr(0, 3), 0u);
time.microsecond = from_string<std::int16_t>(sf.substr(3, 3), 0); time.microsecond = from_string<std::uint16_t>(sf.substr(3, 3), 0u);
} }
else if(sf.size() >= 3) else if(sf.size() >= 3)
{ {
time.millisecond = from_string<std::int16_t>(sf, 0); time.millisecond = from_string<std::uint16_t>(sf, 0u);
time.microsecond = 0; time.microsecond = 0u;
} }
} }
else else
@@ -1934,7 +1939,8 @@ parse(std::istream& is, const std::string& fname = "unknown file")
is.seekg(beg); is.seekg(beg);
// read whole file as a sequence of char // read whole file as a sequence of char
std::vector<char> letters(fsize); assert(fsize >= 0);
std::vector<char> letters(static_cast<std::size_t>(fsize));
is.read(letters.data(), fsize); is.read(letters.data(), fsize);
detail::location<std::vector<char>> detail::location<std::vector<char>>

View File

@@ -70,6 +70,7 @@ template<typename Container>
struct location final : public region_base struct location final : public region_base
{ {
using const_iterator = typename Container::const_iterator; using const_iterator = typename Container::const_iterator;
using difference_type = typename const_iterator::difference_type;
using source_ptr = std::shared_ptr<const Container>; using source_ptr = std::shared_ptr<const Container>;
static_assert(std::is_same<char, typename Container::value_type>::value,""); static_assert(std::is_same<char, typename Container::value_type>::value,"");
@@ -103,15 +104,17 @@ struct location final : public region_base
// to the location changes the point to look. So an overload of `iter()` // to the location changes the point to look. So an overload of `iter()`
// which returns mutable reference is removed and `advance()`, `retrace()` // which returns mutable reference is removed and `advance()`, `retrace()`
// and `reset()` is added. // and `reset()` is added.
void advance(std::size_t n = 1) noexcept void advance(difference_type n = 1) noexcept
{ {
this->line_number_ += std::count(this->iter_, this->iter_ + n, '\n'); this->line_number_ += static_cast<std::size_t>(
std::count(this->iter_, std::next(this->iter_, n), '\n'));
this->iter_ += n; this->iter_ += n;
return; return;
} }
void retrace(std::size_t n = 1) noexcept void retrace(difference_type n = 1) noexcept
{ {
this->line_number_ -= std::count(this->iter_ - n, this->iter_, '\n'); this->line_number_ -= static_cast<std::size_t>(
std::count(std::prev(this->iter_, n), this->iter_, '\n'));
this->iter_ -= n; this->iter_ -= n;
return; return;
} }
@@ -121,11 +124,13 @@ struct location final : public region_base
// iterators and returns a negative value if `first > last`. // iterators and returns a negative value if `first > last`.
if(0 <= std::distance(rollback, this->iter_)) // rollback < iter if(0 <= std::distance(rollback, this->iter_)) // rollback < iter
{ {
this->line_number_ -= std::count(rollback, this->iter_, '\n'); this->line_number_ -= static_cast<std::size_t>(
std::count(rollback, this->iter_, '\n'));
} }
else // iter < rollback [[unlikely]] else // iter < rollback [[unlikely]]
{ {
this->line_number_ += std::count(this->iter_, rollback, '\n'); this->line_number_ += static_cast<std::size_t>(
std::count(this->iter_, rollback, '\n'));
} }
this->iter_ = rollback; this->iter_ = rollback;
return; return;
@@ -162,11 +167,15 @@ struct location final : public region_base
} }
std::size_t before() const noexcept override std::size_t before() const noexcept override
{ {
return std::distance(this->line_begin(), this->iter()); const auto sz = std::distance(this->line_begin(), this->iter());
assert(sz >= 0);
return static_cast<std::size_t>(sz);
} }
std::size_t after() const noexcept override std::size_t after() const noexcept override
{ {
return std::distance(this->iter(), this->line_end()); const auto sz = std::distance(this->iter(), this->line_end());
assert(sz >= 0);
return static_cast<std::size_t>(sz);
} }
source_ptr const& source() const& noexcept {return source_;} source_ptr const& source() const& noexcept {return source_;}
@@ -250,15 +259,21 @@ struct region final : public region_base
std::size_t size() const noexcept override std::size_t size() const noexcept override
{ {
return std::distance(first_, last_); const auto sz = std::distance(first_, last_);
assert(sz >= 0);
return static_cast<std::size_t>(sz);
} }
std::size_t before() const noexcept override std::size_t before() const noexcept override
{ {
return std::distance(this->line_begin(), this->first()); const auto sz = std::distance(this->line_begin(), this->first());
assert(sz >= 0);
return static_cast<std::size_t>(sz);
} }
std::size_t after() const noexcept override std::size_t after() const noexcept override
{ {
return std::distance(this->last(), this->line_end()); const auto sz = std::distance(this->last(), this->line_end());
assert(sz >= 0);
return static_cast<std::size_t>(sz);
} }
bool contain_newline() const noexcept bool contain_newline() const noexcept
@@ -409,13 +424,14 @@ inline std::string format_underline(const std::string& message,
{ {
assert(!reg_com.empty()); assert(!reg_com.empty());
const auto line_num_width = std::max_element(reg_com.begin(), reg_com.end(), const auto line_num_width = static_cast<int>(std::max_element(
reg_com.begin(), reg_com.end(),
[](std::pair<region_base const*, std::string> const& lhs, [](std::pair<region_base const*, std::string> const& lhs,
std::pair<region_base const*, std::string> const& rhs) std::pair<region_base const*, std::string> const& rhs)
{ {
return lhs.first->line_num().size() < rhs.first->line_num().size(); return lhs.first->line_num().size() < rhs.first->line_num().size();
} }
)->first->line_num().size(); )->first->line_num().size());
std::ostringstream retval; std::ostringstream retval;
retval << message << '\n'; retval << message << '\n';
@@ -438,7 +454,7 @@ inline std::string format_underline(const std::string& message,
retval << ' ' << std::setw(line_num_width) << reg->line_num(); retval << ' ' << std::setw(line_num_width) << reg->line_num();
retval << " | " << reg->line() << '\n'; retval << " | " << reg->line() << '\n';
retval << make_string(line_num_width + 1, ' '); retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ');
retval << " | " << make_string(reg->before(), ' '); retval << " | " << make_string(reg->before(), ' ');
if(reg->size() == 1) if(reg->size() == 1)
@@ -462,7 +478,7 @@ inline std::string format_underline(const std::string& message,
if(!helps.empty()) if(!helps.empty())
{ {
retval << '\n'; retval << '\n';
retval << make_string(line_num_width + 1, ' '); retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ');
retval << " | "; retval << " | ";
for(const auto help : helps) for(const auto help : helps)
{ {

View File

@@ -29,7 +29,7 @@ struct serializer
using array_type = typename value_type::array_type ; using array_type = typename value_type::array_type ;
using table_type = typename value_type::table_type ; using table_type = typename value_type::table_type ;
serializer(const std::size_t w = 80, serializer(const std::size_t w = 80u,
const int float_prec = std::numeric_limits<toml::floating>::max_digits10, const int float_prec = std::numeric_limits<toml::floating>::max_digits10,
const bool can_be_inlined = false, const bool can_be_inlined = false,
std::vector<toml::key> ks = {}) std::vector<toml::key> ks = {})
@@ -50,7 +50,8 @@ struct serializer
{ {
const auto fmt = "%.*g"; const auto fmt = "%.*g";
const auto bsz = std::snprintf(nullptr, 0, fmt, this->float_prec_, f); const auto bsz = std::snprintf(nullptr, 0, fmt, this->float_prec_, f);
std::vector<char> buf(bsz + 1, '\0'); // +1 for null character(\0) // +1 for null character(\0)
std::vector<char> buf(static_cast<std::size_t>(bsz + 1), '\0');
std::snprintf(buf.data(), buf.size(), fmt, this->float_prec_, f); std::snprintf(buf.data(), buf.size(), fmt, this->float_prec_, f);
std::string token(buf.begin(), std::prev(buf.end())); std::string token(buf.begin(), std::prev(buf.end()));
@@ -58,16 +59,27 @@ struct serializer
{ {
token += '0'; token += '0';
} }
const auto e = std::find_if(token.cbegin(), token.cend(),
[](const char c) -> bool { const auto e = std::find_if(
return c == 'E' || c == 'e'; token.cbegin(), token.cend(), [](const char c) noexcept -> bool {
return c == 'e' || c == 'E';
}); });
if(e == token.cend()) const auto has_exponent = (token.cend() != e);
const auto has_fraction = (token.cend() != std::find(
token.cbegin(), token.cend(), '.'));
if(!has_exponent && !has_fraction)
{
// the resulting value does not have any float specific part!
token += ".0";
return token;
}
if(!has_exponent)
{ {
return token; // there is no exponent part. just return it. return token; // there is no exponent part. just return it.
} }
// zero-prefix in an exponent is not allowed in TOML. // zero-prefix in an exponent is NOT allowed in TOML.
// remove it if it exists. // remove it if it exists.
bool sign_exists = false; bool sign_exists = false;
std::size_t zero_prefix = 0; std::size_t zero_prefix = 0;
@@ -81,7 +93,8 @@ struct serializer
{ {
const auto offset = std::distance(token.cbegin(), e) + const auto offset = std::distance(token.cbegin(), e) +
(sign_exists ? 2 : 1); (sign_exists ? 2 : 1);
token.erase(offset, zero_prefix); token.erase(static_cast<typename std::string::size_type>(offset),
zero_prefix);
} }
return token; return token;
} }
@@ -609,7 +622,7 @@ struct serializer
template<typename C, template<typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
std::string std::string
format(const basic_value<C, M, V>& v, std::size_t w = 80, format(const basic_value<C, M, V>& v, std::size_t w = 80u,
int fprec = std::numeric_limits<toml::floating>::max_digits10, int fprec = std::numeric_limits<toml::floating>::max_digits10,
bool force_inline = false) bool force_inline = false)
{ {
@@ -638,8 +651,8 @@ std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const basic_value<C, M, V>& v) operator<<(std::basic_ostream<charT, traits>& os, const basic_value<C, M, V>& v)
{ {
// get status of std::setw(). // get status of std::setw().
const std::size_t w = os.width(); const auto w = static_cast<std::size_t>(os.width());
const int fprec = os.precision(); const int fprec = static_cast<int>(os.precision());
os.width(0); os.width(0);
if(!v.comments().empty()) if(!v.comments().empty())

View File

@@ -48,9 +48,9 @@ struct source_location
{ {
if(reg) if(reg)
{ {
line_num_ = std::stoul(reg->line_num()); line_num_ = static_cast<std::uint_least32_t>(std::stoul(reg->line_num()));
column_num_ = reg->before() + 1; column_num_ = static_cast<std::uint_least32_t>(reg->before() + 1);
region_size_ = reg->size(); region_size_ = static_cast<std::uint_least32_t>(reg->size());
file_name_ = reg->name(); file_name_ = reg->name();
line_str_ = reg->line(); line_str_ = reg->line();
} }

View File

@@ -601,7 +601,7 @@ class basic_value
: type_(value_t::floating), : type_(value_t::floating),
region_info_(std::make_shared<region_base>(region_base{})) region_info_(std::make_shared<region_base>(region_base{}))
{ {
assigner(this->floating_, f); assigner(this->floating_, static_cast<floating>(f));
} }
template<typename T, typename Container, typename std::enable_if< template<typename T, typename Container, typename std::enable_if<
@@ -611,7 +611,7 @@ class basic_value
region_info_(std::make_shared<detail::region<Container>>(std::move(reg))), region_info_(std::make_shared<detail::region<Container>>(std::move(reg))),
comments_(region_info_->comments()) comments_(region_info_->comments())
{ {
assigner(this->floating_, f); assigner(this->floating_, static_cast<floating>(f));
} }
template<typename T, typename std::enable_if< template<typename T, typename std::enable_if<
@@ -621,7 +621,7 @@ class basic_value
this->cleanup(); this->cleanup();
this->type_ = value_t::floating; this->type_ = value_t::floating;
this->region_info_ = std::make_shared<region_base>(region_base{}); this->region_info_ = std::make_shared<region_base>(region_base{});
assigner(this->floating_, f); assigner(this->floating_, static_cast<floating>(f));
return *this; return *this;
} }