clean up join/zip ranges with c++17 fold expressions

master
Daniel Kolesa 2017-02-10 20:26:13 +01:00
parent d06637eac6
commit 2e773b3849
2 changed files with 26 additions and 110 deletions

View File

@ -8,10 +8,6 @@ make the language easier and more convenient to use.
Documentation for OctaSTD can be found at https://wiki.octaforge.org/docs/octastd.
It's not necessary that your compiler fully supports C++17, only C++14
language is used, but new C++17 containers have to be present, such as
`string_view` and `optional`.
## Supported compilers
Compiler | Version
@ -35,12 +31,10 @@ use GCC/Clang, if you need Visual Studio, LLVM integration exists.
Sadly, it's not possible to properly integrate `std::string` and `std::hash`
with OctaSTD ranges without utilizing `std::string_view`. Also, C++17 provides
library features that OctaSTD would have to implement otherwise, which would
lead to potentially incompatible APIs. However, OctaSTD does not make wide
use of C++17 language features, limiting itself mostly to library features
which have been present for more or less a pretty long time (in experimental
namespace for example) which should avoid buggy behavior. There is still the
problem of requiring a very recent toolchain, but this situation should solve
itself in near future.
lead to potentially incompatible APIs. C++17 also provides some nice language
features (such as `if constexpr` and fold epxressions) which allow a lot of
code to be written in a cleaner way. However, it is made sure that no features
beyond the minimum supported compiler are necessary to use the library.
## Supported operating systems

View File

@ -1485,44 +1485,6 @@ public:
};
namespace detail {
template<size_t I, size_t N>
struct JoinRangeEmpty {
template<typename T>
static bool empty(T const &tup) {
if (!std::get<I>(tup).empty()) {
return false;
}
return JoinRangeEmpty<I + 1, N>::empty(tup);
}
};
template<size_t N>
struct JoinRangeEmpty<N, N> {
template<typename T>
static bool empty(T const &) {
return true;
}
};
template<size_t I, size_t N>
struct TupleRangeEqual {
template<typename T>
static bool equal(T const &tup1, T const &tup2) {
if (!std::get<I>(tup1).equals_front(std::get<I>(tup2))) {
return false;
}
return TupleRangeEqual<I + 1, N>::equal(tup1, tup2);
}
};
template<size_t N>
struct TupleRangeEqual<N, N> {
template<typename T>
static bool equal(T const &, T const &) {
return true;
}
};
template<size_t I, size_t N>
struct JoinRangePop {
template<typename T>
@ -1587,13 +1549,17 @@ public:
}
bool empty() const {
return detail::JoinRangeEmpty<0, sizeof...(R)>::empty(p_ranges);
return std::apply([](auto const &...args) {
return (... && args.empty());
}, p_ranges);
}
bool equals_front(JoinRange const &r) const {
return detail::TupleRangeEqual<0, sizeof...(R)>::equal(
p_ranges, r.p_ranges
);
return std::apply([&r](auto const &...r1) {
return std::apply([&](auto const &...r2) {
return (... && r1.equals_front(r2));
}, r);
}, p_ranges);
}
bool pop_front() {
@ -1620,58 +1586,6 @@ namespace detail {
template<typename ...T>
using ZipValue = typename detail::ZipValueType<T...>::Type;
template<size_t I, size_t N>
struct ZipRangeEmpty {
template<typename T>
static bool empty(T const &tup) {
if (std::get<I>(tup).empty()) {
return true;
}
return ZipRangeEmpty<I + 1, N>::empty(tup);
}
};
template<size_t N>
struct ZipRangeEmpty<N, N> {
template<typename T>
static bool empty(T const &) {
return false;
}
};
template<size_t I, size_t N>
struct ZipRangePop {
template<typename T>
static bool pop(T &tup) {
return (
std::get<I>(tup).pop_front() && ZipRangePop<I + 1, N>::pop(tup)
);
}
};
template<size_t N>
struct ZipRangePop<N, N> {
template<typename T>
static bool pop(T &) {
return true;
}
};
template<typename ...T>
struct ZipRangeFront {
template<typename U, size_t ...I>
static ZipValue<T...> tup_get(U const &tup, std::index_sequence<I...>) {
return ZipValue<T...>(std::get<I>(tup).front()...);
}
template<typename U>
static ZipValue<T...> front(U const &tup) {
return ZipRangeFront<T...>::tup_get(
tup, std::make_index_sequence<sizeof...(T)>()
);
}
};
}
template<typename ...R>
@ -1701,21 +1615,29 @@ public:
}
bool empty() const {
return detail::ZipRangeEmpty<0, sizeof...(R)>::empty(p_ranges);
return std::apply([](auto const &...args) {
return (... || args.empty());
}, p_ranges);
}
bool equals_front(ZipRange const &r) const {
return detail::TupleRangeEqual<0, sizeof...(R)>::equal(
p_ranges, r.p_ranges
);
return std::apply([&r](auto const &...r1) {
return std::apply([&](auto const &...r2) {
return (... && r1.equals_front(r2));
}, r);
}, p_ranges);
}
bool pop_front() {
return detail::ZipRangePop<0, sizeof...(R)>::pop(p_ranges);
return std::apply([](auto &...args) {
return (... && args.pop_front());
}, p_ranges);
}
detail::ZipValue<RangeReference<R>...> front() const {
return detail::ZipRangeFront<RangeReference<R>...>::front(p_ranges);
return std::apply([](auto &&...args) {
return detail::ZipValue<RangeReference<R>...>{args.front()...};
}, p_ranges);
}
};