Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

For C++17, use range-v3 instead of std::ranges #1667

Merged
merged 51 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
b148995
Integrate ranges v3 and use it for range based sorting.
joka921 Dec 6, 2024
cdf361e
All of...
joka921 Dec 6, 2024
5897af7
for_each works and we have found a fix...
joka921 Dec 6, 2024
6490a1f
std::ranges::fill
joka921 Dec 6, 2024
5cfbddc
any_of, copy
joka921 Dec 9, 2024
3cd8982
empty
joka921 Dec 9, 2024
82e0116
is_sorted
joka921 Dec 9, 2024
0f0349f
min and max
joka921 Dec 9, 2024
85c7f5b
begin
joka921 Dec 9, 2024
99bdff6
end
joka921 Dec 9, 2024
8500c4c
none_of
joka921 Dec 9, 2024
3b55963
Distance
joka921 Dec 9, 2024
65b3bcf
lexicographical_compare
joka921 Dec 9, 2024
4904241
less
joka921 Dec 9, 2024
565cb9a
equal_to
joka921 Dec 9, 2024
f44e72e
rbegin and rend
joka921 Dec 9, 2024
1b5e800
adjacent_find
joka921 Dec 9, 2024
b43a52c
move
joka921 Dec 9, 2024
d6d8293
data
joka921 Dec 9, 2024
ff88e86
size
joka921 Dec 9, 2024
8d7033a
lower_bound
joka921 Dec 9, 2024
ff5d17a
upper_bound
joka921 Dec 9, 2024
a26d26c
equal_range
joka921 Dec 9, 2024
1b3404f
subrange
joka921 Dec 9, 2024
9d143fc
unique_copy
joka921 Dec 9, 2024
8d13339
count_if
joka921 Dec 9, 2024
ec1638a
Playing around with concepts in the `Views` header.
joka921 Dec 9, 2024
c21a1d8
Address the TODOs
joka921 Dec 9, 2024
46ee644
Include a backport macro.
joka921 Dec 10, 2024
15ac111
views::transform (except for one occurence with allView etc.
joka921 Dec 10, 2024
fb895e0
views::keys
joka921 Dec 10, 2024
ab961b1
views::values
joka921 Dec 10, 2024
09829f4
views::iota
joka921 Dec 10, 2024
c03eb73
Join_view
joka921 Dec 11, 2024
a319906
comments for `chunk`
joka921 Dec 11, 2024
ae84f9e
views::drop
joka921 Dec 11, 2024
1dbe560
zip in comments.
joka921 Dec 11, 2024
ca15603
Reverse
joka921 Dec 11, 2024
ac59e36
cartesian_product (in comments)
joka921 Dec 11, 2024
b68cfba
Fix the concept..
joka921 Dec 11, 2024
669a091
The remaining place of `transform`
joka921 Dec 11, 2024
7f95d3d
Most of the `views` in the tests.
joka921 Dec 11, 2024
d5b9839
most of the `std::ranges`
joka921 Dec 11, 2024
534c76a
This works for both modes (range-v3 AND std::range)
joka921 Dec 11, 2024
0eb7ff6
Merge branch 'master' into backport-range-algorithms-c++17
joka921 Dec 12, 2024
35fbac0
Clean up and add a GitHub action.
joka921 Dec 12, 2024
a13676b
Update native-build.yml
joka921 Dec 12, 2024
69c5387
Fix the compilation.
joka921 Dec 12, 2024
14c5347
Merge remote-tracking branch 'origin/backport-range-algorithms-c++17'…
joka921 Dec 12, 2024
e17850c
Small improvements.
joka921 Dec 12, 2024
e712d6b
Merge remote-tracking branch 'origin/master' into backport-range-algo…
Dec 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/native-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ jobs:
- compiler: clang
compiler-version: 13
include:
- compiler: gcc
compiler-version: 11
additional-cmake-options: "-DUSE_CPP_17_BACKPORTS=ON"
build-type: Release
- compiler: clang
compiler-version: 16
asan-flags: "-fsanitize=address -fno-omit-frame-pointer"
Expand Down
22 changes: 21 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ FetchContent_Declare(
SOURCE_SUBDIR runtime/Cpp
)

#################################
# Range v3 (for C++-17 backwards compatibility)
################################
FetchContent_Declare(
range-v3
GIT_REPOSITORY https://github.com/joka921/range-v3
GIT_TAG 1dc0b09abab1bdc7d085a78754abd5c6e37a5d0c # 0.12.0
)



################################
# Threading
################################
Expand Down Expand Up @@ -184,6 +195,14 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
# Enable the specification of additional compiler flags manually from the commandline
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ADDITIONAL_COMPILER_FLAGS}")

# Enable the manual usage of the C++ 17 backports (currently `range-v3` instead
# of `std::ranges` and the `std::enable_if_t` based expansion of the concept
# macros from `range-v3`.
set(USE_CPP_17_BACKPORTS OFF CACHE BOOL "Use the C++17 backports (range-v3 and enable_if_t instead of std::ranges and concepts)")
if (${USE_CPP_17_BACKPORTS})
add_definitions("-DQLEVER_CPP_17 -DCPP_CXX_CONCEPTS=0")
endif()

# Enable the specification of additional linker flags manually from the commandline
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${ADDITIONAL_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${ADDITIONAL_LINKER_FLAGS}")
Expand Down Expand Up @@ -321,7 +340,7 @@ FetchContent_Declare(
################################
# Apply FetchContent
################################
FetchContent_MakeAvailable(googletest ctre abseil re2 stxxl fsst s2 nlohmann-json antlr)
FetchContent_MakeAvailable(googletest ctre abseil re2 stxxl fsst s2 nlohmann-json antlr range-v3)
# Disable some warnings in RE2, STXXL, and GTEST
target_compile_options(s2 PRIVATE -Wno-sign-compare -Wno-unused-parameter -Wno-class-memaccess -Wno-comment -Wno-redundant-move -Wno-unknown-warning-option -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-unused-but-set-variable -Wno-unused-function)
target_compile_options(re2 PRIVATE -Wno-unused-parameter)
Expand All @@ -333,6 +352,7 @@ include_directories(${ctre_SOURCE_DIR}/single-header)
target_compile_options(fsst PRIVATE -Wno-extra -Wno-all -Wno-error)
target_compile_options(fsst12 PRIVATE -Wno-extra -Wno-all -Wno-error)
include_directories(${fsst_SOURCE_DIR})
include_directories(${range-v3_SOURCE_DIR}/include)
target_compile_options(antlr4_static PRIVATE -Wno-all -Wno-extra -Wno-error -Wno-deprecated-declarations)
# Only required because a lot of classes that do not explicitly link against antlr4_static use the headers.
include_directories(SYSTEM "${antlr_SOURCE_DIR}/runtime/Cpp/runtime/src")
Expand Down
59 changes: 59 additions & 0 deletions src/backports/algorithm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2024, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Johannes Kalmbach <[email protected]>

#pragma once

#include <algorithm>
#include <functional>
#include <range/v3/all.hpp>
#include <utility>

// The following defines namespaces `ql::ranges` and `ql::views` that are almost
// drop-in replacements for `std::ranges` and `std::views`. In C++20 mode (when
// the `QLEVER_CPP_17` macro is not used), these namespaces are simply aliases
// for `std::ranges` and `std::views`. In C++17 mode they contain the ranges and
// views from Erice Niebler's `range-v3` library. NOTE: `ql::ranges::unique`
// currently doesn't work, because the interface to this function is different
// in both implementations. NOTE: There might be other caveats which we are
// currently not aware of, because they only affect functions that we currently
// don't use. For those, the following header can be expanded in the future.
#ifndef QLEVER_CPP_17
#include <concepts>
#include <ranges>
#endif

namespace ql {

namespace ranges {
#ifdef QLEVER_CPP_17
using namespace ::ranges;

// The `view` concept (which is rather important when implementing custom views)
// is in a different namespace in range-v3, so we make it manually accessible.
template <typename T>
CPP_concept view = ::ranges::cpp20::view<T>;
#else
using namespace std::ranges;
#endif
} // namespace ranges

namespace views {
#ifdef QLEVER_CPP_17
using namespace ::ranges::views;
#else
using namespace std::views;
#endif
} // namespace views

// The namespace `ql::concepts` includes concepts that are contained in the
// C++20 standard as well as in `range-v3`.
namespace concepts {
#ifdef QLEVER_CPP_17
using namespace ::concepts;
#else
using namespace std;
#endif
} // namespace concepts

} // namespace ql
17 changes: 17 additions & 0 deletions src/backports/concepts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2024, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Johannes Kalmbach <[email protected]>

#pragma once

// Define the following macros:
// `QL_OPT_CONCEPT(arg)` which expands to `arg` in C++20 mode, and to nothing in
// C++17 mode. It can be used to easily opt out of concepts that are only used
// for documentation and increased safety and not for overload resolution.
// Example usage:
// `(QL_OPT_CONCEPT(std::view) auto x = someFunction();`
#ifdef QLEVER_CPP_17
#define QL_OPT_CONCEPT(arg)
#else
#define QL_OPT_CONCEPT(arg) arg
#endif
4 changes: 2 additions & 2 deletions src/engine/AddCombinedRowToTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,8 @@ class AddCombinedRowToIdTable {
// Make sure to reset `mergedVocab_` so it is in a valid state again.
mergedVocab_ = LocalVocab{};
// Only merge non-null vocabs.
auto range = currentVocabs_ | std::views::filter(toBool) |
std::views::transform(dereference);
auto range = currentVocabs_ | ql::views::filter(toBool) |
ql::views::transform(dereference);
mergedVocab_.mergeWith(std::ranges::ref_view{range});
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/engine/Bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ IdTable Bind::cloneSubView(const IdTable& idTable,
const std::pair<size_t, size_t>& subrange) {
IdTable result(idTable.numColumns(), idTable.getAllocator());
result.resize(subrange.second - subrange.first);
std::ranges::copy(idTable.begin() + subrange.first,
idTable.begin() + subrange.second, result.begin());
ql::ranges::copy(idTable.begin() + subrange.first,
idTable.begin() + subrange.second, result.begin());
return result;
}

Expand Down
4 changes: 2 additions & 2 deletions src/engine/CallFixedSize.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ template <int maxValue, size_t NumValues, std::integral Int>
auto callLambdaForIntArray(std::array<Int, NumValues> array, auto&& lambda,
auto&&... args) {
AD_CONTRACT_CHECK(
std::ranges::all_of(array, [](auto el) { return el <= maxValue; }));
ql::ranges::all_of(array, [](auto el) { return el <= maxValue; }));
using ArrayType = std::array<Int, NumValues>;

// Call the `lambda` when the correct compile-time `Int`s are given as a
Expand Down Expand Up @@ -131,7 +131,7 @@ decltype(auto) callFixedSize(std::array<Int, NumIntegers> ints, auto&& functor,
static_assert(NumIntegers > 0);
// TODO<joka921, C++23> Use `std::bind_back`
auto p = [](int i) { return detail::mapToZeroIfTooLarge(i, MaxValue); };
std::ranges::transform(ints, ints.begin(), p);
ql::ranges::transform(ints, ints.begin(), p);

// The only step that remains is to lift our single runtime `value` which
// is in the range `[0, (MaxValue +1)^ NumIntegers]` to a compile-time
Expand Down
41 changes: 20 additions & 21 deletions src/engine/CartesianProductJoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ CartesianProductJoin::CartesianProductJoin(
children_{std::move(children)},
chunkSize_{chunkSize} {
AD_CONTRACT_CHECK(!children_.empty());
AD_CONTRACT_CHECK(std::ranges::all_of(
AD_CONTRACT_CHECK(ql::ranges::all_of(
children_, [](auto& child) { return child != nullptr; }));

// Check that the variables of the passed in operations are in fact
Expand All @@ -25,22 +25,22 @@ CartesianProductJoin::CartesianProductJoin(
// false as soon as a duplicate is encountered.
ad_utility::HashSet<Variable> vars;
auto checkVarsForOp = [&vars](const Operation& op) {
return std::ranges::all_of(
op.getExternallyVisibleVariableColumns() | std::views::keys,
return ql::ranges::all_of(
op.getExternallyVisibleVariableColumns() | ql::views::keys,
[&vars](const Variable& variable) {
return vars.insert(variable).second;
});
};
return std::ranges::all_of(childView(), checkVarsForOp);
return ql::ranges::all_of(childView(), checkVarsForOp);
}();
AD_CONTRACT_CHECK(variablesAreDisjoint);
}

// ____________________________________________________________________________
std::vector<QueryExecutionTree*> CartesianProductJoin::getChildren() {
std::vector<QueryExecutionTree*> result;
std::ranges::copy(
children_ | std::views::transform([](auto& ptr) { return ptr.get(); }),
ql::ranges::copy(
children_ | ql::views::transform([](auto& ptr) { return ptr.get(); }),
std::back_inserter(result));
return result;
}
Expand All @@ -49,28 +49,28 @@ std::vector<QueryExecutionTree*> CartesianProductJoin::getChildren() {
string CartesianProductJoin::getCacheKeyImpl() const {
return "CARTESIAN PRODUCT JOIN " +
ad_utility::lazyStrJoin(
std::views::transform(
ql::views::transform(
childView(), [](auto& child) { return child.getCacheKey(); }),
" ");
}

// ____________________________________________________________________________
size_t CartesianProductJoin::getResultWidth() const {
auto view = childView() | std::views::transform(&Operation::getResultWidth);
auto view = childView() | ql::views::transform(&Operation::getResultWidth);
return std::reduce(view.begin(), view.end(), 0UL, std::plus{});
}

// ____________________________________________________________________________
size_t CartesianProductJoin::getCostEstimate() {
auto childSizes =
childView() | std::views::transform(&Operation::getCostEstimate);
childView() | ql::views::transform(&Operation::getCostEstimate);
return getSizeEstimate() +
std::reduce(childSizes.begin(), childSizes.end(), 0UL, std::plus{});
}

// ____________________________________________________________________________
uint64_t CartesianProductJoin::getSizeEstimateBeforeLimit() {
auto view = childView() | std::views::transform(&Operation::getSizeEstimate);
auto view = childView() | ql::views::transform(&Operation::getSizeEstimate);
return std::reduce(view.begin(), view.end(), 1UL, std::multiplies{});
}

Expand All @@ -86,7 +86,7 @@ float CartesianProductJoin::getMultiplicity([[maybe_unused]] size_t col) {
bool CartesianProductJoin::knownEmptyResult() {
// If children were empty, returning false would be the wrong behavior.
AD_CORRECTNESS_CHECK(!children_.empty());
return std::ranges::any_of(childView(), &Operation::knownEmptyResult);
return ql::ranges::any_of(childView(), &Operation::knownEmptyResult);
}

// ____________________________________________________________________________
Expand Down Expand Up @@ -138,16 +138,15 @@ ProtoResult CartesianProductJoin::computeResult(bool requestLaziness) {
LocalVocab staticMergedVocab{};
staticMergedVocab.mergeWith(
subResults |
std::views::transform([](const auto& result) -> const LocalVocab& {
ql::views::transform([](const auto& result) -> const LocalVocab& {
return result->localVocab();
}));

if (!requestLaziness) {
AD_CORRECTNESS_CHECK(!lazyResult);
return {
writeAllColumns(subResults | std::views::transform(&Result::idTable),
getLimit()._offset, getLimit().limitOrDefault()),
resultSortedOn(), std::move(staticMergedVocab)};
return {writeAllColumns(subResults | ql::views::transform(&Result::idTable),
getLimit()._offset, getLimit().limitOrDefault()),
resultSortedOn(), std::move(staticMergedVocab)};
}

if (lazyResult) {
Expand All @@ -159,7 +158,7 @@ ProtoResult CartesianProductJoin::computeResult(bool requestLaziness) {
// Owning view wrapper to please gcc 11.
return {produceTablesLazily(std::move(staticMergedVocab),
ad_utility::OwningView{std::move(subResults)} |
std::views::transform(&Result::idTable),
ql::views::transform(&Result::idTable),
getLimit()._offset, getLimit().limitOrDefault()),
resultSortedOn()};
}
Expand Down Expand Up @@ -192,11 +191,11 @@ IdTable CartesianProductJoin::writeAllColumns(
// single result is left. This can probably be done by using the
// `ProtoResult`.

auto sizesView = std::views::transform(idTables, &IdTable::size);
auto sizesView = ql::views::transform(idTables, &IdTable::size);
auto totalResultSize =
std::reduce(sizesView.begin(), sizesView.end(), 1UL, std::multiplies{});

if (!std::ranges::empty(idTables) && sizesView.back() != 0) {
if (!ql::ranges::empty(idTables) && sizesView.back() != 0) {
totalResultSize += (totalResultSize / sizesView.back()) * lastTableOffset;
} else {
AD_CORRECTNESS_CHECK(lastTableOffset == 0);
Expand Down Expand Up @@ -254,7 +253,7 @@ CartesianProductJoin::calculateSubResults(bool requestLaziness) {

std::shared_ptr<const Result> lazyResult = nullptr;
auto children = childView();
AD_CORRECTNESS_CHECK(!std::ranges::empty(children));
AD_CORRECTNESS_CHECK(!ql::ranges::empty(children));
// Get all child results (possibly with limit, see above).
for (Operation& child : children) {
if (limitIfPresent.has_value() && child.supportsLimit()) {
Expand Down Expand Up @@ -346,7 +345,7 @@ Result::Generator CartesianProductJoin::createLazyConsumer(
size_t producedTableSize = 0;
for (auto& idTableAndVocab : produceTablesLazily(
std::move(localVocab),
std::views::transform(
ql::views::transform(
idTables,
[](const auto& wrapper) -> const IdTable& { return wrapper; }),
offset, limit, lastTableOffset)) {
Expand Down
9 changes: 4 additions & 5 deletions src/engine/CartesianProductJoin.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ class CartesianProductJoin : public Operation {
// TODO<joka921> We can move this whole children management into a base class
// and clean up the implementation of several other children.
auto childView() {
return std::views::transform(children_, [](auto& child) -> Operation& {
return ql::views::transform(children_, [](auto& child) -> Operation& {
return *child->getRootOperation();
});
}
auto childView() const {
return std::views::transform(children_,
[](auto& child) -> const Operation& {
return *child->getRootOperation();
});
return ql::views::transform(children_, [](auto& child) -> const Operation& {
return *child->getRootOperation();
});
}

public:
Expand Down
Loading
Loading