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
|
||||
.clang-format
|
||||
.clang-tidy
|
||||
.ccls-cache/*
|
||||
.ccls-cache/
|
||||
.cache/
|
||||
experiment/
|
||||
build/
|
||||
|
@ -1,11 +1,15 @@
|
||||
#pragma once
|
||||
#include <cerrno>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#if !__unix__
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#endif
|
||||
|
||||
namespace ss {
|
||||
|
||||
struct none {};
|
||||
@ -17,13 +21,13 @@ constexpr inline auto default_delimiter = ",";
|
||||
constexpr inline auto get_line_initial_buffer_size = 128;
|
||||
|
||||
template <bool StringError>
|
||||
inline void assert_string_error_defined() {
|
||||
void assert_string_error_defined() {
|
||||
static_assert(StringError,
|
||||
"'string_error' needs to be enabled to use 'error_msg'");
|
||||
}
|
||||
|
||||
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 "
|
||||
"'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;
|
||||
|
||||
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)) {
|
||||
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';
|
||||
|
||||
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);
|
||||
size_t buff_used = std::strlen(buff);
|
||||
size_t buff_used = std::strlen(buff.data());
|
||||
|
||||
if (n <= buff_used + line_used) {
|
||||
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;
|
||||
}
|
||||
|
||||
std::memcpy(lineptr + line_used, buff, buff_used);
|
||||
std::memcpy(lineptr + line_used, buff.data(), buff_used);
|
||||
line_used += buff_used;
|
||||
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) {
|
||||
auto new_lineptr = static_cast<char*>(
|
||||
auto* new_lineptr = static_cast<char*>(
|
||||
strict_realloc(lineptr, get_line_initial_buffer_size));
|
||||
lineptr = new_lineptr;
|
||||
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,
|
||||
const char* const csv_data_buffer,
|
||||
size_t csv_data_size, size_t& curr_char) {
|
||||
ssize_t ssize;
|
||||
ssize_t ssize = 0;
|
||||
if (file) {
|
||||
ssize = get_line_file(buffer, buffer_size, file);
|
||||
curr_char += ssize;
|
||||
|
@ -224,8 +224,9 @@ private:
|
||||
}
|
||||
|
||||
std::string error_sufix(const string_range msg, size_t pos) const {
|
||||
constexpr static auto reserve_size = 32;
|
||||
std::string error;
|
||||
error.reserve(32);
|
||||
error.reserve(reserve_size);
|
||||
error.append("at column ")
|
||||
.append(std::to_string(pos + 1))
|
||||
.append(": \'")
|
||||
@ -391,7 +392,7 @@ private:
|
||||
////////////////
|
||||
|
||||
bool columns_mapped() const {
|
||||
return column_mappings_.size() != 0;
|
||||
return !column_mappings_.empty();
|
||||
}
|
||||
|
||||
size_t column_position(size_t tuple_position) const {
|
||||
@ -404,7 +405,7 @@ private:
|
||||
// assumes positions are valid and the vector is not empty
|
||||
void set_column_mapping(std::vector<size_t> positions,
|
||||
size_t number_of_columns) {
|
||||
column_mappings_ = positions;
|
||||
column_mappings_ = std::move(positions);
|
||||
number_of_columns_ = number_of_columns;
|
||||
}
|
||||
|
||||
@ -490,7 +491,7 @@ private:
|
||||
friend class parser;
|
||||
|
||||
std::vector<size_t> column_mappings_;
|
||||
size_t number_of_columns_;
|
||||
size_t number_of_columns_{0};
|
||||
};
|
||||
|
||||
} /* namespace ss */
|
||||
|
@ -12,10 +12,10 @@ class exception : public std::exception {
|
||||
std::string msg_;
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
#include "type_traits.hpp"
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@ -14,6 +14,7 @@
|
||||
#else
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <array>
|
||||
#endif
|
||||
|
||||
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");
|
||||
|
||||
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);
|
||||
std::string long_buff;
|
||||
|
||||
char* buff;
|
||||
char* buff = nullptr;
|
||||
if (string_range > buff_max) {
|
||||
long_buff = std::string{begin, end};
|
||||
buff = long_buff.data();
|
||||
} else {
|
||||
buff = short_buff;
|
||||
buff = short_buff.data();
|
||||
buff[string_range] = '\0';
|
||||
std::copy_n(begin, string_range, buff);
|
||||
}
|
||||
@ -92,6 +94,8 @@ struct numeric_wrapper {
|
||||
numeric_wrapper& operator=(numeric_wrapper&&) = default;
|
||||
numeric_wrapper& operator=(const numeric_wrapper&) = default;
|
||||
|
||||
~numeric_wrapper() = default;
|
||||
|
||||
numeric_wrapper(T other) : value{other} {
|
||||
}
|
||||
|
||||
@ -215,10 +219,13 @@ inline bool extract(const char* begin, const char* end, bool& value) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
constexpr static auto true_size = 4;
|
||||
constexpr static auto false_size = 5;
|
||||
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;
|
||||
} else if (size == 5 && std::strncmp(begin, "false", size) == 0) {
|
||||
} else if (size == false_size &&
|
||||
std::strncmp(begin, "false", size) == 0) {
|
||||
value = false;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
namespace ss {
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "exception.hpp"
|
||||
#include "extract.hpp"
|
||||
#include "restrictions.hpp"
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
@ -33,9 +32,8 @@ class parser {
|
||||
constexpr static bool ignore_empty = setup<Options...>::ignore_empty;
|
||||
|
||||
public:
|
||||
parser(const std::string& file_name,
|
||||
const std::string& delim = ss::default_delimiter)
|
||||
: file_name_{file_name}, reader_{file_name_, delim} {
|
||||
parser(std::string file_name, std::string delim = ss::default_delimiter)
|
||||
: file_name_{std::move(file_name)}, reader_{file_name_, delim} {
|
||||
if (reader_.file_) {
|
||||
read_line();
|
||||
if constexpr (ignore_header) {
|
||||
@ -68,6 +66,7 @@ public:
|
||||
|
||||
parser(parser&& other) = default;
|
||||
parser& operator=(parser&& other) = default;
|
||||
~parser() = default;
|
||||
|
||||
parser() = delete;
|
||||
parser(const parser& other) = delete;
|
||||
@ -237,6 +236,10 @@ public:
|
||||
|
||||
iterator(const iterator& other) = default;
|
||||
iterator(iterator&& other) = default;
|
||||
~iterator() = default;
|
||||
|
||||
iterator& operator=(const iterator& other) = delete;
|
||||
iterator& operator=(iterator&& other) = delete;
|
||||
|
||||
value& operator*() {
|
||||
return value_;
|
||||
@ -261,8 +264,10 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator& operator++(int) {
|
||||
return ++*this;
|
||||
iterator operator++(int) {
|
||||
auto result = *this;
|
||||
++*this;
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator==(const iterator& lhs, const iterator& rhs) {
|
||||
@ -326,7 +331,7 @@ public:
|
||||
Fun&& fun = none{}) {
|
||||
using Value = no_void_validator_tup_t<Us...>;
|
||||
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));
|
||||
}
|
||||
|
||||
@ -335,7 +340,7 @@ public:
|
||||
template <typename U, typename... Us, typename Fun = none>
|
||||
composite<Ts..., std::optional<U>> or_object(Fun&& fun = none{}) {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -443,7 +448,8 @@ private:
|
||||
using Ret = decltype(try_invoke_impl(arg, std::forward<Fun>(fun)));
|
||||
constexpr bool returns_void = std::is_same_v<Ret, 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();
|
||||
}
|
||||
} else {
|
||||
@ -478,7 +484,7 @@ private:
|
||||
if (valid()) {
|
||||
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 {
|
||||
reader(const std::string& file_name_, const std::string& delim)
|
||||
: delim_{delim}, file_{std::fopen(file_name_.c_str(), "rb")} {
|
||||
reader(const std::string& file_name_, std::string delim)
|
||||
: delim_{std::move(delim)},
|
||||
file_{std::fopen(file_name_.c_str(), "rb")} {
|
||||
}
|
||||
|
||||
reader(const char* const buffer, size_t csv_data_size,
|
||||
const std::string& delim)
|
||||
: delim_{delim}, csv_data_buffer_{buffer},
|
||||
std::string delim)
|
||||
: delim_{std::move(delim)}, csv_data_buffer_{buffer},
|
||||
csv_data_size_{csv_data_size} {
|
||||
}
|
||||
|
||||
reader(reader&& other)
|
||||
reader(reader&& other) noexcept
|
||||
: buffer_{other.buffer_},
|
||||
next_line_buffer_{other.next_line_buffer_},
|
||||
helper_buffer_{other.helper_buffer_},
|
||||
@ -705,7 +712,7 @@ private:
|
||||
other.file_ = nullptr;
|
||||
}
|
||||
|
||||
reader& operator=(reader&& other) {
|
||||
reader& operator=(reader&& other) noexcept {
|
||||
if (this != &other) {
|
||||
buffer_ = other.buffer_;
|
||||
next_line_buffer_ = other.next_line_buffer_;
|
||||
@ -853,7 +860,7 @@ private:
|
||||
}
|
||||
|
||||
bool escaped_eol(size_t size) {
|
||||
const char* curr;
|
||||
const char* curr = nullptr;
|
||||
for (curr = next_line_buffer_ + size - 1;
|
||||
curr >= next_line_buffer_ &&
|
||||
setup<Options...>::escape::match(*curr);
|
||||
@ -899,7 +906,7 @@ private:
|
||||
size_t& buffer_size, const char* const second,
|
||||
size_t second_size) {
|
||||
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));
|
||||
|
||||
first = new_first;
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include "common.hpp"
|
||||
#include "exception.hpp"
|
||||
#include "setup.hpp"
|
||||
#include "type_traits.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
@ -321,8 +320,9 @@ private:
|
||||
|
||||
trim_left_if_enabled(begin_);
|
||||
|
||||
for (done_ = false; !done_; read(delim))
|
||||
;
|
||||
for (done_ = false; !done_;) {
|
||||
read(delim);
|
||||
}
|
||||
|
||||
return split_data_;
|
||||
}
|
||||
|
@ -34,7 +34,11 @@ struct left_of_impl;
|
||||
|
||||
template <size_t N, typename T, typename... Ts>
|
||||
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");
|
||||
using type = tup_cat_t<T, typename left_of_impl<N - 1, Ts...>::type>;
|
||||
};
|
||||
|
@ -14,14 +14,21 @@ headers = ['type_traits.hpp',
|
||||
|
||||
combined_file = []
|
||||
includes = []
|
||||
in_pp_block = False
|
||||
|
||||
for header in headers:
|
||||
with open(headers_dir + header) as f:
|
||||
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:
|
||||
continue
|
||||
|
||||
if '#include <' in line:
|
||||
if '#include <' in line and not in_pp_block:
|
||||
includes.append(line)
|
||||
continue
|
||||
|
||||
|
105
ssp.hpp
105
ssp.hpp
@ -49,7 +49,11 @@ struct left_of_impl;
|
||||
|
||||
template <size_t N, typename T, typename... Ts>
|
||||
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");
|
||||
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_;
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
@ -617,6 +621,11 @@ struct ne {
|
||||
|
||||
} /* namespace ss */
|
||||
|
||||
#if !__unix__
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#endif
|
||||
|
||||
namespace ss {
|
||||
|
||||
struct none {};
|
||||
@ -628,13 +637,13 @@ constexpr inline auto default_delimiter = ",";
|
||||
constexpr inline auto get_line_initial_buffer_size = 128;
|
||||
|
||||
template <bool StringError>
|
||||
inline void assert_string_error_defined() {
|
||||
void assert_string_error_defined() {
|
||||
static_assert(StringError,
|
||||
"'string_error' needs to be enabled to use 'error_msg'");
|
||||
}
|
||||
|
||||
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 "
|
||||
"'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;
|
||||
|
||||
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)) {
|
||||
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';
|
||||
|
||||
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);
|
||||
size_t buff_used = std::strlen(buff);
|
||||
size_t buff_used = std::strlen(buff.data());
|
||||
|
||||
if (n <= buff_used + line_used) {
|
||||
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;
|
||||
}
|
||||
|
||||
std::memcpy(lineptr + line_used, buff, buff_used);
|
||||
std::memcpy(lineptr + line_used, buff.data(), buff_used);
|
||||
line_used += buff_used;
|
||||
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) {
|
||||
auto new_lineptr = static_cast<char*>(
|
||||
auto* new_lineptr = static_cast<char*>(
|
||||
strict_realloc(lineptr, get_line_initial_buffer_size));
|
||||
lineptr = new_lineptr;
|
||||
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,
|
||||
const char* const csv_data_buffer,
|
||||
size_t csv_data_size, size_t& curr_char) {
|
||||
ssize_t ssize;
|
||||
ssize_t ssize = 0;
|
||||
if (file) {
|
||||
ssize = get_line_file(buffer, buffer_size, file);
|
||||
curr_char += ssize;
|
||||
@ -1359,8 +1368,9 @@ private:
|
||||
|
||||
trim_left_if_enabled(begin_);
|
||||
|
||||
for (done_ = false; !done_; read(delim))
|
||||
;
|
||||
for (done_ = false; !done_;) {
|
||||
read(delim);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
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);
|
||||
std::string long_buff;
|
||||
|
||||
char* buff;
|
||||
char* buff = nullptr;
|
||||
if (string_range > buff_max) {
|
||||
long_buff = std::string{begin, end};
|
||||
buff = long_buff.data();
|
||||
} else {
|
||||
buff = short_buff;
|
||||
buff = short_buff.data();
|
||||
buff[string_range] = '\0';
|
||||
std::copy_n(begin, string_range, buff);
|
||||
}
|
||||
@ -1599,6 +1610,8 @@ struct numeric_wrapper {
|
||||
numeric_wrapper& operator=(numeric_wrapper&&) = default;
|
||||
numeric_wrapper& operator=(const numeric_wrapper&) = default;
|
||||
|
||||
~numeric_wrapper() = default;
|
||||
|
||||
numeric_wrapper(T other) : value{other} {
|
||||
}
|
||||
|
||||
@ -1649,7 +1662,7 @@ template <typename T>
|
||||
struct unsupported_type {
|
||||
constexpr static bool value = false;
|
||||
};
|
||||
} /* namespace error */
|
||||
} /* namespace errors */
|
||||
|
||||
template <typename 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;
|
||||
}
|
||||
} else {
|
||||
constexpr static auto true_size = 4;
|
||||
constexpr static auto false_size = 5;
|
||||
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;
|
||||
} else if (size == 5 && std::strncmp(begin, "false", size) == 0) {
|
||||
} else if (size == false_size &&
|
||||
std::strncmp(begin, "false", size) == 0) {
|
||||
value = false;
|
||||
} else {
|
||||
return false;
|
||||
@ -1971,8 +1987,9 @@ private:
|
||||
}
|
||||
|
||||
std::string error_sufix(const string_range msg, size_t pos) const {
|
||||
constexpr static auto reserve_size = 32;
|
||||
std::string error;
|
||||
error.reserve(32);
|
||||
error.reserve(reserve_size);
|
||||
error.append("at column ")
|
||||
.append(std::to_string(pos + 1))
|
||||
.append(": \'")
|
||||
@ -2138,7 +2155,7 @@ private:
|
||||
////////////////
|
||||
|
||||
bool columns_mapped() const {
|
||||
return column_mappings_.size() != 0;
|
||||
return !column_mappings_.empty();
|
||||
}
|
||||
|
||||
size_t column_position(size_t tuple_position) const {
|
||||
@ -2151,7 +2168,7 @@ private:
|
||||
// assumes positions are valid and the vector is not empty
|
||||
void set_column_mapping(std::vector<size_t> positions,
|
||||
size_t number_of_columns) {
|
||||
column_mappings_ = positions;
|
||||
column_mappings_ = std::move(positions);
|
||||
number_of_columns_ = number_of_columns;
|
||||
}
|
||||
|
||||
@ -2237,7 +2254,7 @@ private:
|
||||
friend class parser;
|
||||
|
||||
std::vector<size_t> column_mappings_;
|
||||
size_t number_of_columns_;
|
||||
size_t number_of_columns_{0};
|
||||
};
|
||||
|
||||
} /* namespace ss */
|
||||
@ -2264,9 +2281,8 @@ class parser {
|
||||
constexpr static bool ignore_empty = setup<Options...>::ignore_empty;
|
||||
|
||||
public:
|
||||
parser(const std::string& file_name,
|
||||
const std::string& delim = ss::default_delimiter)
|
||||
: file_name_{file_name}, reader_{file_name_, delim} {
|
||||
parser(std::string file_name, std::string delim = ss::default_delimiter)
|
||||
: file_name_{std::move(file_name)}, reader_{file_name_, delim} {
|
||||
if (reader_.file_) {
|
||||
read_line();
|
||||
if constexpr (ignore_header) {
|
||||
@ -2299,6 +2315,7 @@ public:
|
||||
|
||||
parser(parser&& other) = default;
|
||||
parser& operator=(parser&& other) = default;
|
||||
~parser() = default;
|
||||
|
||||
parser() = delete;
|
||||
parser(const parser& other) = delete;
|
||||
@ -2468,6 +2485,10 @@ public:
|
||||
|
||||
iterator(const iterator& other) = default;
|
||||
iterator(iterator&& other) = default;
|
||||
~iterator() = default;
|
||||
|
||||
iterator& operator=(const iterator& other) = delete;
|
||||
iterator& operator=(iterator&& other) = delete;
|
||||
|
||||
value& operator*() {
|
||||
return value_;
|
||||
@ -2492,8 +2513,10 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator& operator++(int) {
|
||||
return ++*this;
|
||||
iterator operator++(int) {
|
||||
auto result = *this;
|
||||
++*this;
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator==(const iterator& lhs, const iterator& rhs) {
|
||||
@ -2557,7 +2580,7 @@ public:
|
||||
Fun&& fun = none{}) {
|
||||
using Value = no_void_validator_tup_t<Us...>;
|
||||
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));
|
||||
}
|
||||
|
||||
@ -2566,7 +2589,7 @@ public:
|
||||
template <typename U, typename... Us, typename Fun = none>
|
||||
composite<Ts..., std::optional<U>> or_object(Fun&& fun = none{}) {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -2674,7 +2697,8 @@ private:
|
||||
using Ret = decltype(try_invoke_impl(arg, std::forward<Fun>(fun)));
|
||||
constexpr bool returns_void = std::is_same_v<Ret, 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();
|
||||
}
|
||||
} else {
|
||||
@ -2709,7 +2733,7 @@ private:
|
||||
if (valid()) {
|
||||
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 {
|
||||
reader(const std::string& file_name_, const std::string& delim)
|
||||
: delim_{delim}, file_{std::fopen(file_name_.c_str(), "rb")} {
|
||||
reader(const std::string& file_name_, std::string delim)
|
||||
: delim_{std::move(delim)},
|
||||
file_{std::fopen(file_name_.c_str(), "rb")} {
|
||||
}
|
||||
|
||||
reader(const char* const buffer, size_t csv_data_size,
|
||||
const std::string& delim)
|
||||
: delim_{delim}, csv_data_buffer_{buffer},
|
||||
std::string delim)
|
||||
: delim_{std::move(delim)}, csv_data_buffer_{buffer},
|
||||
csv_data_size_{csv_data_size} {
|
||||
}
|
||||
|
||||
reader(reader&& other)
|
||||
reader(reader&& other) noexcept
|
||||
: buffer_{other.buffer_},
|
||||
next_line_buffer_{other.next_line_buffer_},
|
||||
helper_buffer_{other.helper_buffer_},
|
||||
@ -2936,7 +2961,7 @@ private:
|
||||
other.file_ = nullptr;
|
||||
}
|
||||
|
||||
reader& operator=(reader&& other) {
|
||||
reader& operator=(reader&& other) noexcept {
|
||||
if (this != &other) {
|
||||
buffer_ = other.buffer_;
|
||||
next_line_buffer_ = other.next_line_buffer_;
|
||||
@ -3084,7 +3109,7 @@ private:
|
||||
}
|
||||
|
||||
bool escaped_eol(size_t size) {
|
||||
const char* curr;
|
||||
const char* curr = nullptr;
|
||||
for (curr = next_line_buffer_ + size - 1;
|
||||
curr >= next_line_buffer_ &&
|
||||
setup<Options...>::escape::match(*curr);
|
||||
@ -3130,7 +3155,7 @@ private:
|
||||
size_t& buffer_size, const char* const second,
|
||||
size_t second_size) {
|
||||
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));
|
||||
|
||||
first = new_first;
|
||||
|
@ -3,12 +3,14 @@
|
||||
set -x
|
||||
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; }' \
|
||||
>> ssp.cpp
|
||||
python3 script/single_header_generator.py > ${TMP_HDR}
|
||||
cat ${TMP_HDR} test/test_single_header_main.txt > ${TMP_SRC}
|
||||
|
||||
g++ -std=c++17 ssp.cpp -o ssp.bin -Wall -Wextra
|
||||
./ssp.bin
|
||||
g++ -std=c++17 ${TMP_SRC} -o ${TMP_BIN} -Wall -Wextra
|
||||
./${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