From 2e773b3849a1905afc162d91aa0cf70fe618bf92 Mon Sep 17 00:00:00 2001 From: q66 Date: Fri, 10 Feb 2017 20:26:13 +0100 Subject: [PATCH] clean up join/zip ranges with c++17 fold expressions --- README.md | 14 ++---- ostd/range.hh | 122 +++++++++----------------------------------------- 2 files changed, 26 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index a1a0990..d0e0771 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/ostd/range.hh b/ostd/range.hh index f5c5c48..2f6a972 100644 --- a/ostd/range.hh +++ b/ostd/range.hh @@ -1485,44 +1485,6 @@ public: }; namespace detail { - template - struct JoinRangeEmpty { - template - static bool empty(T const &tup) { - if (!std::get(tup).empty()) { - return false; - } - return JoinRangeEmpty::empty(tup); - } - }; - - template - struct JoinRangeEmpty { - template - static bool empty(T const &) { - return true; - } - }; - - template - struct TupleRangeEqual { - template - static bool equal(T const &tup1, T const &tup2) { - if (!std::get(tup1).equals_front(std::get(tup2))) { - return false; - } - return TupleRangeEqual::equal(tup1, tup2); - } - }; - - template - struct TupleRangeEqual { - template - static bool equal(T const &, T const &) { - return true; - } - }; - template struct JoinRangePop { template @@ -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 using ZipValue = typename detail::ZipValueType::Type; - - template - struct ZipRangeEmpty { - template - static bool empty(T const &tup) { - if (std::get(tup).empty()) { - return true; - } - return ZipRangeEmpty::empty(tup); - } - }; - - template - struct ZipRangeEmpty { - template - static bool empty(T const &) { - return false; - } - }; - - template - struct ZipRangePop { - template - static bool pop(T &tup) { - return ( - std::get(tup).pop_front() && ZipRangePop::pop(tup) - ); - } - }; - - template - struct ZipRangePop { - template - static bool pop(T &) { - return true; - } - }; - - template - struct ZipRangeFront { - template - static ZipValue tup_get(U const &tup, std::index_sequence) { - return ZipValue(std::get(tup).front()...); - } - - template - static ZipValue front(U const &tup) { - return ZipRangeFront::tup_get( - tup, std::make_index_sequence() - ); - } - }; } template @@ -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...> front() const { - return detail::ZipRangeFront...>::front(p_ranges); + return std::apply([](auto &&...args) { + return detail::ZipValue...>{args.front()...}; + }, p_ranges); } };