Merge branch 'master' into find-idx

This commit is contained in:
ToruNiina
2020-01-07 22:13:15 +09:00
21 changed files with 910 additions and 288 deletions

64
toml/color.hpp Normal file
View File

@@ -0,0 +1,64 @@
#ifndef TOML11_COLOR_HPP
#define TOML11_COLOR_HPP
#include <ostream>
#include <cstdint>
#ifdef TOML11_COLORIZE_ERROR_MESSAGE
#define TOML11_ERROR_MESSAGE_COLORIZED true
#else
#define TOML11_ERROR_MESSAGE_COLORIZED false
#endif
namespace toml
{
// put ANSI escape sequence to ostream
namespace color_ansi
{
namespace detail
{
inline int colorize_index()
{
static const int index = std::ios_base::xalloc();
return index;
}
} // detail
inline std::ostream& colorize(std::ostream& os)
{
// by default, it is zero.
os.iword(detail::colorize_index()) = 1;
return os;
}
inline std::ostream& nocolorize(std::ostream& os)
{
os.iword(detail::colorize_index()) = 0;
return os;
}
inline std::ostream& reset (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[00m";} return os;}
inline std::ostream& bold (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[01m";} return os;}
inline std::ostream& grey (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[30m";} return os;}
inline std::ostream& red (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[31m";} return os;}
inline std::ostream& green (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[32m";} return os;}
inline std::ostream& yellow (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[33m";} return os;}
inline std::ostream& blue (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[34m";} return os;}
inline std::ostream& magenta(std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[35m";} return os;}
inline std::ostream& cyan (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[36m";} return os;}
inline std::ostream& white (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[37m";} return os;}
} // color_ansi
// ANSI escape sequence is the only and default colorization method currently
namespace color = color_ansi;
} // toml
#endif// TOML11_COLOR_HPP

View File

@@ -45,6 +45,7 @@ inline std::string show_char(const char c)
buf.fill('\0');
const auto r = std::snprintf(
buf.data(), buf.size(), "0x%02x", static_cast<int>(c) & 0xFF);
(void) r; // Unused variable warning
assert(r == static_cast<int>(buf.size()) - 1);
return std::string(buf.data());
}

View File

@@ -20,7 +20,7 @@ namespace toml
namespace detail
{
// TODO: find more sophisticated way to handle this
#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE
#if _POSIX_C_SOURCE >= 1 || defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(_POSIX_SOURCE)
inline std::tm localtime_s(const std::time_t* src)
{
std::tm dst;
@@ -28,6 +28,13 @@ inline std::tm localtime_s(const std::time_t* src)
if (!result) { throw std::runtime_error("localtime_r failed."); }
return dst;
}
inline std::tm gmtime_s(const std::time_t* src)
{
std::tm dst;
const auto result = ::gmtime_r(src, &dst);
if (!result) { throw std::runtime_error("gmtime_r failed."); }
return dst;
}
#elif _MSC_VER
inline std::tm localtime_s(const std::time_t* src)
{
@@ -36,13 +43,26 @@ inline std::tm localtime_s(const std::time_t* src)
if (result) { throw std::runtime_error("localtime_s failed."); }
return dst;
}
#else
inline std::tm gmtime_s(const std::time_t* src)
{
std::tm dst;
const auto result = ::gmtime_s(&dst, src);
if (result) { throw std::runtime_error("gmtime_s failed."); }
return dst;
}
#else // fallback. not threadsafe
inline std::tm localtime_s(const std::time_t* src)
{
const auto result = std::localtime(src);
if (!result) { throw std::runtime_error("localtime failed."); }
return *result;
}
inline std::tm gmtime_s(const std::time_t* src)
{
const auto result = std::gmtime(src);
if (!result) { throw std::runtime_error("gmtime failed."); }
return *result;
}
#endif
} // detail
@@ -378,10 +398,31 @@ struct local_datetime
{
using internal_duration =
typename std::chrono::system_clock::time_point::duration;
// Normally DST begins at A.M. 3 or 4. If we re-use conversion operator
// of local_date and local_time independently, the conversion fails if
// it is the day when DST begins or ends. Since local_date considers the
// time is 00:00 A.M. and local_time does not consider DST because it
// does not have any date information. We need to consider both date and
// time information at the same time to convert it correctly.
std::tm t;
t.tm_sec = static_cast<int>(this->time.second);
t.tm_min = static_cast<int>(this->time.minute);
t.tm_hour = static_cast<int>(this->time.hour);
t.tm_mday = static_cast<int>(this->date.day);
t.tm_mon = static_cast<int>(this->date.month);
t.tm_year = static_cast<int>(this->date.year) - 1900;
t.tm_wday = 0; // the value will be ignored
t.tm_yday = 0; // the value will be ignored
t.tm_isdst = -1;
// std::mktime returns date as local time zone. no conversion needed
auto dt = std::chrono::system_clock::time_point(this->date);
auto dt = std::chrono::system_clock::from_time_t(std::mktime(&t));
dt += std::chrono::duration_cast<internal_duration>(
std::chrono::nanoseconds(this->time));
std::chrono::milliseconds(this->time.millisecond) +
std::chrono::microseconds(this->time.microsecond) +
std::chrono::nanoseconds (this->time.nanosecond));
return dt;
}
@@ -447,40 +488,71 @@ struct offset_datetime
: date(dt.date), time(dt.time), offset(o)
{}
explicit offset_datetime(const local_datetime& ld)
: date(ld.date), time(ld.time), offset(get_local_offset())
: date(ld.date), time(ld.time), offset(get_local_offset(nullptr))
// use the current local timezone offset
{}
explicit offset_datetime(const std::chrono::system_clock::time_point& tp)
: offset_datetime(local_datetime(tp))
{}
: offset(0, 0) // use gmtime
{
const auto timet = std::chrono::system_clock::to_time_t(tp);
const auto tm = detail::gmtime_s(&timet);
this->date = local_date(tm);
this->time = local_time(tm);
}
explicit offset_datetime(const std::time_t& t)
: offset_datetime(local_datetime(t))
{}
: offset(0, 0) // use gmtime
{
const auto tm = detail::gmtime_s(&t);
this->date = local_date(tm);
this->time = local_time(tm);
}
explicit offset_datetime(const std::tm& t)
: offset_datetime(local_datetime(t))
{}
: offset(0, 0) // assume gmtime
{
this->date = local_date(t);
this->time = local_time(t);
}
operator std::chrono::system_clock::time_point() const
{
// get date-time
using internal_duration =
typename std::chrono::system_clock::time_point::duration;
std::chrono::system_clock::time_point tp =
std::chrono::system_clock::time_point(this->date) +
std::chrono::duration_cast<internal_duration>(
std::chrono::nanoseconds(this->time));
// get date-time in UTC. let's say we are in +09:00 (JPN).
// writing 12:00:00 in +09:00 means 03:00:00Z. to represent
// 12:00:00Z, first we need to add +09:00.
const auto ofs = get_local_offset();
// first, convert it to local date-time information in the same way as
// local_datetime does. later we will use time_t to adjust time offset.
std::tm t;
t.tm_sec = static_cast<int>(this->time.second);
t.tm_min = static_cast<int>(this->time.minute);
t.tm_hour = static_cast<int>(this->time.hour);
t.tm_mday = static_cast<int>(this->date.day);
t.tm_mon = static_cast<int>(this->date.month);
t.tm_year = static_cast<int>(this->date.year) - 1900;
t.tm_wday = 0; // the value will be ignored
t.tm_yday = 0; // the value will be ignored
t.tm_isdst = -1;
const std::time_t tp_loc = std::mktime(std::addressof(t));
auto tp = std::chrono::system_clock::from_time_t(tp_loc);
tp += std::chrono::duration_cast<internal_duration>(
std::chrono::milliseconds(this->time.millisecond) +
std::chrono::microseconds(this->time.microsecond) +
std::chrono::nanoseconds (this->time.nanosecond));
// Since mktime uses local time zone, it should be corrected.
// `12:00:00+09:00` means `03:00:00Z`. So mktime returns `03:00:00Z` if
// we are in `+09:00` timezone. To represent `12:00:00Z` there, we need
// to add `+09:00` to `03:00:00Z`.
// Here, it uses the time_t converted from date-time info to handle
// daylight saving time.
const auto ofs = get_local_offset(std::addressof(tp_loc));
tp += std::chrono::hours (ofs.hour);
tp += std::chrono::minutes(ofs.minute);
// here, tp represents 12:00:00 in UTC but we have offset information.
// we need to subtract it. For example, let's say the input is
// 12:00:00-08:00. now we have tp = 12:00:00Z as a result of the above
// conversion. But the actual time we need to return is 20:00:00Z
// because of -08:00.
// We got `12:00:00Z` by correcting local timezone applied by mktime.
// Then we will apply the offset. Let's say `12:00:00-08:00` is given.
// And now, we have `12:00:00Z`. `12:00:00-08:00` means `20:00:00Z`.
// So we need to subtract the offset.
tp -= std::chrono::minutes(this->offset);
return tp;
}
@@ -500,11 +572,10 @@ struct offset_datetime
private:
static time_offset get_local_offset()
static time_offset get_local_offset(const std::time_t* tp)
{
// get current timezone
const auto tmp1 = std::time(nullptr);
const auto t = detail::localtime_s(&tmp1);
// get local timezone with the same date-time information as mktime
const auto t = detail::localtime_s(tp);
std::array<char, 6> buf;
const auto result = std::strftime(buf.data(), 6, "%z", &t); // +hhmm\0

View File

@@ -2,6 +2,7 @@
// Distributed under the MIT License.
#ifndef TOML11_EXCEPTION_HPP
#define TOML11_EXCEPTION_HPP
#include "source_location.hpp"
#include <stdexcept>
#include <string>
@@ -11,15 +12,21 @@ namespace toml
struct exception : public std::exception
{
public:
exception(const source_location& loc): loc_(loc) {}
virtual ~exception() noexcept override = default;
virtual const char* what() const noexcept override {return "";}
virtual source_location const& location() const noexcept {return loc_;}
protected:
source_location loc_;
};
struct syntax_error : public toml::exception
{
public:
explicit syntax_error(const std::string& what_arg) : what_(what_arg){}
explicit syntax_error(const char* what_arg) : what_(what_arg){}
explicit syntax_error(const std::string& what_arg, const source_location& loc)
: exception(loc), what_(what_arg)
{}
virtual ~syntax_error() noexcept override = default;
virtual const char* what() const noexcept override {return what_.c_str();}
@@ -30,8 +37,9 @@ struct syntax_error : public toml::exception
struct type_error : public toml::exception
{
public:
explicit type_error(const std::string& what_arg) : what_(what_arg){}
explicit type_error(const char* what_arg) : what_(what_arg){}
explicit type_error(const std::string& what_arg, const source_location& loc)
: exception(loc), what_(what_arg)
{}
virtual ~type_error() noexcept override = default;
virtual const char* what() const noexcept override {return what_.c_str();}
@@ -42,10 +50,12 @@ struct type_error : public toml::exception
struct internal_error : public toml::exception
{
public:
explicit internal_error(const std::string& what_arg) : what_(what_arg){}
explicit internal_error(const char* what_arg) : what_(what_arg){}
explicit internal_error(const std::string& what_arg, const source_location& loc)
: exception(loc), what_(what_arg)
{}
virtual ~internal_error() noexcept override = default;
virtual const char* what() const noexcept override {return what_.c_str();}
protected:
std::string what_;
};

View File

@@ -186,11 +186,11 @@ get(const basic_value<C, M, V>& v)
}
default:
{
throw type_error(detail::format_underline("[error] toml::value "
throw type_error(detail::format_underline("toml::value: "
"bad_cast to std::chrono::system_clock::time_point", {
{std::addressof(detail::get_region(v)),
concat_to_string("the actual type is ", v.type())}
}));
}), v.location());
}
}
}
@@ -301,7 +301,7 @@ get(const basic_value<C, M, V>& v)
if(ar.size() != container.size())
{
throw std::out_of_range(detail::format_underline(concat_to_string(
"[erorr] toml::get specified container size is ", container.size(),
"toml::get: specified container size is ", container.size(),
" but there are ", ar.size(), " elements in toml array."), {
{std::addressof(detail::get_region(v)), "here"}
}));
@@ -326,7 +326,7 @@ get(const basic_value<C, M, V>& v)
if(ar.size() != 2)
{
throw std::out_of_range(detail::format_underline(concat_to_string(
"[erorr] toml::get specified std::pair but there are ", ar.size(),
"toml::get: specified std::pair but there are ", ar.size(),
" elements in toml array."), {
{std::addressof(detail::get_region(v)), "here"}
}));
@@ -357,8 +357,8 @@ get(const basic_value<C, M, V>& v)
if(ar.size() != std::tuple_size<T>::value)
{
throw std::out_of_range(detail::format_underline(concat_to_string(
"[erorr] toml::get specified std::tuple with ",
std::tuple_size<T>::value, "elements, but there are ", ar.size(),
"toml::get: specified std::tuple with ",
std::tuple_size<T>::value, " elements, but there are ", ar.size(),
" elements in toml array."), {
{std::addressof(detail::get_region(v)), "here"}
}));
@@ -430,7 +430,7 @@ basic_value<C, M, V> const& find(const basic_value<C, M, V>& v, const key& ky)
if(tab.count(ky) == 0)
{
throw std::out_of_range(detail::format_underline(concat_to_string(
"[error] key \"", ky, "\" not found"), {
"key \"", ky, "\" not found"), {
{std::addressof(detail::get_region(v)), "in this table"}
}));
}
@@ -444,7 +444,7 @@ basic_value<C, M, V>& find(basic_value<C, M, V>& v, const key& ky)
if(tab.count(ky) == 0)
{
throw std::out_of_range(detail::format_underline(concat_to_string(
"[error] key \"", ky, "\" not found"), {
"key \"", ky, "\" not found"), {
{std::addressof(detail::get_region(v)), "in this table"}
}));
}
@@ -458,7 +458,7 @@ basic_value<C, M, V> find(basic_value<C, M, V>&& v, const key& ky)
if(tab.count(ky) == 0)
{
throw std::out_of_range(detail::format_underline(concat_to_string(
"[error] key \"", ky, "\" not found"), {
"key \"", ky, "\" not found"), {
{std::addressof(detail::get_region(v)), "in this table"}
}));
}
@@ -523,7 +523,7 @@ find(const basic_value<C, M, V>& v, const key& ky)
if(tab.count(ky) == 0)
{
throw std::out_of_range(detail::format_underline(concat_to_string(
"[error] key \"", ky, "\" not found"), {
"key \"", ky, "\" not found"), {
{std::addressof(detail::get_region(v)), "in this table"}
}));
}
@@ -539,7 +539,7 @@ find(basic_value<C, M, V>& v, const key& ky)
if(tab.count(ky) == 0)
{
throw std::out_of_range(detail::format_underline(concat_to_string(
"[error] key \"", ky, "\" not found"), {
"key \"", ky, "\" not found"), {
{std::addressof(detail::get_region(v)), "in this table"}
}));
}
@@ -555,7 +555,7 @@ find(basic_value<C, M, V>&& v, const key& ky)
if(tab.count(ky) == 0)
{
throw std::out_of_range(detail::format_underline(concat_to_string(
"[error] key \"", ky, "\" not found"), {
"key \"", ky, "\" not found"), {
{std::addressof(detail::get_region(v)), "in this table"}
}));
}

View File

@@ -76,7 +76,8 @@ inline ::toml::value operator"" _toml(const char* str, std::size_t len)
}
else // none of them.
{
throw ::toml::syntax_error(data.unwrap_err());
throw ::toml::syntax_error(data.unwrap_err(),
source_location(std::addressof(loc)));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
// Distributed under the MIT License.
#ifndef TOML11_REGION_HPP
#define TOML11_REGION_HPP
#include "exception.hpp"
#include <memory>
#include <vector>
#include <algorithm>
@@ -10,6 +9,7 @@
#include <iterator>
#include <iomanip>
#include <cassert>
#include "color.hpp"
namespace toml
{
@@ -231,11 +231,10 @@ struct region final : public region_base
region& operator+=(const region& other)
{
if(this->begin() != other.begin() || this->end() != other.end() ||
this->last_ != other.first_)
{
throw internal_error("invalid region concatenation");
}
// different regions cannot be concatenated
assert(this->begin() == other.begin() && this->end() == other.end() &&
this->last_ == other.first_);
this->last_ = other.last_;
return *this;
}
@@ -420,7 +419,8 @@ struct region final : public region_base
// to show a better error message.
inline std::string format_underline(const std::string& message,
const std::vector<std::pair<region_base const*, std::string>>& reg_com,
const std::vector<std::string>& helps = {})
const std::vector<std::string>& helps = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED)
{
assert(!reg_com.empty());
@@ -434,7 +434,27 @@ inline std::string format_underline(const std::string& message,
)->first->line_num().size());
std::ostringstream retval;
retval << message << '\n';
if(colorize)
{
retval << color::colorize; // turn on ANSI color
}
// XXX
// Here, before `colorize` support, it does not output `[error]` prefix
// automatically. So some user may output it manually and this change may
// duplicate the prefix. To avoid it, check the first 7 characters and
// if it is "[error]", it removes that part from the message shown.
if(message.size() > 7 && message.substr(0, 7) == "[error]")
{
retval << color::bold << color::red << "[error]" << color::reset
<< color::bold << message.substr(7) << color::reset << '\n';
}
else
{
retval << color::bold << color::red << "[error] " << color::reset
<< color::bold << message << color::reset << '\n';
}
for(auto iter = reg_com.begin(); iter != reg_com.end(); ++iter)
{
@@ -442,34 +462,42 @@ inline std::string format_underline(const std::string& message,
if(iter != reg_com.begin() &&
std::prev(iter)->first->name() == iter->first->name())
{
retval << "\n ...\n";
retval << color::bold << color::blue << "\n ...\n" << color::reset;
}
else // if filename differs, print " --> filename.toml"
{
if(iter != reg_com.begin()) {retval << '\n';}
retval << " --> " << iter->first->name() << '\n';
retval << color::bold << color::blue << " --> " << color::reset
<< iter->first->name() << '\n';
// add one almost-empty line for readability
retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ')
<< color::bold << color::blue << " | " << color::reset << '\n';
}
const region_base* const reg = iter->first;
const std::string& comment = iter->second;
retval << ' ' << std::setw(line_num_width) << reg->line_num();
retval << " | " << reg->line() << '\n';
retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ');
retval << " | " << make_string(reg->before(), ' ');
retval << ' ' << color::bold << color::blue << std::setw(line_num_width)
<< std::right << reg->line_num() << " | " << color::reset
<< reg->line() << '\n';
retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ')
<< color::bold << color::blue << " | " << color::reset
<< make_string(reg->before(), ' ');
if(reg->size() == 1)
{
// invalid
// ^------
retval << '^';
retval << make_string(reg->after(), '-');
retval << color::bold << color::red
<< '^' << make_string(reg->after(), '-') << color::reset;
}
else
{
// invalid
// ~~~~~~~
const auto underline_len = std::min(reg->size(), reg->line().size());
retval << make_string(underline_len, '~');
retval << color::bold << color::red
<< make_string(underline_len, '~') << color::reset;
}
retval << ' ';
retval << comment;
@@ -479,10 +507,10 @@ inline std::string format_underline(const std::string& message,
{
retval << '\n';
retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ');
retval << " | ";
retval << color::bold << color::blue << " | " << color::reset;
for(const auto help : helps)
{
retval << "\nHint: ";
retval << color::bold << "\nHint: " << color::reset;
retval << help;
}
}

View File

@@ -118,8 +118,14 @@ struct serializer
{
return token; // there is no exponent part. just return it.
}
// zero-prefix in an exponent is NOT allowed in TOML.
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
// Although currently it is not released yet, TOML will allow
// zero-prefix in an exponent part such as 1.234e+01.
// The following code removes the zero prefixes.
// If the feature is activated, the following codes can be skipped.
return token;
#endif
// zero-prefix in an exponent is NOT allowed in TOML v0.5.0.
// remove it if it exists.
bool sign_exists = false;
std::size_t zero_prefix = 0;

View File

@@ -48,7 +48,11 @@ struct source_location
{
if(reg)
{
line_num_ = static_cast<std::uint_least32_t>(std::stoul(reg->line_num()));
if(reg->line_num() != detail::region_base().line_num())
{
line_num_ = static_cast<std::uint_least32_t>(
std::stoul(reg->line_num()));
}
column_num_ = static_cast<std::uint_least32_t>(reg->before() + 1);
region_size_ = static_cast<std::uint_least32_t>(reg->size());
file_name_ = reg->name();

View File

@@ -2,6 +2,7 @@
// Distributed under the MIT License.
#ifndef TOML11_STRING_HPP
#define TOML11_STRING_HPP
#include <algorithm>
#include <string>
#include <cstdint>
#if __cplusplus >= 201703L
@@ -45,6 +46,11 @@ struct string
operator std::string const& () const& noexcept {return str;}
operator std::string&& () && noexcept {return std::move(str);}
string& operator+=(const char* rhs) {str += rhs; return *this;}
string& operator+=(const char rhs) {str += rhs; return *this;}
string& operator+=(const std::string& rhs) {str += rhs; return *this;}
string& operator+=(const string& rhs) {str += rhs.str; return *this;}
#if __cplusplus >= 201703L
explicit string(std::string_view s): kind(string_t::basic), str(s){}
string(std::string_view s, string_t k): kind(k), str(s){}
@@ -54,6 +60,8 @@ struct string
explicit operator std::string_view() const noexcept
{return std::string_view(str);}
string& operator+=(const std::string_view& rhs) {str += rhs; return *this;}
#endif
string_t kind;

View File

@@ -105,7 +105,7 @@ struct has_into_toml_method
: decltype(has_into_toml_method_impl::check<T>(nullptr)){};
#ifdef __INTEL_COMPILER
#undef decltype(...)
#undef decltype
#endif
// ---------------------------------------------------------------------------

View File

@@ -32,10 +32,10 @@ template<value_t Expected,
throw_bad_cast(value_t actual, const ::toml::basic_value<C, T, A>& v)
{
throw type_error(detail::format_underline(concat_to_string(
"[error] toml::value bad_cast to ", Expected), {
"toml::value: bad_cast to ", Expected), {
{std::addressof(get_region(v)),
concat_to_string("the actual type is ", actual)}
}));
}), v.location());
}
// switch by `value_t` and call the corresponding `value::as_xxx()`. {{{
@@ -1579,6 +1579,14 @@ class basic_value
{
return this->as_table().at(k);
}
value_type& operator[](const key& k)
{
if(this->is_uninitialized())
{
*this = table_type{};
}
return this->as_table()[k];
}
value_type& at(const std::size_t idx)
{
@@ -1589,6 +1597,15 @@ class basic_value
return this->as_array().at(idx);
}
value_type& operator[](const std::size_t idx) noexcept
{
return this->as_array(std::nothrow)[idx];
}
value_type const& operator[](const std::size_t idx) const noexcept
{
return this->as_array(std::nothrow)[idx];
}
source_location location() const
{
return source_location(this->region_info_.get());
@@ -1843,25 +1860,27 @@ operator>=(const basic_value<C, T, A>& lhs, const basic_value<C, T, A>& rhs)
template<typename C, template<typename ...> class T, template<typename ...> class A>
inline std::string format_error(const std::string& err_msg,
const basic_value<C, T, A>& v, const std::string& comment,
std::vector<std::string> hints = {})
std::vector<std::string> hints = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED)
{
return detail::format_underline(err_msg,
std::vector<std::pair<detail::region_base const*, std::string>>{
{std::addressof(detail::get_region(v)), comment}
}, std::move(hints));
}, std::move(hints), colorize);
}
template<typename C, template<typename ...> class T, template<typename ...> class A>
inline std::string format_error(const std::string& err_msg,
const toml::basic_value<C, T, A>& v1, const std::string& comment1,
const toml::basic_value<C, T, A>& v2, const std::string& comment2,
std::vector<std::string> hints = {})
std::vector<std::string> hints = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED)
{
return detail::format_underline(err_msg,
std::vector<std::pair<detail::region_base const*, std::string>>{
{std::addressof(detail::get_region(v1)), comment1},
{std::addressof(detail::get_region(v2)), comment2}
}, std::move(hints));
}, std::move(hints), colorize);
}
template<typename C, template<typename ...> class T, template<typename ...> class A>
@@ -1869,14 +1888,15 @@ inline std::string format_error(const std::string& err_msg,
const toml::basic_value<C, T, A>& v1, const std::string& comment1,
const toml::basic_value<C, T, A>& v2, const std::string& comment2,
const toml::basic_value<C, T, A>& v3, const std::string& comment3,
std::vector<std::string> hints = {})
std::vector<std::string> hints = {},
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED)
{
return detail::format_underline(err_msg,
std::vector<std::pair<detail::region_base const*, std::string>>{
{std::addressof(detail::get_region(v1)), comment1},
{std::addressof(detail::get_region(v2)), comment2},
{std::addressof(detail::get_region(v3)), comment3}
}, std::move(hints));
}, std::move(hints), colorize);
}
template<typename Visitor, typename C,