mirror of
https://github.com/pantor/inja.git
synced 2026-03-17 14:35:57 +00:00
There is an inline function that assumes the compiler has copy elision optimization which is actually not required until C++17. GCC 4.8 does it but it requires the copy constructor to be defined which is not the case for std::ifstream. Fixed by passing reference by parameter. Co-authored-by: Rafael Lorenzo Alonso <ralorenz@cisco.com>
71 lines
2.0 KiB
C++
71 lines
2.0 KiB
C++
// Copyright (c) 2020 Pantor. All rights reserved.
|
|
|
|
#ifndef INCLUDE_INJA_UTILS_HPP_
|
|
#define INCLUDE_INJA_UTILS_HPP_
|
|
|
|
#include <algorithm>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "exceptions.hpp"
|
|
#include "string_view.hpp"
|
|
|
|
namespace inja {
|
|
|
|
inline void open_file_or_throw(const std::string &path, std::ifstream &file) {
|
|
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
|
try {
|
|
file.open(path);
|
|
} catch (const std::ios_base::failure & /*e*/) {
|
|
throw FileError("failed accessing file at '" + path + "'");
|
|
}
|
|
}
|
|
|
|
namespace string_view {
|
|
inline nonstd::string_view slice(nonstd::string_view view, size_t start, size_t end) {
|
|
start = std::min(start, view.size());
|
|
end = std::min(std::max(start, end), view.size());
|
|
return view.substr(start, end - start);
|
|
}
|
|
|
|
inline std::pair<nonstd::string_view, nonstd::string_view> split(nonstd::string_view view, char Separator) {
|
|
size_t idx = view.find(Separator);
|
|
if (idx == nonstd::string_view::npos) {
|
|
return std::make_pair(view, nonstd::string_view());
|
|
}
|
|
return std::make_pair(slice(view, 0, idx), slice(view, idx + 1, nonstd::string_view::npos));
|
|
}
|
|
|
|
inline bool starts_with(nonstd::string_view view, nonstd::string_view prefix) {
|
|
return (view.size() >= prefix.size() && view.compare(0, prefix.size(), prefix) == 0);
|
|
}
|
|
} // namespace string_view
|
|
|
|
inline SourceLocation get_source_location(nonstd::string_view content, size_t pos) {
|
|
// Get line and offset position (starts at 1:1)
|
|
auto sliced = string_view::slice(content, 0, pos);
|
|
std::size_t last_newline = sliced.rfind("\n");
|
|
|
|
if (last_newline == nonstd::string_view::npos) {
|
|
return {1, sliced.length() + 1};
|
|
}
|
|
|
|
// Count newlines
|
|
size_t count_lines = 0;
|
|
size_t search_start = 0;
|
|
while (search_start <= sliced.size()) {
|
|
search_start = sliced.find("\n", search_start) + 1;
|
|
if (search_start <= 0) {
|
|
break;
|
|
}
|
|
count_lines += 1;
|
|
}
|
|
|
|
return {count_lines + 1, sliced.length() - last_newline};
|
|
}
|
|
|
|
} // namespace inja
|
|
|
|
#endif // INCLUDE_INJA_UTILS_HPP_
|