From bdebc6fba2399a00505f1d238661341c443532ba Mon Sep 17 00:00:00 2001 From: Jessica James Date: Wed, 10 Nov 2021 20:56:23 -0600 Subject: [PATCH] More cleanup --- src/include/split.hpp | 83 ++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/include/split.hpp b/src/include/split.hpp index 157059c..d91289d 100644 --- a/src/include/split.hpp +++ b/src/include/split.hpp @@ -29,24 +29,23 @@ #include namespace jessilib { -namespace impl { -template typename ContainerT, typename FallbackArg, typename... ArgsT> -struct split_container_helper { - using type = ContainerT; +template typename ContainerT, typename ElementT, typename...> +struct split_defaults { + using member_type = std::basic_string; + using container_type = ContainerT; }; -template typename ContainerT, typename FallbackArg, typename FirstOptional, typename... ArgsT> -struct split_container_helper { - using type = ContainerT; +template typename ContainerT, typename ElementT, typename FirstOptional, typename... ContainerArgsT> +struct split_defaults { + using member_type = FirstOptional; + using container_type = ContainerT; }; -template typename ContainerT, typename... ArgsT> -using split_container_helper_t = typename split_container_helper::type; - +// Can probably be specialized for types which don't take in iterators _or_ template::value>::type* = nullptr> -MemberT member_from_range(ItrT in_itr, EndT in_end) { - // Workaround due to C++20 iterator constructor being inconsistently available +MemberT make_split_member(ItrT in_itr, EndT in_end) { + // Intended for string_view if constexpr (std::is_pointer_v) { return { in_itr, static_cast(in_end - in_itr) }; } @@ -59,13 +58,11 @@ MemberT member_from_range(ItrT in_itr, EndT in_end) { } template::value>::type* = nullptr> -MemberT member_from_range(ItrT in_itr, EndT in_end) { - // Workaround due to C++20 iterator constructor being inconsistently available +MemberT make_split_member(ItrT in_itr, EndT in_end) { + // Can construct with iterators, so construct with iterators return { in_itr, in_end }; } -} // namespace impl - /** * Splits an input string into substrings * @@ -78,8 +75,9 @@ MemberT member_from_range(ItrT in_itr, EndT in_end) { */ template typename ContainerT = std::vector, typename... ContainerArgsT, typename ItrT, typename EndT, typename ElementT> constexpr auto split(ItrT begin, EndT end, ElementT in_delim) { - using MemberT = std::tuple_element_t<0, std::tuple>>; - using container_type = impl::split_container_helper_t; + using split_defaults_type = split_defaults; + using member_type = typename split_defaults_type::member_type; + using container_type = typename split_defaults_type::container_type; container_type result; if (begin >= end) { @@ -90,13 +88,13 @@ constexpr auto split(ItrT begin, EndT end, ElementT in_delim) { for (auto itr = begin; itr != end; ++itr) { if (*itr == in_delim) { // Push token to result - result.push_back(impl::member_from_range(begin, itr)); + result.push_back(make_split_member(begin, itr)); begin = itr + 1; } } // Push final token to the end; may be empty - result.push_back(impl::member_from_range(begin, end)); + result.push_back(make_split_member(begin, end)); return result; } @@ -115,8 +113,9 @@ constexpr auto split(ItrT begin, EndT end, ElementT in_delim) { template typename ContainerT = std::vector, typename... ContainerArgsT, typename ItrT, typename EndT, typename DelimItrT, typename DelimEndT> constexpr auto split(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimEndT in_delim_end) { using ElementT = std::remove_cvref_t; - using MemberT = std::tuple_element_t<0, std::tuple>>; - using container_type = impl::split_container_helper_t; + using split_defaults_type = split_defaults; + using member_type = typename split_defaults_type::member_type; + using container_type = typename split_defaults_type::container_type; auto delim_length = std::distance(in_delim_begin, in_delim_end); if (delim_length == 1) { @@ -132,7 +131,7 @@ constexpr auto split(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimEndT i if (in_delim_begin >= in_delim_end || (end - begin) < delim_length) { // Absent or impossible to match delimiter, therefore no match, therefore return input as single token - result.push_back(impl::member_from_range(begin, end)); + result.push_back(make_split_member(begin, end)); return result; } @@ -140,7 +139,7 @@ constexpr auto split(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimEndT i for (auto itr = begin; itr < itr_end;) { if (std::equal(in_delim_begin, in_delim_end, itr)) { // Push token to result - result.push_back(impl::member_from_range(begin, itr)); + result.push_back(make_split_member(begin, itr)); itr += delim_length; begin = itr; continue; @@ -150,7 +149,7 @@ constexpr auto split(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimEndT i } // Push final token to the end; may be empty - result.push_back(impl::member_from_range(begin, end)); + result.push_back(make_split_member(begin, end)); return result; } @@ -201,14 +200,14 @@ constexpr auto split_once(ItrT begin, EndT end, ElementT in_delim) { for (auto itr = begin; itr != end; ++itr) { if (*itr == in_delim) { // in_delim found; split upon it - result.first = impl::member_from_range(begin, itr); - result.second = impl::member_from_range(itr + 1, end); + result.first = make_split_member(begin, itr); + result.second = make_split_member(itr + 1, end); return result; } } // in_delim not found - result.first = impl::member_from_range(begin, end); + result.first = make_split_member(begin, end); return result; } @@ -245,7 +244,7 @@ constexpr auto split_once(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimE if (in_delim_begin >= in_delim_end || (end - begin) < delim_length) { // Absent or impossible to match delimiter, therefore no match, therefore return input as single token - result.first = impl::member_from_range(begin, end); + result.first = make_split_member(begin, end); return result; } @@ -253,14 +252,14 @@ constexpr auto split_once(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimE for (auto itr = begin; itr < itr_end;) { if (std::equal(in_delim_begin, in_delim_end, itr)) { // in_delim found; split upon it - result.first = impl::member_from_range(begin, itr); - result.second = impl::member_from_range(itr + delim_length, end); + result.first = make_split_member(begin, itr); + result.second = make_split_member(itr + delim_length, end); return result; } } // in_delim not found - result.first = impl::member_from_range(begin, end); + result.first = make_split_member(begin, end); return result; } @@ -305,8 +304,9 @@ constexpr auto split_once(const InputT& in_string, const DelimT& in_delim) { */ template typename ContainerT = std::vector, typename... ContainerArgsT, typename ItrT, typename EndT, typename ElementT> constexpr auto split_n(ItrT begin, EndT end, ElementT in_delim, size_t in_limit) { - using MemberT = std::tuple_element_t<0, std::tuple>>; - using container_type = impl::split_container_helper_t; + using split_defaults_type = split_defaults; + using member_type = typename split_defaults_type::member_type; + using container_type = typename split_defaults_type::container_type; container_type result; if (begin >= end) { @@ -317,14 +317,14 @@ constexpr auto split_n(ItrT begin, EndT end, ElementT in_delim, size_t in_limit) for (auto itr = begin; itr != end && in_limit != 0; ++itr) { if (*itr == in_delim) { // Push token to result - result.push_back(impl::member_from_range(begin, itr)); + result.push_back(make_split_member(begin, itr)); begin = itr + 1; --in_limit; } } // Push final token to the end; may be empty - result.push_back(impl::member_from_range(begin, end)); + result.push_back(make_split_member(begin, end)); return result; } @@ -344,8 +344,9 @@ constexpr auto split_n(ItrT begin, EndT end, ElementT in_delim, size_t in_limit) template typename ContainerT = std::vector, typename... ContainerArgsT, typename ItrT, typename EndT, typename DelimItrT, typename DelimEndT> constexpr auto split_n(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimEndT in_delim_end, size_t in_limit) { using ElementT = std::remove_cvref_t; - using MemberT = std::tuple_element_t<0, std::tuple>>; - using container_type = impl::split_container_helper_t; + using split_defaults_type = split_defaults; + using member_type = typename split_defaults_type::member_type; + using container_type = typename split_defaults_type::container_type; auto delim_length = std::distance(in_delim_begin, in_delim_end); if (delim_length == 1) { @@ -361,7 +362,7 @@ constexpr auto split_n(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimEndT if (in_delim_begin >= in_delim_end || (end - begin) < delim_length) { // Absent or impossible to match delimiter, therefore no match, therefore return input as single token - result.push_back(impl::member_from_range(begin, end)); + result.push_back(make_split_member(begin, end)); return result; } @@ -369,7 +370,7 @@ constexpr auto split_n(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimEndT for (auto itr = begin; itr < itr_end && in_limit != 0;) { if (std::equal(in_delim_begin, in_delim_end, itr)) { // Push token to result - result.push_back(impl::member_from_range(begin, itr)); + result.push_back(make_split_member(begin, itr)); itr += delim_length; begin = itr; --in_limit; @@ -380,7 +381,7 @@ constexpr auto split_n(ItrT begin, EndT end, DelimItrT in_delim_begin, DelimEndT } // Push final token to the end; may be empty - result.push_back(impl::member_from_range(begin, end)); + result.push_back(make_split_member(begin, end)); return result; }