diff --git a/.gitignore b/.gitignore index eb880af..38a1e99 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ build/ hbuild/ subprojects/* !subprojects/*.wrap +ssp.cpp +ssp.bin diff --git a/README.md b/README.md index 44d97d4..57ca902 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,10 @@ Bill (Heath) Gates 65 3.3 * [Conversions can be chained if invalid](#Substitute-conversions) * Fast +# Single header + +The library can be used with a single header file **`ssp.hpp`**, but it sufferes a slight performance loss when converting floating point values since the **`fast_float`** library is not present within the file. + # Installation ```shell @@ -78,8 +82,8 @@ $ cmake --configure . $ sudo make install ``` -*Note, this will also install the fast_float library* -The library supports [CMake](#Cmake) and [meson](#Meson) build systems +*Note, this will also install the fast_float library* +The library supports [CMake](#Cmake) and [meson](#Meson) build systems # Usage diff --git a/include/ss/extract.hpp b/include/ss/extract.hpp index 2e9e6f0..760aca8 100644 --- a/include/ss/extract.hpp +++ b/include/ss/extract.hpp @@ -2,21 +2,27 @@ #include "type_traits.hpp" #include -#include #include #include #include -#include #include #include #include +#ifndef SSP_DISABLE_FAST_FLOAT +#include +#else +#include +#endif + namespace ss { //////////////// // number converters //////////////// +#ifndef SSP_DISABLE_FAST_FLOAT + template std::enable_if_t, std::optional> to_num( const char* const begin, const char* const end) { @@ -29,6 +35,22 @@ std::enable_if_t, std::optional> to_num( return ret; } +#else + +template +std::enable_if_t, std::optional> to_num( + const char* const begin, const char* const end) { + T ret; + auto [ptr, ec] = std::from_chars(begin, end, ret); + + if (ec != std::errc() || ptr != end) { + return std::nullopt; + } + return ret; +} + +#endif + inline std::optional from_char(char c) { if (c >= '0' && c <= '9') { return c - '0'; diff --git a/script/single_header_generator.py b/script/single_header_generator.py new file mode 100755 index 0000000..3916666 --- /dev/null +++ b/script/single_header_generator.py @@ -0,0 +1,34 @@ +#!/bin/python3 + +headers_dir = 'include/ss/' +headers = ['type_traits.hpp', + 'function_traits.hpp', + 'restrictions.hpp', + 'common.hpp', + 'setup.hpp', + 'splitter.hpp', + 'extract.hpp', + 'converter.hpp', + 'parser.hpp'] + +combined_file = [] +includes = [] + +for header in headers: + with open(headers_dir + header) as f: + for line in f.read().splitlines(): + if '#include "' in line or '#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SSP_DISABLE_FAST_FLOAT + + +namespace ss { + +//////////////// +// tup merge/cat +//////////////// + +template +struct tup_cat; + +template +struct tup_cat, std::tuple> { + using type = std::tuple; +}; + +template +struct tup_cat> { + using type = std::tuple; +}; + +template +using tup_cat_t = typename tup_cat::type; + +//////////////// +// tup first/head +//////////////// + +template +struct left_of_impl; + +template +struct left_of_impl { + static_assert(N < 128, "recursion limit reached"); + static_assert(N != 0, "cannot take the whole tuple"); + using type = tup_cat_t::type>; +}; + +template +struct left_of_impl<0, T, Ts...> { + using type = std::tuple; +}; + +template +using left_of_t = typename left_of_impl::type; + +template +using first_t = typename left_of_impl::type; + +template +using head_t = typename left_of_impl<0, Ts...>::type; + +//////////////// +// tup tail/last +//////////////// + +template +struct right_of_impl; + +template +struct right_of_impl { + using type = typename right_of_impl::type; +}; + +template +struct right_of_impl<0, T, Ts...> { + using type = std::tuple; +}; + +template +using right_of_t = typename right_of_impl::type; + +template +using tail_t = typename right_of_impl<1, Ts...>::type; + +template +using last_t = typename right_of_impl::type; + +//////////////// +// apply trait +//////////////// + +template