diff --git a/src/include/split.hpp b/src/include/split.hpp index 777acda..60b6e8b 100644 --- a/src/include/split.hpp +++ b/src/include/split.hpp @@ -20,6 +20,7 @@ #include #include +#include "type_traits.hpp" // is_string_view; remove when compilers don't suck namespace jessilib { namespace impl { @@ -45,6 +46,18 @@ constexpr auto split_container_helper_f() -> ContainerT { template typename ContainerT, typename... ArgsT> using split_container_helper_t = decltype(split_container_helper_f()); +template::value>::type* = nullptr> +MemberT member_from_range(ItrT in_itr, EndT in_end) { + // Workaround due to C++20 iterator constructor being inconsistently available + return { &*in_itr, static_cast(in_end - in_itr) }; +} + +template::value>::type* = nullptr> +MemberT member_from_range(ItrT in_itr, EndT in_end) { + // Workaround due to C++20 iterator constructor being inconsistently available + return { in_itr, in_end }; +} + } // namespace impl /** @@ -66,18 +79,18 @@ constexpr auto split(const InputT& in_string, typename InputT::value_type in_del return result; } - auto begin = in_string.data(); - auto end = in_string.data() + in_string.size(); + auto begin = in_string.begin(); + auto end = in_string.end(); for (auto itr = begin; itr != end; ++itr) { if (*itr == in_delim) { // Push token to result - result.emplace_back(begin, itr); + result.push_back(impl::member_from_range(begin, itr)); begin = itr + 1; } } // Push final token to the end; may be empty - result.emplace_back(begin, end); + result.push_back(impl::member_from_range(begin, end)); return result; } @@ -102,13 +115,13 @@ constexpr std::pair split_once(const InStringT& in return result; } - auto begin = in_string.data(); - auto end = in_string.data() + in_string.size(); + auto begin = in_string.begin(); + auto end = in_string.end(); for (auto itr = begin; itr != end; ++itr) { if (*itr == in_delim) { // in_delim found; split upon it - result.first = ResultMemberT{ begin, itr }; - result.second = ResultMemberT{ itr + 1, end }; + result.first = impl::member_from_range(begin, itr); + result.second = impl::member_from_range(itr + 1, end); return result; } } @@ -138,19 +151,19 @@ constexpr auto split_n(const InputT& in_string, typename InputT::value_type in_d return result; } - auto begin = in_string.data(); - auto end = in_string.data() + in_string.size(); + auto begin = in_string.begin(); + auto end = in_string.end(); for (auto itr = begin; itr != end && in_limit != 0; ++itr) { if (*itr == in_delim) { // Push token to result - result.emplace_back(begin, itr); + result.push_back(impl::member_from_range(begin, itr)); begin = itr + 1; --in_limit; } } // Push final token to the end; may be empty - result.emplace_back(begin, end); + result.push_back(impl::member_from_range(begin, end)); return result; } diff --git a/src/include/type_traits.hpp b/src/include/type_traits.hpp index af6242f..85fd80d 100644 --- a/src/include/type_traits.hpp +++ b/src/include/type_traits.hpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include namespace jessilib { @@ -37,6 +39,32 @@ struct remove_cvref { typedef std::remove_cv_t> type; }; +/** is_basic_string */ + +template +struct is_basic_string : std::false_type {}; + +template +struct is_basic_string> { + using type = T; + static constexpr bool value{ true }; + constexpr operator bool() const noexcept { return true; } + constexpr bool operator()() const noexcept { return true; } +}; + +/** is_basic_string_view */ + +template +struct is_basic_string_view : std::false_type {}; + +template +struct is_basic_string_view> { + using type = T; + static constexpr bool value{ true }; + constexpr operator bool() const noexcept { return true; } + constexpr bool operator()() const noexcept { return true; } +}; + /** is_vector */ template