mirror of
https://github.com/red0124/ssp.git
synced 2025-01-23 04:55:20 +01:00
Resolve clang-tidy warnings (#48)
* Resolve clang-tidy warnings, update single_header_generator.py * Update single header test, resolve additional clang-tidy warnings
This commit is contained in:
parent
457defadaa
commit
69875c238e
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,7 +1,7 @@
|
|||||||
compile_commands.json
|
compile_commands.json
|
||||||
.clang-format
|
.clang-format
|
||||||
.clang-tidy
|
.clang-tidy
|
||||||
.ccls-cache/*
|
.ccls-cache/
|
||||||
.cache/
|
.cache/
|
||||||
experiment/
|
experiment/
|
||||||
build/
|
build/
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#if !__unix__
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ss {
|
namespace ss {
|
||||||
|
|
||||||
struct none {};
|
struct none {};
|
||||||
@ -17,13 +21,13 @@ constexpr inline auto default_delimiter = ",";
|
|||||||
constexpr inline auto get_line_initial_buffer_size = 128;
|
constexpr inline auto get_line_initial_buffer_size = 128;
|
||||||
|
|
||||||
template <bool StringError>
|
template <bool StringError>
|
||||||
inline void assert_string_error_defined() {
|
void assert_string_error_defined() {
|
||||||
static_assert(StringError,
|
static_assert(StringError,
|
||||||
"'string_error' needs to be enabled to use 'error_msg'");
|
"'string_error' needs to be enabled to use 'error_msg'");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool ThrowOnError>
|
template <bool ThrowOnError>
|
||||||
inline void assert_throw_on_error_not_defined() {
|
void assert_throw_on_error_not_defined() {
|
||||||
static_assert(!ThrowOnError, "cannot handle errors manually if "
|
static_assert(!ThrowOnError, "cannot handle errors manually if "
|
||||||
"'throw_on_error' is enabled");
|
"'throw_on_error' is enabled");
|
||||||
}
|
}
|
||||||
@ -46,7 +50,7 @@ inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
|||||||
using ssize_t = intptr_t;
|
using ssize_t = intptr_t;
|
||||||
|
|
||||||
inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
||||||
char buff[get_line_initial_buffer_size];
|
std::array<char, get_line_initial_buffer_size> buff;
|
||||||
|
|
||||||
if (lineptr == nullptr || n < sizeof(buff)) {
|
if (lineptr == nullptr || n < sizeof(buff)) {
|
||||||
size_t new_n = sizeof(buff);
|
size_t new_n = sizeof(buff);
|
||||||
@ -57,9 +61,9 @@ inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
|||||||
lineptr[0] = '\0';
|
lineptr[0] = '\0';
|
||||||
|
|
||||||
size_t line_used = 0;
|
size_t line_used = 0;
|
||||||
while (std::fgets(buff, sizeof(buff), file) != nullptr) {
|
while (std::fgets(buff.data(), sizeof(buff), file) != nullptr) {
|
||||||
line_used = std::strlen(lineptr);
|
line_used = std::strlen(lineptr);
|
||||||
size_t buff_used = std::strlen(buff);
|
size_t buff_used = std::strlen(buff.data());
|
||||||
|
|
||||||
if (n <= buff_used + line_used) {
|
if (n <= buff_used + line_used) {
|
||||||
size_t new_n = n * 2;
|
size_t new_n = n * 2;
|
||||||
@ -67,7 +71,7 @@ inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
|||||||
n = new_n;
|
n = new_n;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memcpy(lineptr + line_used, buff, buff_used);
|
std::memcpy(lineptr + line_used, buff.data(), buff_used);
|
||||||
line_used += buff_used;
|
line_used += buff_used;
|
||||||
lineptr[line_used] = '\0';
|
lineptr[line_used] = '\0';
|
||||||
|
|
||||||
@ -89,7 +93,7 @@ inline ssize_t get_line_buffer(char*& lineptr, size_t& n,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lineptr == nullptr || n < get_line_initial_buffer_size) {
|
if (lineptr == nullptr || n < get_line_initial_buffer_size) {
|
||||||
auto new_lineptr = static_cast<char*>(
|
auto* new_lineptr = static_cast<char*>(
|
||||||
strict_realloc(lineptr, get_line_initial_buffer_size));
|
strict_realloc(lineptr, get_line_initial_buffer_size));
|
||||||
lineptr = new_lineptr;
|
lineptr = new_lineptr;
|
||||||
n = get_line_initial_buffer_size;
|
n = get_line_initial_buffer_size;
|
||||||
@ -122,7 +126,7 @@ inline std::tuple<ssize_t, bool> get_line(char*& buffer, size_t& buffer_size,
|
|||||||
FILE* file,
|
FILE* file,
|
||||||
const char* const csv_data_buffer,
|
const char* const csv_data_buffer,
|
||||||
size_t csv_data_size, size_t& curr_char) {
|
size_t csv_data_size, size_t& curr_char) {
|
||||||
ssize_t ssize;
|
ssize_t ssize = 0;
|
||||||
if (file) {
|
if (file) {
|
||||||
ssize = get_line_file(buffer, buffer_size, file);
|
ssize = get_line_file(buffer, buffer_size, file);
|
||||||
curr_char += ssize;
|
curr_char += ssize;
|
||||||
|
@ -224,8 +224,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string error_sufix(const string_range msg, size_t pos) const {
|
std::string error_sufix(const string_range msg, size_t pos) const {
|
||||||
|
constexpr static auto reserve_size = 32;
|
||||||
std::string error;
|
std::string error;
|
||||||
error.reserve(32);
|
error.reserve(reserve_size);
|
||||||
error.append("at column ")
|
error.append("at column ")
|
||||||
.append(std::to_string(pos + 1))
|
.append(std::to_string(pos + 1))
|
||||||
.append(": \'")
|
.append(": \'")
|
||||||
@ -391,7 +392,7 @@ private:
|
|||||||
////////////////
|
////////////////
|
||||||
|
|
||||||
bool columns_mapped() const {
|
bool columns_mapped() const {
|
||||||
return column_mappings_.size() != 0;
|
return !column_mappings_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t column_position(size_t tuple_position) const {
|
size_t column_position(size_t tuple_position) const {
|
||||||
@ -404,7 +405,7 @@ private:
|
|||||||
// assumes positions are valid and the vector is not empty
|
// assumes positions are valid and the vector is not empty
|
||||||
void set_column_mapping(std::vector<size_t> positions,
|
void set_column_mapping(std::vector<size_t> positions,
|
||||||
size_t number_of_columns) {
|
size_t number_of_columns) {
|
||||||
column_mappings_ = positions;
|
column_mappings_ = std::move(positions);
|
||||||
number_of_columns_ = number_of_columns;
|
number_of_columns_ = number_of_columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,7 +491,7 @@ private:
|
|||||||
friend class parser;
|
friend class parser;
|
||||||
|
|
||||||
std::vector<size_t> column_mappings_;
|
std::vector<size_t> column_mappings_;
|
||||||
size_t number_of_columns_;
|
size_t number_of_columns_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ss */
|
} /* namespace ss */
|
||||||
|
@ -12,10 +12,10 @@ class exception : public std::exception {
|
|||||||
std::string msg_;
|
std::string msg_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
exception(const std::string& msg): msg_{msg} {
|
exception(std::string msg): msg_{std::move(msg)} {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual char const* what() const noexcept {
|
char const* what() const noexcept override {
|
||||||
return msg_.c_str();
|
return msg_.c_str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include "type_traits.hpp"
|
#include "type_traits.hpp"
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <functional>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@ -14,6 +14,7 @@
|
|||||||
#else
|
#else
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <array>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ss {
|
namespace ss {
|
||||||
@ -45,16 +46,17 @@ std::enable_if_t<std::is_floating_point_v<T>, std::optional<T>> to_num(
|
|||||||
"Conversion to long double is disabled");
|
"Conversion to long double is disabled");
|
||||||
|
|
||||||
constexpr static auto buff_max = 64;
|
constexpr static auto buff_max = 64;
|
||||||
char short_buff[buff_max];
|
std::array<char, buff_max> short_buff;
|
||||||
|
|
||||||
size_t string_range = std::distance(begin, end);
|
size_t string_range = std::distance(begin, end);
|
||||||
std::string long_buff;
|
std::string long_buff;
|
||||||
|
|
||||||
char* buff;
|
char* buff = nullptr;
|
||||||
if (string_range > buff_max) {
|
if (string_range > buff_max) {
|
||||||
long_buff = std::string{begin, end};
|
long_buff = std::string{begin, end};
|
||||||
buff = long_buff.data();
|
buff = long_buff.data();
|
||||||
} else {
|
} else {
|
||||||
buff = short_buff;
|
buff = short_buff.data();
|
||||||
buff[string_range] = '\0';
|
buff[string_range] = '\0';
|
||||||
std::copy_n(begin, string_range, buff);
|
std::copy_n(begin, string_range, buff);
|
||||||
}
|
}
|
||||||
@ -92,6 +94,8 @@ struct numeric_wrapper {
|
|||||||
numeric_wrapper& operator=(numeric_wrapper&&) = default;
|
numeric_wrapper& operator=(numeric_wrapper&&) = default;
|
||||||
numeric_wrapper& operator=(const numeric_wrapper&) = default;
|
numeric_wrapper& operator=(const numeric_wrapper&) = default;
|
||||||
|
|
||||||
|
~numeric_wrapper() = default;
|
||||||
|
|
||||||
numeric_wrapper(T other) : value{other} {
|
numeric_wrapper(T other) : value{other} {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,10 +219,13 @@ inline bool extract(const char* begin, const char* end, bool& value) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
constexpr static auto true_size = 4;
|
||||||
|
constexpr static auto false_size = 5;
|
||||||
size_t size = end - begin;
|
size_t size = end - begin;
|
||||||
if (size == 4 && std::strncmp(begin, "true", size) == 0) {
|
if (size == true_size && std::strncmp(begin, "true", size) == 0) {
|
||||||
value = true;
|
value = true;
|
||||||
} else if (size == 5 && std::strncmp(begin, "false", size) == 0) {
|
} else if (size == false_size &&
|
||||||
|
std::strncmp(begin, "false", size) == 0) {
|
||||||
value = false;
|
value = false;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
namespace ss {
|
namespace ss {
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "extract.hpp"
|
#include "extract.hpp"
|
||||||
#include "restrictions.hpp"
|
#include "restrictions.hpp"
|
||||||
#include <cerrno>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@ -33,9 +32,8 @@ class parser {
|
|||||||
constexpr static bool ignore_empty = setup<Options...>::ignore_empty;
|
constexpr static bool ignore_empty = setup<Options...>::ignore_empty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
parser(const std::string& file_name,
|
parser(std::string file_name, std::string delim = ss::default_delimiter)
|
||||||
const std::string& delim = ss::default_delimiter)
|
: file_name_{std::move(file_name)}, reader_{file_name_, delim} {
|
||||||
: file_name_{file_name}, reader_{file_name_, delim} {
|
|
||||||
if (reader_.file_) {
|
if (reader_.file_) {
|
||||||
read_line();
|
read_line();
|
||||||
if constexpr (ignore_header) {
|
if constexpr (ignore_header) {
|
||||||
@ -68,6 +66,7 @@ public:
|
|||||||
|
|
||||||
parser(parser&& other) = default;
|
parser(parser&& other) = default;
|
||||||
parser& operator=(parser&& other) = default;
|
parser& operator=(parser&& other) = default;
|
||||||
|
~parser() = default;
|
||||||
|
|
||||||
parser() = delete;
|
parser() = delete;
|
||||||
parser(const parser& other) = delete;
|
parser(const parser& other) = delete;
|
||||||
@ -237,6 +236,10 @@ public:
|
|||||||
|
|
||||||
iterator(const iterator& other) = default;
|
iterator(const iterator& other) = default;
|
||||||
iterator(iterator&& other) = default;
|
iterator(iterator&& other) = default;
|
||||||
|
~iterator() = default;
|
||||||
|
|
||||||
|
iterator& operator=(const iterator& other) = delete;
|
||||||
|
iterator& operator=(iterator&& other) = delete;
|
||||||
|
|
||||||
value& operator*() {
|
value& operator*() {
|
||||||
return value_;
|
return value_;
|
||||||
@ -261,8 +264,10 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator& operator++(int) {
|
iterator operator++(int) {
|
||||||
return ++*this;
|
auto result = *this;
|
||||||
|
++*this;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator==(const iterator& lhs, const iterator& rhs) {
|
friend bool operator==(const iterator& lhs, const iterator& rhs) {
|
||||||
@ -326,7 +331,7 @@ public:
|
|||||||
Fun&& fun = none{}) {
|
Fun&& fun = none{}) {
|
||||||
using Value = no_void_validator_tup_t<Us...>;
|
using Value = no_void_validator_tup_t<Us...>;
|
||||||
std::optional<Value> value;
|
std::optional<Value> value;
|
||||||
try_convert_and_invoke<Value, Us...>(value, fun);
|
try_convert_and_invoke<Value, Us...>(value, std::forward<Fun>(fun));
|
||||||
return composite_with(std::move(value));
|
return composite_with(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +340,7 @@ public:
|
|||||||
template <typename U, typename... Us, typename Fun = none>
|
template <typename U, typename... Us, typename Fun = none>
|
||||||
composite<Ts..., std::optional<U>> or_object(Fun&& fun = none{}) {
|
composite<Ts..., std::optional<U>> or_object(Fun&& fun = none{}) {
|
||||||
std::optional<U> value;
|
std::optional<U> value;
|
||||||
try_convert_and_invoke<U, Us...>(value, fun);
|
try_convert_and_invoke<U, Us...>(value, std::forward<Fun>(fun));
|
||||||
return composite_with(std::move(value));
|
return composite_with(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,7 +448,8 @@ private:
|
|||||||
using Ret = decltype(try_invoke_impl(arg, std::forward<Fun>(fun)));
|
using Ret = decltype(try_invoke_impl(arg, std::forward<Fun>(fun)));
|
||||||
constexpr bool returns_void = std::is_same_v<Ret, void>;
|
constexpr bool returns_void = std::is_same_v<Ret, void>;
|
||||||
if constexpr (!returns_void) {
|
if constexpr (!returns_void) {
|
||||||
if (!try_invoke_impl(arg, std::forward<Fun>(fun))) {
|
if (!try_invoke_impl(std::forward<Arg>(arg),
|
||||||
|
std::forward<Fun>(fun))) {
|
||||||
handle_error_failed_check();
|
handle_error_failed_check();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -478,7 +484,7 @@ private:
|
|||||||
if (valid()) {
|
if (valid()) {
|
||||||
try_invoke(*value, std::forward<Fun>(fun));
|
try_invoke(*value, std::forward<Fun>(fun));
|
||||||
}
|
}
|
||||||
return {valid() ? std::move(value) : std::nullopt, *this};
|
return {valid() ? std::forward<T>(value) : std::nullopt, *this};
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
@ -674,17 +680,18 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct reader {
|
struct reader {
|
||||||
reader(const std::string& file_name_, const std::string& delim)
|
reader(const std::string& file_name_, std::string delim)
|
||||||
: delim_{delim}, file_{std::fopen(file_name_.c_str(), "rb")} {
|
: delim_{std::move(delim)},
|
||||||
|
file_{std::fopen(file_name_.c_str(), "rb")} {
|
||||||
}
|
}
|
||||||
|
|
||||||
reader(const char* const buffer, size_t csv_data_size,
|
reader(const char* const buffer, size_t csv_data_size,
|
||||||
const std::string& delim)
|
std::string delim)
|
||||||
: delim_{delim}, csv_data_buffer_{buffer},
|
: delim_{std::move(delim)}, csv_data_buffer_{buffer},
|
||||||
csv_data_size_{csv_data_size} {
|
csv_data_size_{csv_data_size} {
|
||||||
}
|
}
|
||||||
|
|
||||||
reader(reader&& other)
|
reader(reader&& other) noexcept
|
||||||
: buffer_{other.buffer_},
|
: buffer_{other.buffer_},
|
||||||
next_line_buffer_{other.next_line_buffer_},
|
next_line_buffer_{other.next_line_buffer_},
|
||||||
helper_buffer_{other.helper_buffer_},
|
helper_buffer_{other.helper_buffer_},
|
||||||
@ -705,7 +712,7 @@ private:
|
|||||||
other.file_ = nullptr;
|
other.file_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
reader& operator=(reader&& other) {
|
reader& operator=(reader&& other) noexcept {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
buffer_ = other.buffer_;
|
buffer_ = other.buffer_;
|
||||||
next_line_buffer_ = other.next_line_buffer_;
|
next_line_buffer_ = other.next_line_buffer_;
|
||||||
@ -853,7 +860,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool escaped_eol(size_t size) {
|
bool escaped_eol(size_t size) {
|
||||||
const char* curr;
|
const char* curr = nullptr;
|
||||||
for (curr = next_line_buffer_ + size - 1;
|
for (curr = next_line_buffer_ + size - 1;
|
||||||
curr >= next_line_buffer_ &&
|
curr >= next_line_buffer_ &&
|
||||||
setup<Options...>::escape::match(*curr);
|
setup<Options...>::escape::match(*curr);
|
||||||
@ -899,7 +906,7 @@ private:
|
|||||||
size_t& buffer_size, const char* const second,
|
size_t& buffer_size, const char* const second,
|
||||||
size_t second_size) {
|
size_t second_size) {
|
||||||
buffer_size = first_size + second_size + 3;
|
buffer_size = first_size + second_size + 3;
|
||||||
auto new_first = static_cast<char*>(
|
auto* new_first = static_cast<char*>(
|
||||||
strict_realloc(static_cast<void*>(first), buffer_size));
|
strict_realloc(static_cast<void*>(first), buffer_size));
|
||||||
|
|
||||||
first = new_first;
|
first = new_first;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "setup.hpp"
|
#include "setup.hpp"
|
||||||
#include "type_traits.hpp"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -321,8 +320,9 @@ private:
|
|||||||
|
|
||||||
trim_left_if_enabled(begin_);
|
trim_left_if_enabled(begin_);
|
||||||
|
|
||||||
for (done_ = false; !done_; read(delim))
|
for (done_ = false; !done_;) {
|
||||||
;
|
read(delim);
|
||||||
|
}
|
||||||
|
|
||||||
return split_data_;
|
return split_data_;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,11 @@ struct left_of_impl;
|
|||||||
|
|
||||||
template <size_t N, typename T, typename... Ts>
|
template <size_t N, typename T, typename... Ts>
|
||||||
struct left_of_impl {
|
struct left_of_impl {
|
||||||
static_assert(N < 128, "recursion limit reached");
|
private:
|
||||||
|
constexpr static auto recursion_limit = 128;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static_assert(N < recursion_limit, "recursion limit reached");
|
||||||
static_assert(N != 0, "cannot take the whole tuple");
|
static_assert(N != 0, "cannot take the whole tuple");
|
||||||
using type = tup_cat_t<T, typename left_of_impl<N - 1, Ts...>::type>;
|
using type = tup_cat_t<T, typename left_of_impl<N - 1, Ts...>::type>;
|
||||||
};
|
};
|
||||||
|
@ -14,14 +14,21 @@ headers = ['type_traits.hpp',
|
|||||||
|
|
||||||
combined_file = []
|
combined_file = []
|
||||||
includes = []
|
includes = []
|
||||||
|
in_pp_block = False
|
||||||
|
|
||||||
for header in headers:
|
for header in headers:
|
||||||
with open(headers_dir + header) as f:
|
with open(headers_dir + header) as f:
|
||||||
for line in f.read().splitlines():
|
for line in f.read().splitlines():
|
||||||
|
if '#if ' in line:
|
||||||
|
in_pp_block = True
|
||||||
|
|
||||||
|
if '#endif' in line:
|
||||||
|
in_pp_block = False
|
||||||
|
|
||||||
if '#include "' in line or '#include <fast_float' in line:
|
if '#include "' in line or '#include <fast_float' in line:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if '#include <' in line:
|
if '#include <' in line and not in_pp_block:
|
||||||
includes.append(line)
|
includes.append(line)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
105
ssp.hpp
105
ssp.hpp
@ -49,7 +49,11 @@ struct left_of_impl;
|
|||||||
|
|
||||||
template <size_t N, typename T, typename... Ts>
|
template <size_t N, typename T, typename... Ts>
|
||||||
struct left_of_impl {
|
struct left_of_impl {
|
||||||
static_assert(N < 128, "recursion limit reached");
|
private:
|
||||||
|
constexpr static auto recursion_limit = 128;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static_assert(N < recursion_limit, "recursion limit reached");
|
||||||
static_assert(N != 0, "cannot take the whole tuple");
|
static_assert(N != 0, "cannot take the whole tuple");
|
||||||
using type = tup_cat_t<T, typename left_of_impl<N - 1, Ts...>::type>;
|
using type = tup_cat_t<T, typename left_of_impl<N - 1, Ts...>::type>;
|
||||||
};
|
};
|
||||||
@ -405,10 +409,10 @@ class exception : public std::exception {
|
|||||||
std::string msg_;
|
std::string msg_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
exception(const std::string& msg): msg_{msg} {
|
exception(std::string msg): msg_{std::move(msg)} {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual char const* what() const noexcept {
|
char const* what() const noexcept override {
|
||||||
return msg_.c_str();
|
return msg_.c_str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -617,6 +621,11 @@ struct ne {
|
|||||||
|
|
||||||
} /* namespace ss */
|
} /* namespace ss */
|
||||||
|
|
||||||
|
#if !__unix__
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ss {
|
namespace ss {
|
||||||
|
|
||||||
struct none {};
|
struct none {};
|
||||||
@ -628,13 +637,13 @@ constexpr inline auto default_delimiter = ",";
|
|||||||
constexpr inline auto get_line_initial_buffer_size = 128;
|
constexpr inline auto get_line_initial_buffer_size = 128;
|
||||||
|
|
||||||
template <bool StringError>
|
template <bool StringError>
|
||||||
inline void assert_string_error_defined() {
|
void assert_string_error_defined() {
|
||||||
static_assert(StringError,
|
static_assert(StringError,
|
||||||
"'string_error' needs to be enabled to use 'error_msg'");
|
"'string_error' needs to be enabled to use 'error_msg'");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool ThrowOnError>
|
template <bool ThrowOnError>
|
||||||
inline void assert_throw_on_error_not_defined() {
|
void assert_throw_on_error_not_defined() {
|
||||||
static_assert(!ThrowOnError, "cannot handle errors manually if "
|
static_assert(!ThrowOnError, "cannot handle errors manually if "
|
||||||
"'throw_on_error' is enabled");
|
"'throw_on_error' is enabled");
|
||||||
}
|
}
|
||||||
@ -657,7 +666,7 @@ inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
|||||||
using ssize_t = intptr_t;
|
using ssize_t = intptr_t;
|
||||||
|
|
||||||
inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
||||||
char buff[get_line_initial_buffer_size];
|
std::array<char, get_line_initial_buffer_size> buff;
|
||||||
|
|
||||||
if (lineptr == nullptr || n < sizeof(buff)) {
|
if (lineptr == nullptr || n < sizeof(buff)) {
|
||||||
size_t new_n = sizeof(buff);
|
size_t new_n = sizeof(buff);
|
||||||
@ -668,9 +677,9 @@ inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
|||||||
lineptr[0] = '\0';
|
lineptr[0] = '\0';
|
||||||
|
|
||||||
size_t line_used = 0;
|
size_t line_used = 0;
|
||||||
while (std::fgets(buff, sizeof(buff), file) != nullptr) {
|
while (std::fgets(buff.data(), sizeof(buff), file) != nullptr) {
|
||||||
line_used = std::strlen(lineptr);
|
line_used = std::strlen(lineptr);
|
||||||
size_t buff_used = std::strlen(buff);
|
size_t buff_used = std::strlen(buff.data());
|
||||||
|
|
||||||
if (n <= buff_used + line_used) {
|
if (n <= buff_used + line_used) {
|
||||||
size_t new_n = n * 2;
|
size_t new_n = n * 2;
|
||||||
@ -678,7 +687,7 @@ inline ssize_t get_line_file(char*& lineptr, size_t& n, FILE* file) {
|
|||||||
n = new_n;
|
n = new_n;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memcpy(lineptr + line_used, buff, buff_used);
|
std::memcpy(lineptr + line_used, buff.data(), buff_used);
|
||||||
line_used += buff_used;
|
line_used += buff_used;
|
||||||
lineptr[line_used] = '\0';
|
lineptr[line_used] = '\0';
|
||||||
|
|
||||||
@ -700,7 +709,7 @@ inline ssize_t get_line_buffer(char*& lineptr, size_t& n,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lineptr == nullptr || n < get_line_initial_buffer_size) {
|
if (lineptr == nullptr || n < get_line_initial_buffer_size) {
|
||||||
auto new_lineptr = static_cast<char*>(
|
auto* new_lineptr = static_cast<char*>(
|
||||||
strict_realloc(lineptr, get_line_initial_buffer_size));
|
strict_realloc(lineptr, get_line_initial_buffer_size));
|
||||||
lineptr = new_lineptr;
|
lineptr = new_lineptr;
|
||||||
n = get_line_initial_buffer_size;
|
n = get_line_initial_buffer_size;
|
||||||
@ -733,7 +742,7 @@ inline std::tuple<ssize_t, bool> get_line(char*& buffer, size_t& buffer_size,
|
|||||||
FILE* file,
|
FILE* file,
|
||||||
const char* const csv_data_buffer,
|
const char* const csv_data_buffer,
|
||||||
size_t csv_data_size, size_t& curr_char) {
|
size_t csv_data_size, size_t& curr_char) {
|
||||||
ssize_t ssize;
|
ssize_t ssize = 0;
|
||||||
if (file) {
|
if (file) {
|
||||||
ssize = get_line_file(buffer, buffer_size, file);
|
ssize = get_line_file(buffer, buffer_size, file);
|
||||||
curr_char += ssize;
|
curr_char += ssize;
|
||||||
@ -1359,8 +1368,9 @@ private:
|
|||||||
|
|
||||||
trim_left_if_enabled(begin_);
|
trim_left_if_enabled(begin_);
|
||||||
|
|
||||||
for (done_ = false; !done_; read(delim))
|
for (done_ = false; !done_;) {
|
||||||
;
|
read(delim);
|
||||||
|
}
|
||||||
|
|
||||||
return split_data_;
|
return split_data_;
|
||||||
}
|
}
|
||||||
@ -1552,16 +1562,17 @@ std::enable_if_t<std::is_floating_point_v<T>, std::optional<T>> to_num(
|
|||||||
"Conversion to long double is disabled");
|
"Conversion to long double is disabled");
|
||||||
|
|
||||||
constexpr static auto buff_max = 64;
|
constexpr static auto buff_max = 64;
|
||||||
char short_buff[buff_max];
|
std::array<char, buff_max> short_buff;
|
||||||
|
|
||||||
size_t string_range = std::distance(begin, end);
|
size_t string_range = std::distance(begin, end);
|
||||||
std::string long_buff;
|
std::string long_buff;
|
||||||
|
|
||||||
char* buff;
|
char* buff = nullptr;
|
||||||
if (string_range > buff_max) {
|
if (string_range > buff_max) {
|
||||||
long_buff = std::string{begin, end};
|
long_buff = std::string{begin, end};
|
||||||
buff = long_buff.data();
|
buff = long_buff.data();
|
||||||
} else {
|
} else {
|
||||||
buff = short_buff;
|
buff = short_buff.data();
|
||||||
buff[string_range] = '\0';
|
buff[string_range] = '\0';
|
||||||
std::copy_n(begin, string_range, buff);
|
std::copy_n(begin, string_range, buff);
|
||||||
}
|
}
|
||||||
@ -1599,6 +1610,8 @@ struct numeric_wrapper {
|
|||||||
numeric_wrapper& operator=(numeric_wrapper&&) = default;
|
numeric_wrapper& operator=(numeric_wrapper&&) = default;
|
||||||
numeric_wrapper& operator=(const numeric_wrapper&) = default;
|
numeric_wrapper& operator=(const numeric_wrapper&) = default;
|
||||||
|
|
||||||
|
~numeric_wrapper() = default;
|
||||||
|
|
||||||
numeric_wrapper(T other) : value{other} {
|
numeric_wrapper(T other) : value{other} {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1649,7 +1662,7 @@ template <typename T>
|
|||||||
struct unsupported_type {
|
struct unsupported_type {
|
||||||
constexpr static bool value = false;
|
constexpr static bool value = false;
|
||||||
};
|
};
|
||||||
} /* namespace error */
|
} /* namespace errors */
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::enable_if_t<!std::is_integral_v<T> && !std::is_floating_point_v<T> &&
|
std::enable_if_t<!std::is_integral_v<T> && !std::is_floating_point_v<T> &&
|
||||||
@ -1722,10 +1735,13 @@ inline bool extract(const char* begin, const char* end, bool& value) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
constexpr static auto true_size = 4;
|
||||||
|
constexpr static auto false_size = 5;
|
||||||
size_t size = end - begin;
|
size_t size = end - begin;
|
||||||
if (size == 4 && std::strncmp(begin, "true", size) == 0) {
|
if (size == true_size && std::strncmp(begin, "true", size) == 0) {
|
||||||
value = true;
|
value = true;
|
||||||
} else if (size == 5 && std::strncmp(begin, "false", size) == 0) {
|
} else if (size == false_size &&
|
||||||
|
std::strncmp(begin, "false", size) == 0) {
|
||||||
value = false;
|
value = false;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -1971,8 +1987,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string error_sufix(const string_range msg, size_t pos) const {
|
std::string error_sufix(const string_range msg, size_t pos) const {
|
||||||
|
constexpr static auto reserve_size = 32;
|
||||||
std::string error;
|
std::string error;
|
||||||
error.reserve(32);
|
error.reserve(reserve_size);
|
||||||
error.append("at column ")
|
error.append("at column ")
|
||||||
.append(std::to_string(pos + 1))
|
.append(std::to_string(pos + 1))
|
||||||
.append(": \'")
|
.append(": \'")
|
||||||
@ -2138,7 +2155,7 @@ private:
|
|||||||
////////////////
|
////////////////
|
||||||
|
|
||||||
bool columns_mapped() const {
|
bool columns_mapped() const {
|
||||||
return column_mappings_.size() != 0;
|
return !column_mappings_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t column_position(size_t tuple_position) const {
|
size_t column_position(size_t tuple_position) const {
|
||||||
@ -2151,7 +2168,7 @@ private:
|
|||||||
// assumes positions are valid and the vector is not empty
|
// assumes positions are valid and the vector is not empty
|
||||||
void set_column_mapping(std::vector<size_t> positions,
|
void set_column_mapping(std::vector<size_t> positions,
|
||||||
size_t number_of_columns) {
|
size_t number_of_columns) {
|
||||||
column_mappings_ = positions;
|
column_mappings_ = std::move(positions);
|
||||||
number_of_columns_ = number_of_columns;
|
number_of_columns_ = number_of_columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2237,7 +2254,7 @@ private:
|
|||||||
friend class parser;
|
friend class parser;
|
||||||
|
|
||||||
std::vector<size_t> column_mappings_;
|
std::vector<size_t> column_mappings_;
|
||||||
size_t number_of_columns_;
|
size_t number_of_columns_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ss */
|
} /* namespace ss */
|
||||||
@ -2264,9 +2281,8 @@ class parser {
|
|||||||
constexpr static bool ignore_empty = setup<Options...>::ignore_empty;
|
constexpr static bool ignore_empty = setup<Options...>::ignore_empty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
parser(const std::string& file_name,
|
parser(std::string file_name, std::string delim = ss::default_delimiter)
|
||||||
const std::string& delim = ss::default_delimiter)
|
: file_name_{std::move(file_name)}, reader_{file_name_, delim} {
|
||||||
: file_name_{file_name}, reader_{file_name_, delim} {
|
|
||||||
if (reader_.file_) {
|
if (reader_.file_) {
|
||||||
read_line();
|
read_line();
|
||||||
if constexpr (ignore_header) {
|
if constexpr (ignore_header) {
|
||||||
@ -2299,6 +2315,7 @@ public:
|
|||||||
|
|
||||||
parser(parser&& other) = default;
|
parser(parser&& other) = default;
|
||||||
parser& operator=(parser&& other) = default;
|
parser& operator=(parser&& other) = default;
|
||||||
|
~parser() = default;
|
||||||
|
|
||||||
parser() = delete;
|
parser() = delete;
|
||||||
parser(const parser& other) = delete;
|
parser(const parser& other) = delete;
|
||||||
@ -2468,6 +2485,10 @@ public:
|
|||||||
|
|
||||||
iterator(const iterator& other) = default;
|
iterator(const iterator& other) = default;
|
||||||
iterator(iterator&& other) = default;
|
iterator(iterator&& other) = default;
|
||||||
|
~iterator() = default;
|
||||||
|
|
||||||
|
iterator& operator=(const iterator& other) = delete;
|
||||||
|
iterator& operator=(iterator&& other) = delete;
|
||||||
|
|
||||||
value& operator*() {
|
value& operator*() {
|
||||||
return value_;
|
return value_;
|
||||||
@ -2492,8 +2513,10 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator& operator++(int) {
|
iterator operator++(int) {
|
||||||
return ++*this;
|
auto result = *this;
|
||||||
|
++*this;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator==(const iterator& lhs, const iterator& rhs) {
|
friend bool operator==(const iterator& lhs, const iterator& rhs) {
|
||||||
@ -2557,7 +2580,7 @@ public:
|
|||||||
Fun&& fun = none{}) {
|
Fun&& fun = none{}) {
|
||||||
using Value = no_void_validator_tup_t<Us...>;
|
using Value = no_void_validator_tup_t<Us...>;
|
||||||
std::optional<Value> value;
|
std::optional<Value> value;
|
||||||
try_convert_and_invoke<Value, Us...>(value, fun);
|
try_convert_and_invoke<Value, Us...>(value, std::forward<Fun>(fun));
|
||||||
return composite_with(std::move(value));
|
return composite_with(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2566,7 +2589,7 @@ public:
|
|||||||
template <typename U, typename... Us, typename Fun = none>
|
template <typename U, typename... Us, typename Fun = none>
|
||||||
composite<Ts..., std::optional<U>> or_object(Fun&& fun = none{}) {
|
composite<Ts..., std::optional<U>> or_object(Fun&& fun = none{}) {
|
||||||
std::optional<U> value;
|
std::optional<U> value;
|
||||||
try_convert_and_invoke<U, Us...>(value, fun);
|
try_convert_and_invoke<U, Us...>(value, std::forward<Fun>(fun));
|
||||||
return composite_with(std::move(value));
|
return composite_with(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2674,7 +2697,8 @@ private:
|
|||||||
using Ret = decltype(try_invoke_impl(arg, std::forward<Fun>(fun)));
|
using Ret = decltype(try_invoke_impl(arg, std::forward<Fun>(fun)));
|
||||||
constexpr bool returns_void = std::is_same_v<Ret, void>;
|
constexpr bool returns_void = std::is_same_v<Ret, void>;
|
||||||
if constexpr (!returns_void) {
|
if constexpr (!returns_void) {
|
||||||
if (!try_invoke_impl(arg, std::forward<Fun>(fun))) {
|
if (!try_invoke_impl(std::forward<Arg>(arg),
|
||||||
|
std::forward<Fun>(fun))) {
|
||||||
handle_error_failed_check();
|
handle_error_failed_check();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2709,7 +2733,7 @@ private:
|
|||||||
if (valid()) {
|
if (valid()) {
|
||||||
try_invoke(*value, std::forward<Fun>(fun));
|
try_invoke(*value, std::forward<Fun>(fun));
|
||||||
}
|
}
|
||||||
return {valid() ? std::move(value) : std::nullopt, *this};
|
return {valid() ? std::forward<T>(value) : std::nullopt, *this};
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
@ -2905,17 +2929,18 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct reader {
|
struct reader {
|
||||||
reader(const std::string& file_name_, const std::string& delim)
|
reader(const std::string& file_name_, std::string delim)
|
||||||
: delim_{delim}, file_{std::fopen(file_name_.c_str(), "rb")} {
|
: delim_{std::move(delim)},
|
||||||
|
file_{std::fopen(file_name_.c_str(), "rb")} {
|
||||||
}
|
}
|
||||||
|
|
||||||
reader(const char* const buffer, size_t csv_data_size,
|
reader(const char* const buffer, size_t csv_data_size,
|
||||||
const std::string& delim)
|
std::string delim)
|
||||||
: delim_{delim}, csv_data_buffer_{buffer},
|
: delim_{std::move(delim)}, csv_data_buffer_{buffer},
|
||||||
csv_data_size_{csv_data_size} {
|
csv_data_size_{csv_data_size} {
|
||||||
}
|
}
|
||||||
|
|
||||||
reader(reader&& other)
|
reader(reader&& other) noexcept
|
||||||
: buffer_{other.buffer_},
|
: buffer_{other.buffer_},
|
||||||
next_line_buffer_{other.next_line_buffer_},
|
next_line_buffer_{other.next_line_buffer_},
|
||||||
helper_buffer_{other.helper_buffer_},
|
helper_buffer_{other.helper_buffer_},
|
||||||
@ -2936,7 +2961,7 @@ private:
|
|||||||
other.file_ = nullptr;
|
other.file_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
reader& operator=(reader&& other) {
|
reader& operator=(reader&& other) noexcept {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
buffer_ = other.buffer_;
|
buffer_ = other.buffer_;
|
||||||
next_line_buffer_ = other.next_line_buffer_;
|
next_line_buffer_ = other.next_line_buffer_;
|
||||||
@ -3084,7 +3109,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool escaped_eol(size_t size) {
|
bool escaped_eol(size_t size) {
|
||||||
const char* curr;
|
const char* curr = nullptr;
|
||||||
for (curr = next_line_buffer_ + size - 1;
|
for (curr = next_line_buffer_ + size - 1;
|
||||||
curr >= next_line_buffer_ &&
|
curr >= next_line_buffer_ &&
|
||||||
setup<Options...>::escape::match(*curr);
|
setup<Options...>::escape::match(*curr);
|
||||||
@ -3130,7 +3155,7 @@ private:
|
|||||||
size_t& buffer_size, const char* const second,
|
size_t& buffer_size, const char* const second,
|
||||||
size_t second_size) {
|
size_t second_size) {
|
||||||
buffer_size = first_size + second_size + 3;
|
buffer_size = first_size + second_size + 3;
|
||||||
auto new_first = static_cast<char*>(
|
auto* new_first = static_cast<char*>(
|
||||||
strict_realloc(static_cast<void*>(first), buffer_size));
|
strict_realloc(static_cast<void*>(first), buffer_size));
|
||||||
|
|
||||||
first = new_first;
|
first = new_first;
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
set -x
|
set -x
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
python3 script/single_header_generator.py > ssp.cpp
|
TMP_HDR=test_single_header.hpp
|
||||||
|
TMP_SRC=test_single_header.cpp
|
||||||
|
TMP_BIN=test_single_header
|
||||||
|
|
||||||
echo 'int main(){ ss::parser p{""}; p.get_next<int, float>(); return 0; }' \
|
python3 script/single_header_generator.py > ${TMP_HDR}
|
||||||
>> ssp.cpp
|
cat ${TMP_HDR} test/test_single_header_main.txt > ${TMP_SRC}
|
||||||
|
|
||||||
g++ -std=c++17 ssp.cpp -o ssp.bin -Wall -Wextra
|
g++ -std=c++17 ${TMP_SRC} -o ${TMP_BIN} -Wall -Wextra
|
||||||
./ssp.bin
|
./${TMP_BIN}
|
||||||
|
|
||||||
rm ssp.cpp ssp.bin
|
rm ${TMP_HDR} ${TMP_SRC} ${TMP_BIN}
|
||||||
|
12
test/test_single_header_main.txt
Normal file
12
test/test_single_header_main.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
int main() {
|
||||||
|
using quote = ss::quote<'"'>;
|
||||||
|
using escape = ss::escape<'\\'>;
|
||||||
|
using trim = ss::trim<' '>;
|
||||||
|
|
||||||
|
std::string data = "1,string,2.34,c";
|
||||||
|
|
||||||
|
ss::parser<quote, escape, trim, ss::multiline> p{data.c_str(), data.size()};
|
||||||
|
auto tup = p.get_next<int, std::string, float, std::optional<char>>();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user