mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 19:10:11 +08:00

source_location stores the whole line. In case of short range in a long line like: ``` array = [1, 2, 3, ... , 100, 101, ..., 10000] ^^^- the region ``` It save the whole line as a `std::stirng`. It consumes a lot of memory and slows down everything. We can omit most of the part of the line because we only need the region, `100` here.
149 lines
4.4 KiB
C++
149 lines
4.4 KiB
C++
#ifndef TOML11_SOURCE_LOCATION_FWD_HPP
|
|
#define TOML11_SOURCE_LOCATION_FWD_HPP
|
|
|
|
#include "../region.hpp"
|
|
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace toml
|
|
{
|
|
|
|
//
|
|
// A struct to contain location in a toml file.
|
|
//
|
|
// To reduce memory consumption, it omits unrelated parts of long lines. like:
|
|
//
|
|
// 1. one long line, short region
|
|
// ```
|
|
// |
|
|
// 1 | ... "foo", "bar", baz, "qux", "foobar", ...
|
|
// | ^-- unknown value
|
|
// ```
|
|
// 2. long region
|
|
// ```
|
|
// |
|
|
// 1 | array = [ "foo", ... "bar" ]
|
|
// | ^^^^^^^^^^^^^^^^^^^^- in this array
|
|
// ```
|
|
// 3. many lines
|
|
// |
|
|
// 1 | array = [ "foo",
|
|
// | ^^^^^^^^
|
|
// | ...
|
|
// | ^^^
|
|
// |
|
|
// 10 | , "bar"]
|
|
// | ^^^^^^^^- in this array
|
|
// ```
|
|
//
|
|
struct source_location
|
|
{
|
|
public:
|
|
|
|
explicit source_location(const detail::region& r);
|
|
~source_location() = default;
|
|
source_location(source_location const&) = default;
|
|
source_location(source_location &&) = default;
|
|
source_location& operator=(source_location const&) = default;
|
|
source_location& operator=(source_location &&) = default;
|
|
|
|
bool is_ok() const noexcept {return this->is_ok_;}
|
|
std::size_t length() const noexcept {return this->length_;}
|
|
|
|
std::size_t first_line_number() const noexcept {return this->first_line_;}
|
|
std::size_t first_column_number() const noexcept {return this->first_column_;}
|
|
std::size_t last_line_number() const noexcept {return this->last_line_;}
|
|
std::size_t last_column_number() const noexcept {return this->last_column_;}
|
|
|
|
std::string const& file_name() const noexcept {return this->file_name_;}
|
|
|
|
std::size_t num_lines() const noexcept {return this->line_str_.size();}
|
|
|
|
std::string const& first_line() const;
|
|
std::string const& last_line() const;
|
|
|
|
std::vector<std::string> const& lines() const noexcept {return line_str_;}
|
|
|
|
// for internal use
|
|
std::size_t first_column_offset() const noexcept {return this->first_offset_;}
|
|
std::size_t last_column_offset() const noexcept {return this->last_offset_;}
|
|
|
|
private:
|
|
|
|
bool is_ok_;
|
|
std::size_t first_line_;
|
|
std::size_t first_column_; // column num in the actual file
|
|
std::size_t first_offset_; // column num in the shown line
|
|
std::size_t last_line_;
|
|
std::size_t last_column_; // column num in the actual file
|
|
std::size_t last_offset_; // column num in the shown line
|
|
std::size_t length_;
|
|
std::string file_name_;
|
|
std::vector<std::string> line_str_;
|
|
};
|
|
|
|
namespace detail
|
|
{
|
|
|
|
std::size_t integer_width_base10(std::size_t i) noexcept;
|
|
|
|
inline std::size_t line_width() noexcept {return 0;}
|
|
|
|
template<typename ... Ts>
|
|
std::size_t line_width(const source_location& loc, const std::string& /*msg*/,
|
|
const Ts& ... tail) noexcept
|
|
{
|
|
return (std::max)(
|
|
integer_width_base10(loc.last_line_number()), line_width(tail...));
|
|
}
|
|
|
|
std::ostringstream&
|
|
format_filename(std::ostringstream& oss, const source_location& loc);
|
|
|
|
std::ostringstream&
|
|
format_empty_line(std::ostringstream& oss, const std::size_t lnw);
|
|
|
|
std::ostringstream& format_line(std::ostringstream& oss,
|
|
const std::size_t lnw, const std::size_t linenum, const std::string& line);
|
|
|
|
std::ostringstream& format_underline(std::ostringstream& oss,
|
|
const std::size_t lnw, const std::size_t col, const std::size_t len,
|
|
const std::string& msg);
|
|
|
|
std::string format_location_impl(const std::size_t lnw,
|
|
const std::string& prev_fname,
|
|
const source_location& loc, const std::string& msg);
|
|
|
|
inline std::string format_location_rec(const std::size_t, const std::string&)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
template<typename ... Ts>
|
|
std::string format_location_rec(const std::size_t lnw,
|
|
const std::string& prev_fname,
|
|
const source_location& loc, const std::string& msg,
|
|
const Ts& ... tail)
|
|
{
|
|
return format_location_impl(lnw, prev_fname, loc, msg) +
|
|
format_location_rec(lnw, loc.file_name(), tail...);
|
|
}
|
|
|
|
} // namespace detail
|
|
|
|
// format a location info without title
|
|
template<typename ... Ts>
|
|
std::string format_location(
|
|
const source_location& loc, const std::string& msg, const Ts& ... tail)
|
|
{
|
|
const auto lnw = detail::line_width(loc, msg, tail...);
|
|
|
|
const std::string f(""); // at the 1st iteration, no prev_filename is given
|
|
return detail::format_location_rec(lnw, f, loc, msg, tail...);
|
|
}
|
|
|
|
} // toml
|
|
#endif // TOML11_SOURCE_LOCATION_FWD_HPP
|