Browse Source

Added impl::member_from_range to workaround missing library support for basic_string_view(first,last)

master
Jessica James 3 years ago
parent
commit
6ba4d916a9
  1. 37
      src/include/split.hpp
  2. 28
      src/include/type_traits.hpp

37
src/include/split.hpp

@ -20,6 +20,7 @@
#include <string_view> #include <string_view>
#include <vector> #include <vector>
#include "type_traits.hpp" // is_string_view; remove when compilers don't suck
namespace jessilib { namespace jessilib {
namespace impl { namespace impl {
@ -45,6 +46,18 @@ constexpr auto split_container_helper_f() -> ContainerT<ArgsT...> {
template<template<typename...> typename ContainerT, typename... ArgsT> template<template<typename...> typename ContainerT, typename... ArgsT>
using split_container_helper_t = decltype(split_container_helper_f<ContainerT, ArgsT...>()); using split_container_helper_t = decltype(split_container_helper_f<ContainerT, ArgsT...>());
template<typename MemberT, typename ItrT, typename EndT, typename std::enable_if<is_basic_string_view<MemberT>::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<size_t>(in_end - in_itr) };
}
template<typename MemberT, typename ItrT, typename EndT, typename std::enable_if<!is_basic_string_view<MemberT>::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 } // namespace impl
/** /**
@ -66,18 +79,18 @@ constexpr auto split(const InputT& in_string, typename InputT::value_type in_del
return result; return result;
} }
auto begin = in_string.data(); auto begin = in_string.begin();
auto end = in_string.data() + in_string.size(); auto end = in_string.end();
for (auto itr = begin; itr != end; ++itr) { for (auto itr = begin; itr != end; ++itr) {
if (*itr == in_delim) { if (*itr == in_delim) {
// Push token to result // Push token to result
result.emplace_back(begin, itr); result.push_back(impl::member_from_range<MemberT>(begin, itr));
begin = itr + 1; begin = itr + 1;
} }
} }
// Push final token to the end; may be empty // Push final token to the end; may be empty
result.emplace_back(begin, end); result.push_back(impl::member_from_range<MemberT>(begin, end));
return result; return result;
} }
@ -102,13 +115,13 @@ constexpr std::pair<ResultMemberT, ResultMemberT> split_once(const InStringT& in
return result; return result;
} }
auto begin = in_string.data(); auto begin = in_string.begin();
auto end = in_string.data() + in_string.size(); auto end = in_string.end();
for (auto itr = begin; itr != end; ++itr) { for (auto itr = begin; itr != end; ++itr) {
if (*itr == in_delim) { if (*itr == in_delim) {
// in_delim found; split upon it // in_delim found; split upon it
result.first = ResultMemberT{ begin, itr }; result.first = impl::member_from_range<ResultMemberT>(begin, itr);
result.second = ResultMemberT{ itr + 1, end }; result.second = impl::member_from_range<ResultMemberT>(itr + 1, end);
return result; return result;
} }
} }
@ -138,19 +151,19 @@ constexpr auto split_n(const InputT& in_string, typename InputT::value_type in_d
return result; return result;
} }
auto begin = in_string.data(); auto begin = in_string.begin();
auto end = in_string.data() + in_string.size(); auto end = in_string.end();
for (auto itr = begin; itr != end && in_limit != 0; ++itr) { for (auto itr = begin; itr != end && in_limit != 0; ++itr) {
if (*itr == in_delim) { if (*itr == in_delim) {
// Push token to result // Push token to result
result.emplace_back(begin, itr); result.push_back(impl::member_from_range<MemberT>(begin, itr));
begin = itr + 1; begin = itr + 1;
--in_limit; --in_limit;
} }
} }
// Push final token to the end; may be empty // Push final token to the end; may be empty
result.emplace_back(begin, end); result.push_back(impl::member_from_range<MemberT>(begin, end));
return result; return result;
} }

28
src/include/type_traits.hpp

@ -27,6 +27,8 @@
#include <unordered_set> #include <unordered_set>
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include <string>
#include <string_view>
namespace jessilib { namespace jessilib {
@ -37,6 +39,32 @@ struct remove_cvref {
typedef std::remove_cv_t<std::remove_reference_t<T>> type; typedef std::remove_cv_t<std::remove_reference_t<T>> type;
}; };
/** is_basic_string */
template<typename T>
struct is_basic_string : std::false_type {};
template<typename T>
struct is_basic_string<std::basic_string<T>> {
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<typename T>
struct is_basic_string_view : std::false_type {};
template<typename T>
struct is_basic_string_view<std::basic_string_view<T>> {
using type = T;
static constexpr bool value{ true };
constexpr operator bool() const noexcept { return true; }
constexpr bool operator()() const noexcept { return true; }
};
/** is_vector */ /** is_vector */
template<typename T> template<typename T>

Loading…
Cancel
Save