20 Commits

Author SHA1 Message Date
red0124
8b928de086 Merge pull request #22 from red0124/bugfix/multiline_on_custom_delimiter
Fix bug where the default delimiter would be used for multiline data
2023-07-25 00:46:43 +02:00
ado
6edce88d79 Fix bug where the default delimiter would be used for multiline data 2023-07-25 00:36:53 +02:00
red0124
6196f7796b Merge pull request #21 from red0124/improvement/markdown_labels
Update README links to sections
2023-07-20 00:21:38 +02:00
ado
5672aa635e Update README links to sections 2023-07-20 00:19:31 +02:00
ado
3eefac93b1 Fix README issues 2023-05-25 01:10:37 +02:00
ado
774f452689 fix typo 2023-03-19 19:48:22 +01:00
ado
448066b173 Update version 2023-02-18 14:20:32 +01:00
red0124
a7eca6064a Merge pull request #20 from red0124/improvement/conditional_t
Replace ss::ternary_t with std::conditional_t
2023-02-12 12:57:36 +01:00
ado
a4ecbd4dc8 Replace ss::ternary_t with std::conditional_t 2023-02-12 12:45:49 +01:00
red0124
a9e9783e6a Merge pull request #19 from red0124/improvement/doctest_update
Make project used forked doctest
2023-02-12 12:38:34 +01:00
ado
04edf1e532 Make project used forked doctest 2023-02-12 12:23:25 +01:00
red0124
8dcb69aa2c Merge pull request #18 from red0124/improvement/cmake_update
Update CMake files
2023-02-09 20:20:27 +01:00
ado
db2a72c18b Update CMake files 2023-02-08 21:54:44 +01:00
red0124
0e28a06799 Merge pull request #17 from red0124/improvement/meson_update
Improvement/meson update
2023-02-07 23:29:29 +01:00
ado
2218b01b81 Merge remote-tracking branch 'origin/master' into improvement/meson_update 2023-02-07 23:22:36 +01:00
ado
f777b04eb8 Fix failing mingw unit test 2023-02-01 22:45:50 +01:00
ado
7831bbd735 Add forcefallback wrap_mode option in meson.build 2023-02-01 01:22:43 +01:00
ado
6efb39b2db Add version number to meson.build 2023-02-01 00:57:32 +01:00
ado
f2b49e6d6c Update meson dependency usage 2023-02-01 00:52:23 +01:00
ado
5cb3c65b24 Update doctest revision 2023-01-31 21:23:04 +01:00
14 changed files with 116 additions and 146 deletions

View File

@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.14)
project( project(
ssp ssp
VERSION 0.0.1 VERSION 1.4.0
DESCRIPTION "Static split parser" DESCRIPTION "csv parser"
HOMEPAGE_URL "https://github.com/red0124/ssp" HOMEPAGE_URL "https://github.com/red0124/ssp"
LANGUAGES CXX LANGUAGES CXX
) )
@@ -11,22 +11,23 @@ project(
# ---- Warning guard ---- # ---- Warning guard ----
# Protect dependents from this project's warnings if the guard isn't disabled # Protect dependents from this project's warnings if the guard isn't disabled
set(ssp_warning_guard SYSTEM) set(SSP_WARNING_GUARD SYSTEM)
if(ssp_INCLUDE_WITHOUT_SYSTEM) if(SSP_INCLUDE_WITHOUT_SYSTEM)
set(ssp_warning_guard "") set(SSP_WARNING_GUARD "")
endif() endif()
# ---- Dependencies ---- # ---- Dependencies ----
include(FetchContent) include(FetchContent)
FetchContent_Declare( fetchcontent_declare(
fast_float fast_float
GIT_REPOSITORY https://github.com/red0124/fast_float.git GIT_REPOSITORY https://github.com/red0124/fast_float.git
GIT_TAG origin/meson GIT_TAG origin/meson
GIT_SHALLOW TRUE) GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(fast_float) fetchcontent_makeavailable(fast_float)
set(fast_float_source_dir "${FETCHCONTENT_BASE_DIR}/fast_float-src") set(FAST_FLOAT_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/fast_float-src")
# ---- Declare library ---- # ---- Declare library ----
@@ -35,10 +36,10 @@ add_library(ssp::ssp ALIAS ssp)
target_include_directories( target_include_directories(
ssp ssp
${ssp_warning_guard} ${SSP_WARNING_GUARD}
INTERFACE INTERFACE
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>" "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/fast_float>" "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/fast_float>"
) )
target_compile_features(ssp INTERFACE cxx_std_17) target_compile_features(ssp INTERFACE cxx_std_17)
@@ -46,8 +47,8 @@ target_compile_features(ssp INTERFACE cxx_std_17)
target_link_libraries( target_link_libraries(
ssp ssp
INTERFACE INTERFACE
"$<$<AND:$<CXX_COMPILER_ID:AppleClang,Clang>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.0>>:c++fs>" "$<$<AND:$<CXX_COMPILER_ID:AppleClang,Clang>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.0>>:c++fs>"
"$<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.1>>:stdc++fs>" "$<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.1>>:stdc++fs>"
) )
# ---- Install ---- # ---- Install ----
@@ -55,19 +56,21 @@ target_link_libraries(
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
include(GNUInstallDirs) include(GNUInstallDirs)
set(ssp_directory "ssp-${PROJECT_VERSION}") set(SSP_DIRECTORY "ssp-${PROJECT_VERSION}")
set(ssp_include_directory "${CMAKE_INSTALL_INCLUDEDIR}") set(SSP_INCLUDE_DIRECTORY "${CMAKE_INSTALL_INCLUDEDIR}")
install( install(
DIRECTORY "${PROJECT_SOURCE_DIR}/include/" "${fast_float_source_dir}/include/" DIRECTORY
DESTINATION "${ssp_include_directory}" "${PROJECT_SOURCE_DIR}/include/"
"${FAST_FLOAT_SOURCE_DIR}/include/"
DESTINATION "${SSP_INCLUDE_DIRECTORY}"
COMPONENT ssp_Development COMPONENT ssp_Development
) )
install( install(
TARGETS ssp TARGETS ssp
EXPORT sspTargets EXPORT sspTargets
INCLUDES DESTINATION "${ssp_include_directory}" INCLUDES DESTINATION "${SSP_INCLUDE_DIRECTORY}"
) )
write_basic_package_version_file( write_basic_package_version_file(
@@ -76,11 +79,11 @@ write_basic_package_version_file(
ARCH_INDEPENDENT ARCH_INDEPENDENT
) )
set(ssp_install_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/${ssp_directory}") set(SSP_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${SSP_DIRECTORY}")
install( install(
FILES "${PROJECT_BINARY_DIR}/ssp-config-version.cmake" FILES "${PROJECT_BINARY_DIR}/ssp-config-version.cmake"
DESTINATION "${ssp_install_cmakedir}" DESTINATION "${SSP_INSTALL_CMAKEDIR}"
COMPONENT ssp_Development COMPONENT ssp_Development
) )
@@ -88,10 +91,10 @@ install(
EXPORT sspTargets EXPORT sspTargets
FILE ssp-config.cmake FILE ssp-config.cmake
NAMESPACE ssp:: NAMESPACE ssp::
DESTINATION "${ssp_install_cmakedir}" DESTINATION "${SSP_INSTALL_CMAKEDIR}"
COMPONENT ssp_Development COMPONENT ssp_Development
) )
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
include(CPack) include(CPack)
endif() endif()

View File

@@ -53,20 +53,20 @@ Brian S. Wolfe 40 1.9
Bill (Heath) Gates 65 3.3 Bill (Heath) Gates 65 3.3
``` ```
# Features # Features
* [Works on any type](#Custom-conversions) * [Works on any type](#custom-conversions)
* Easy to use * Easy to use
* No exceptions * No exceptions
* [Works with headers](#Headers) * [Works with headers](#headers)
* [Works with quotes, escapes and spacings](#Setup) * [Works with quotes, escapes and spacings](#setup)
* [Works with values containing new lines](#Multiline) * [Works with values containing new lines](#multiline)
* [Columns and rows can be ignored](#Special-types) * [Columns and rows can be ignored](#special-types)
* Works with any type of delimiter * Works with any type of delimiter
* Can return whole objects composed of converted values * Can return whole objects composed of converted values
* [Descriptive error handling can be enabled](#Error-handling) * [Descriptive error handling can be enabled](#error-handling)
* [Restrictions can be added for each column](#Restrictions) * [Restrictions can be added for each column](#restrictions)
* [Works with `std::optional` and `std::variant`](#Special-types) * [Works with `std::optional` and `std::variant`](#special-types)
* Works with **`CRLF`** and **`LF`** * Works with **`CRLF`** and **`LF`**
* [Conversions can be chained if invalid](#Substitute-conversions) * [Conversions can be chained if invalid](#substitute-conversions)
* Fast * Fast
# Single header # Single header
@@ -378,7 +378,7 @@ if(std::holds_alternative<float>(grade)) {
``` ```
## Restrictions ## Restrictions
Custom **`restrictions`** can be used to narrow down the conversions of unwanted values. **`ss::ir`** (in range) and **`ss::ne`** (none empty) are one of those: Custom **`restrictions`** can be used to narrow down the conversions of unwanted values. **`ss::ir`** (in range) and **`ss::ne`** (none empty) are some of those:
```cpp ```cpp
// ss::ne makes sure that the name is not empty // ss::ne makes sure that the name is not empty
// ss::ir makes sure that the grade will be in range [0, 10] // ss::ir makes sure that the grade will be in range [0, 10]
@@ -472,7 +472,6 @@ The delimiter is " ", and the number of columns varies depending on which shape
```cpp ```cpp
ss::parser p{"shapes.txt", " "}; ss::parser p{"shapes.txt", " "};
if (!p.valid()) { if (!p.valid()) {
std::cout << p.error_msg() << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@@ -632,6 +631,5 @@ revision = origin/master
``` ```
Then simply fetch the dependency and it is ready to be used: Then simply fetch the dependency and it is ready to be used:
```meson ```meson
ssp_sub = subproject('ssp') ssp_dep = dependency('ssp')
ssp_dep = ssp_sub.get_variable('ssp_dep')
``` ```

View File

@@ -102,7 +102,7 @@ class converter {
constexpr static auto string_error = setup<Matchers...>::string_error; constexpr static auto string_error = setup<Matchers...>::string_error;
constexpr static auto default_delimiter = ","; constexpr static auto default_delimiter = ",";
using error_type = ss::ternary_t<string_error, std::string, bool>; using error_type = std::conditional_t<string_error, std::string, bool>;
public: public:
// parses line with given delimiter, returns a 'T' object created with // parses line with given delimiter, returns a 'T' object created with
@@ -194,7 +194,7 @@ private:
//////////////// ////////////////
const split_data& resplit(line_ptr_type new_line, ssize_t new_size, const split_data& resplit(line_ptr_type new_line, ssize_t new_size,
const std::string& delim = default_delimiter) { const std::string& delim) {
return splitter_.resplit(new_line, new_size, delim); return splitter_.resplit(new_line, new_size, delim);
} }

View File

@@ -17,7 +17,7 @@ class parser {
constexpr static auto string_error = setup<Matchers...>::string_error; constexpr static auto string_error = setup<Matchers...>::string_error;
using multiline = typename setup<Matchers...>::multiline; using multiline = typename setup<Matchers...>::multiline;
using error_type = ss::ternary_t<string_error, std::string, bool>; using error_type = std::conditional_t<string_error, std::string, bool>;
constexpr static bool escaped_multiline_enabled = constexpr static bool escaped_multiline_enabled =
multiline::enabled && setup<Matchers...>::escape::enabled; multiline::enabled && setup<Matchers...>::escape::enabled;
@@ -151,8 +151,8 @@ public:
template <bool get_object, typename T, typename... Ts> template <bool get_object, typename T, typename... Ts>
struct iterable { struct iterable {
struct iterator { struct iterator {
using value = using value = std::conditional_t<get_object, T,
ss::ternary_t<get_object, T, no_void_validator_tup_t<T, Ts...>>; no_void_validator_tup_t<T, Ts...>>;
iterator() : parser_{nullptr} { iterator() : parser_{nullptr} {
} }
@@ -623,7 +623,8 @@ private:
} }
} }
next_line_converter_.resplit(next_line_buffer_, size); next_line_converter_.resplit(next_line_buffer_, size,
delim_);
} }
} }

View File

@@ -111,8 +111,8 @@ struct get_matcher<Matcher, T, Ts...> {
static_assert(count_v<is_matcher, T, Ts...> <= 1, static_assert(count_v<is_matcher, T, Ts...> <= 1,
"the same matcher is cannot" "the same matcher is cannot"
"be defined multiple times"); "be defined multiple times");
using type = ternary_t<is_matcher<T>::value, T, using type = std::conditional_t<is_matcher<T>::value, T,
typename get_matcher<Matcher, Ts...>::type>; typename get_matcher<Matcher, Ts...>::type>;
}; };
template <template <char...> class Matcher> template <template <char...> class Matcher>
@@ -149,8 +149,8 @@ struct get_multiline;
template <typename T, typename... Ts> template <typename T, typename... Ts>
struct get_multiline<T, Ts...> { struct get_multiline<T, Ts...> {
using type = ternary_t<is_instance_of_multiline<T>::value, T, using type = std::conditional_t<is_instance_of_multiline<T>::value, T,
typename get_multiline<Ts...>::type>; typename get_multiline<Ts...>::type>;
}; };
template <> template <>
@@ -227,8 +227,10 @@ public:
using quote = get_matcher_t<quote, Ts...>; using quote = get_matcher_t<quote, Ts...>;
using escape = get_matcher_t<escape, Ts...>; using escape = get_matcher_t<escape, Ts...>;
using trim_left = ternary_t<trim_all::enabled, trim_all, trim_left_only>; using trim_left =
using trim_right = ternary_t<trim_all::enabled, trim_all, trim_right_only>; std::conditional_t<trim_all::enabled, trim_all, trim_left_only>;
using trim_right =
std::conditional_t<trim_all::enabled, trim_all, trim_right_only>;
using multiline = get_multiline_t<Ts...>; using multiline = get_multiline_t<Ts...>;
constexpr static bool string_error = (count_string_error == 1); constexpr static bool string_error = (count_string_error == 1);

View File

@@ -23,10 +23,10 @@ private:
constexpr static auto string_error = setup<Ts...>::string_error; constexpr static auto string_error = setup<Ts...>::string_error;
constexpr static auto is_const_line = !quote::enabled && !escape::enabled; constexpr static auto is_const_line = !quote::enabled && !escape::enabled;
using error_type = ss::ternary_t<string_error, std::string, bool>; using error_type = std::conditional_t<string_error, std::string, bool>;
public: public:
using line_ptr_type = ternary_t<is_const_line, const char*, char*>; using line_ptr_type = std::conditional_t<is_const_line, const char*, char*>;
bool valid() const { bool valid() const {
if constexpr (string_error) { if constexpr (string_error) {

View File

@@ -357,26 +357,6 @@ struct is_instance_of<Template, Template<Ts...>> {
template <template <typename...> class Template, typename... Ts> template <template <typename...> class Template, typename... Ts>
constexpr bool is_instance_of_v = is_instance_of<Template, Ts...>::value; constexpr bool is_instance_of_v = is_instance_of<Template, Ts...>::value;
////////////////
// ternary
////////////////
template <bool B, typename T, typename U>
struct ternary;
template <typename T, typename U>
struct ternary<true, T, U> {
using type = T;
};
template <typename T, typename U>
struct ternary<false, T, U> {
using type = U;
};
template <bool B, typename T, typename U>
using ternary_t = typename ternary<B, T, U>::type;
//////////////// ////////////////
// tuple to struct // tuple to struct
//////////////// ////////////////

View File

@@ -1,17 +1,24 @@
project('ssp', 'cpp', project(
'ssp',
['cpp'],
default_options : default_options :
['warning_level=3', ['warning_level=3',
'cpp_std=c++17', 'cpp_std=c++17',
'buildtype=debugoptimized']) 'buildtype=debugoptimized',
'wrap_mode=forcefallback'],
version: '1.4.0',
meson_version:'>=0.54.0')
fast_float_sub = subproject('fast_float') fast_float_dep = dependency('fast_float')
fast_float_dep = fast_float_sub.get_variable('fast_float_dep')
ssp_dep = declare_dependency( ssp_dep = declare_dependency(
include_directories: include_directories('include'), include_directories: include_directories('include'),
dependencies: fast_float_dep dependencies: fast_float_dep
) )
meson.override_dependency('ssp', ssp_dep)
if not meson.is_subproject() if not meson.is_subproject()
subdir('test') subdir('test')
endif endif

View File

@@ -5,7 +5,7 @@ BUILD_TYPE=Debug
set -eux set -eux
git clone https://github.com/onqtam/doctest -b 2.4.4 --depth 1 git clone https://github.com/red0124/doctest -b master --depth 1
cmake -S doctest -B doctest/build \ cmake -S doctest -B doctest/build \
-D CMAKE_BUILD_TYPE=${BUILD_TYPE} \ -D CMAKE_BUILD_TYPE=${BUILD_TYPE} \

51
ssp.hpp
View File

@@ -17,7 +17,6 @@
#include <vector> #include <vector>
#define SSP_DISABLE_FAST_FLOAT #define SSP_DISABLE_FAST_FLOAT
namespace ss { namespace ss {
//////////////// ////////////////
@@ -372,26 +371,6 @@ struct is_instance_of<Template, Template<Ts...>> {
template <template <typename...> class Template, typename... Ts> template <template <typename...> class Template, typename... Ts>
constexpr bool is_instance_of_v = is_instance_of<Template, Ts...>::value; constexpr bool is_instance_of_v = is_instance_of<Template, Ts...>::value;
////////////////
// ternary
////////////////
template <bool B, typename T, typename U>
struct ternary;
template <typename T, typename U>
struct ternary<true, T, U> {
using type = T;
};
template <typename T, typename U>
struct ternary<false, T, U> {
using type = U;
};
template <bool B, typename T, typename U>
using ternary_t = typename ternary<B, T, U>::type;
//////////////// ////////////////
// tuple to struct // tuple to struct
//////////////// ////////////////
@@ -415,7 +394,6 @@ T to_object(U&& data) {
} /* trait */ } /* trait */
namespace ss { namespace ss {
//////////////// ////////////////
@@ -797,10 +775,10 @@ struct get_matcher<Matcher, T, Ts...> {
struct is_matcher : is_instance_of_matcher<U, Matcher> {}; struct is_matcher : is_instance_of_matcher<U, Matcher> {};
static_assert(count_v<is_matcher, T, Ts...> <= 1, static_assert(count_v<is_matcher, T, Ts...> <= 1,
"the same matcher is cannot" "the same matcher cannot"
"be defined multiple times"); "be defined multiple times");
using type = ternary_t<is_matcher<T>::value, T, using type = std::conditional_t<is_matcher<T>::value, T,
typename get_matcher<Matcher, Ts...>::type>; typename get_matcher<Matcher, Ts...>::type>;
}; };
template <template <char...> class Matcher> template <template <char...> class Matcher>
@@ -837,8 +815,8 @@ struct get_multiline;
template <typename T, typename... Ts> template <typename T, typename... Ts>
struct get_multiline<T, Ts...> { struct get_multiline<T, Ts...> {
using type = ternary_t<is_instance_of_multiline<T>::value, T, using type = std::conditional_t<is_instance_of_multiline<T>::value, T,
typename get_multiline<Ts...>::type>; typename get_multiline<Ts...>::type>;
}; };
template <> template <>
@@ -915,8 +893,10 @@ public:
using quote = get_matcher_t<quote, Ts...>; using quote = get_matcher_t<quote, Ts...>;
using escape = get_matcher_t<escape, Ts...>; using escape = get_matcher_t<escape, Ts...>;
using trim_left = ternary_t<trim_all::enabled, trim_all, trim_left_only>; using trim_left =
using trim_right = ternary_t<trim_all::enabled, trim_all, trim_right_only>; std::conditional_t<trim_all::enabled, trim_all, trim_left_only>;
using trim_right =
std::conditional_t<trim_all::enabled, trim_all, trim_right_only>;
using multiline = get_multiline_t<Ts...>; using multiline = get_multiline_t<Ts...>;
constexpr static bool string_error = (count_string_error == 1); constexpr static bool string_error = (count_string_error == 1);
@@ -973,10 +953,10 @@ private:
constexpr static auto string_error = setup<Ts...>::string_error; constexpr static auto string_error = setup<Ts...>::string_error;
constexpr static auto is_const_line = !quote::enabled && !escape::enabled; constexpr static auto is_const_line = !quote::enabled && !escape::enabled;
using error_type = ss::ternary_t<string_error, std::string, bool>; using error_type = std::conditional_t<string_error, std::string, bool>;
public: public:
using line_ptr_type = ternary_t<is_const_line, const char*, char*>; using line_ptr_type = std::conditional_t<is_const_line, const char*, char*>;
bool valid() const { bool valid() const {
if constexpr (string_error) { if constexpr (string_error) {
@@ -1400,7 +1380,6 @@ public:
} /* ss */ } /* ss */
#ifndef SSP_DISABLE_FAST_FLOAT #ifndef SSP_DISABLE_FAST_FLOAT
#else #else
#endif #endif
@@ -1838,7 +1817,7 @@ class converter {
constexpr static auto string_error = setup<Matchers...>::string_error; constexpr static auto string_error = setup<Matchers...>::string_error;
constexpr static auto default_delimiter = ","; constexpr static auto default_delimiter = ",";
using error_type = ss::ternary_t<string_error, std::string, bool>; using error_type = std::conditional_t<string_error, std::string, bool>;
public: public:
// parses line with given delimiter, returns a 'T' object created with // parses line with given delimiter, returns a 'T' object created with
@@ -2219,7 +2198,6 @@ private:
} /* ss */ } /* ss */
namespace ss { namespace ss {
template <typename... Matchers> template <typename... Matchers>
@@ -2227,7 +2205,7 @@ class parser {
constexpr static auto string_error = setup<Matchers...>::string_error; constexpr static auto string_error = setup<Matchers...>::string_error;
using multiline = typename setup<Matchers...>::multiline; using multiline = typename setup<Matchers...>::multiline;
using error_type = ss::ternary_t<string_error, std::string, bool>; using error_type = std::conditional_t<string_error, std::string, bool>;
constexpr static bool escaped_multiline_enabled = constexpr static bool escaped_multiline_enabled =
multiline::enabled && setup<Matchers...>::escape::enabled; multiline::enabled && setup<Matchers...>::escape::enabled;
@@ -2362,7 +2340,8 @@ public:
struct iterable { struct iterable {
struct iterator { struct iterator {
using value = using value =
ss::ternary_t<get_object, T, no_void_validator_tup_t<T, Ts...>>; std::conditional_t<get_object, T,
no_void_validator_tup_t<T, Ts...>>;
iterator() : parser_{nullptr} { iterator() : parser_{nullptr} {
} }

View File

@@ -1,3 +1,3 @@
[wrap-git] [wrap-git]
url = https://github.com/onqtam/doctest url = https://github.com/red0124/doctest
revision = 2.4.4 revision = master

View File

@@ -4,34 +4,38 @@ project(ssp_tests CXX)
# ---- Dependencies ---- # ---- Dependencies ----
set(
ssp_INCLUDE_WITHOUT_SYSTEM
YES
CACHE
INTERNAL
"Turn the warning guard off to have errors appear in test builds"
)
include(FetchContent) include(FetchContent)
FetchContent_Declare(ssp SOURCE_DIR "${PROJECT_SOURCE_DIR}/..") fetchcontent_declare(ssp SOURCE_DIR "${PROJECT_SOURCE_DIR}/..")
FetchContent_MakeAvailable(ssp) fetchcontent_makeavailable(ssp)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(ssp INTERFACE -Wall -Wextra) target_compile_options(ssp INTERFACE -Wall -Wextra)
endif() endif()
find_package(doctest 2.4.4 CONFIG REQUIRED) include(FetchContent)
# for doctest_discover_tests fetchcontent_declare(
include(doctest) DOCTEST
GIT_REPOSITORY https://github.com/red0124/doctest
GIT_TAG origin/master
GIT_SHALLOW TRUE
)
fetchcontent_makeavailable(DOCTEST)
set(DOCTEST "${FETCHCONTENT_BASE_DIR}/doctest-src")
# ---- Test ---- # ---- Test ----
enable_testing() enable_testing()
foreach(name IN ITEMS test_splitter test_parser test_converter test_extractions) foreach(name IN ITEMS test_splitter test_parser test_converter test_extractions)
add_executable("${name}" "${name}.cpp") add_executable("${name}" "${name}.cpp")
target_link_libraries("${name}" PRIVATE ssp::ssp fast_float doctest::doctest) target_link_libraries(
target_compile_definitions("${name}" PRIVATE "${name}"
DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN CMAKE_GITHUB_CI) PRIVATE ssp::ssp fast_float doctest::doctest
doctest_discover_tests("${name}") )
target_compile_definitions(
"${name}"
PRIVATE DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN CMAKE_GITHUB_CI
)
add_test(NAME "${name}" COMMAND "${name}")
endforeach() endforeach()

View File

@@ -7,8 +7,7 @@ test_sources = files([
'test_extractions_without_fast_float.cpp', 'test_extractions_without_fast_float.cpp',
]) ])
doctest_proj = subproject('doctest') doctest_dep = dependency('doctest')
doctest_dep = doctest_proj.get_variable('doctest_dep')
test_exe = executable( test_exe = executable(
'test_ssp', 'test_ssp',

View File

@@ -610,8 +610,6 @@ struct xyz {
}; };
TEST_CASE("parser test the moving of parsed values") { TEST_CASE("parser test the moving of parsed values") {
size_t move_called_one_col;
{ {
unique_file_name f; unique_file_name f;
{ {
@@ -621,8 +619,7 @@ TEST_CASE("parser test the moving of parsed values") {
ss::parser p{f.name, ","}; ss::parser p{f.name, ","};
auto x = p.get_next<my_string>(); auto x = p.get_next<my_string>();
CHECK_LT(move_called, 3); CHECK_LE(move_called, 1);
move_called_one_col = move_called;
move_called = 0; move_called = 0;
} }
@@ -636,21 +633,21 @@ TEST_CASE("parser test the moving of parsed values") {
ss::parser p{f.name, ","}; ss::parser p{f.name, ","};
auto x = p.get_next<my_string, my_string, my_string>(); auto x = p.get_next<my_string, my_string, my_string>();
CHECK_LE(move_called, 3 * move_called_one_col); CHECK_LE(move_called, 3);
move_called = 0; move_called = 0;
} }
{ {
ss::parser p{f.name, ","}; ss::parser p{f.name, ","};
auto x = p.get_object<xyz, my_string, my_string, my_string>(); auto x = p.get_object<xyz, my_string, my_string, my_string>();
CHECK_LE(move_called, 6 * move_called_one_col); CHECK_LE(move_called, 6);
move_called = 0; move_called = 0;
} }
{ {
ss::parser p{f.name, ","}; ss::parser p{f.name, ","};
auto x = p.get_next<xyz>(); auto x = p.get_next<xyz>();
CHECK_LE(move_called, 6 * move_called_one_col); CHECK_LE(move_called, 6);
move_called = 0; move_called = 0;
} }
} }