diff --git a/.gitignore b/.gitignore index 1fadaf3..55f29f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ compile_commands.json .clang-format .clang-tidy -.ccls-cache/* +.ccls-cache/ .cache/ experiment/ build/ diff --git a/include/ss/common.hpp b/include/ss/common.hpp index ab6eb59..61b0983 100644 --- a/include/ss/common.hpp +++ b/include/ss/common.hpp @@ -21,13 +21,13 @@ constexpr inline auto default_delimiter = ","; constexpr inline auto get_line_initial_buffer_size = 128; template -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 -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"); } diff --git a/include/ss/extract.hpp b/include/ss/extract.hpp index 682e494..3c2f82e 100644 --- a/include/ss/extract.hpp +++ b/include/ss/extract.hpp @@ -14,6 +14,7 @@ #else #include #include +#include #endif namespace ss { @@ -45,16 +46,17 @@ std::enable_if_t, std::optional> to_num( "Conversion to long double is disabled"); constexpr static auto buff_max = 64; - char short_buff[buff_max]; + std::array 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); } diff --git a/include/ss/parser.hpp b/include/ss/parser.hpp index 2cce8cb..5fbf647 100644 --- a/include/ss/parser.hpp +++ b/include/ss/parser.hpp @@ -32,8 +32,7 @@ class parser { constexpr static bool ignore_empty = setup::ignore_empty; public: - parser(std::string file_name, - std::string delim = ss::default_delimiter) + 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(); @@ -449,7 +448,8 @@ private: using Ret = decltype(try_invoke_impl(arg, std::forward(fun))); constexpr bool returns_void = std::is_same_v; if constexpr (!returns_void) { - if (!try_invoke_impl(std::forward(arg), std::forward(fun))) { + if (!try_invoke_impl(std::forward(arg), + std::forward(fun))) { handle_error_failed_check(); } } else { @@ -681,7 +681,8 @@ private: struct reader { reader(const std::string& file_name_, std::string delim) - : delim_{std::move(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, diff --git a/ssp.hpp b/ssp.hpp index 85371ba..6ec769e 100644 --- a/ssp.hpp +++ b/ssp.hpp @@ -637,13 +637,13 @@ constexpr inline auto default_delimiter = ","; constexpr inline auto get_line_initial_buffer_size = 128; template -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 -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"); } @@ -1562,16 +1562,17 @@ std::enable_if_t, std::optional> to_num( "Conversion to long double is disabled"); constexpr static auto buff_max = 64; - char short_buff[buff_max]; + std::array 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); } @@ -2280,8 +2281,7 @@ class parser { constexpr static bool ignore_empty = setup::ignore_empty; public: - parser(std::string file_name, - std::string delim = ss::default_delimiter) + 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(); @@ -2697,7 +2697,8 @@ private: using Ret = decltype(try_invoke_impl(arg, std::forward(fun))); constexpr bool returns_void = std::is_same_v; if constexpr (!returns_void) { - if (!try_invoke_impl(std::forward(arg), std::forward(fun))) { + if (!try_invoke_impl(std::forward(arg), + std::forward(fun))) { handle_error_failed_check(); } } else { @@ -2929,7 +2930,8 @@ private: struct reader { reader(const std::string& file_name_, std::string delim) - : delim_{std::move(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, diff --git a/test/test_single_header.sh b/test/test_single_header.sh index 8a2bb91..bd47386 100755 --- a/test/test_single_header.sh +++ b/test/test_single_header.sh @@ -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(); 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} diff --git a/test/test_single_header_main.txt b/test/test_single_header_main.txt new file mode 100644 index 0000000..77d8c6c --- /dev/null +++ b/test/test_single_header_main.txt @@ -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 p{data.c_str(), data.size()}; + auto tup = p.get_next>(); + + return 0; +}