Skip to content

Commit

Permalink
descartes product
Browse files Browse the repository at this point in the history
  • Loading branch information
deepgrace committed Nov 22, 2023
1 parent c37674a commit 19a1c2c
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 5 deletions.
12 changes: 12 additions & 0 deletions Guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,18 @@ using c4 = cartesian_product_t<std::integer_sequence<int, 1, 2>, std::integer_se
// c3 == std::tuple<int, char, int, float, double ,char, double, float>
// c4 == std::integer_sequence<int, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5>

// descartes product
std::vector<int> v1 { 1, 2, 3, 4 };
std::vector<float> v2 { 9.8f, 4.4f };
std::vector<std::string> v3 { "r", "g", "b" };

descartes_product([](int x, float y, const std::string& z)
{
std::cout << x << " " << y << " " << z << std::endl;
}, v1, v2, v3);

// print elements from v1 x v2 x v3

// matrix operatings
using matrix = std::tuple<std::tuple<char, int, double>,
std::tuple<char, double, int>,
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
## Overview
```cpp
#include <monster.hpp>

using namespace monster;

int main(int argc, char* argv[])
Expand Down
19 changes: 18 additions & 1 deletion Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -1564,12 +1564,20 @@ int main(int argc, char* argv[])
{
[](float i){ std::cout << "float " << i << std::endl; },
[](double d){ std::cout << "double " << d << std::endl; },
[](const auto& s){ std::cout << "string " << s << std::endl; }
[](const std::string& s){ std::cout << "string " << s << std::endl; }
};

for (auto&& v : to_range(tup))
std::visit(show, v);

std::any a = 7;

a = float(1.98);
any_visit(show, a);

a = std::string("[]<template auto ...>(){}();");
any_visit(show, a);

capture_invoke(pf)(1, 2, 3);
capture_invoke(pf, 3)(1, 2);

Expand Down Expand Up @@ -1951,6 +1959,15 @@ int main(int argc, char* argv[])
is_identical<is_subset_v<std::tuple<float, char, double>,
std::tuple<int, double, char, float, char, double, int>>>();

std::vector<int> v1 { 1, 2, 3, 4 };
std::vector<float> v2 { 9.8f, 4.4f };
std::vector<std::string> v3 { "r", "g", "b" };

descartes_product([](int x, float y, const std::string& z)
{
std::cout << x << " " << y << " " << z << std::endl;
}, v1, v2, v3);

is_identical<cartesian_product_t<std::tuple<int, double>, std::tuple<char, float>>,
std::tuple<int, char, int, float, double ,char, double, float>>();
is_identical<cartesian_product_t<std::integer_sequence<int, 1, 2>, std::integer_sequence<int, 3, 4, 5>>,
Expand Down
9 changes: 9 additions & 0 deletions example/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1957,6 +1957,15 @@ int main(int argc, char* argv[])
is_identical<is_subset_v<std::tuple<float, char, double>,
std::tuple<int, double, char, float, char, double, int>>>();

std::vector<int> v1 { 1, 2, 3, 4 };
std::vector<float> v2 { 9.8f, 4.4f };
std::vector<std::string> v3 { "r", "g", "b" };

descartes_product([](int x, float y, const std::string& z)
{
std::cout << x << " " << y << " " << z << std::endl;
}, v1, v2, v3);

is_identical<cartesian_product_t<std::tuple<int, double>, std::tuple<char, float>>,
std::tuple<int, char, int, float, double ,char, double, float>>();
is_identical<cartesian_product_t<std::integer_sequence<int, 1, 2>, std::integer_sequence<int, 3, 4, 5>>,
Expand Down
62 changes: 59 additions & 3 deletions include/monster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5500,8 +5500,13 @@ namespace monster

using F::operator()...;

consteval decltype(auto) operator()(auto) const
{
static_assert(false, "unsupported type");
}

template <typename T>
decltype(auto) operator()(std::reference_wrapper<T> r)
constexpr decltype(auto) operator()(std::reference_wrapper<T> r)
{
return (*this)(r.get());
}
Expand Down Expand Up @@ -5758,15 +5763,15 @@ namespace monster
requires std::is_aggregate_v<T>
constexpr decltype(auto) aggregate_fields_count()
{
decltype(auto) [...Args] = T();
auto [...Args] = T();

return sizeof...(Args);
}

template <typename T>
constexpr decltype(auto) aggregate_to_tuple(T&& t)
{
decltype(auto) [...Args] = t;
auto& [...Args] = t;

return std::forward_as_tuple(std::forward<decltype(Args)>(Args)...);
}
Expand Down Expand Up @@ -6793,6 +6798,16 @@ namespace monster
(integer_sequence_t<size_t, j - i, i, 1>());
}

template <typename F, typename... Args>
constexpr decltype(auto) transform_as_tuple(F&& f, const std::tuple<Args...>& t)
{
return [&]<size_t... N>(const std::index_sequence<N...>&)
{
return std::tuple<std::result_of_t<F(Args)>...>(std::forward<F>(f)(std::get<N>(t))...);
}
(std::index_sequence_for<Args...>());
}

template <typename F, typename... Args>
constexpr decltype(auto) tuple_adjacent_transform(F&& f, const std::tuple<Args...>& t)
{
Expand Down Expand Up @@ -8551,6 +8566,47 @@ namespace monster
template <typename T, typename U>
using cartesian_product_t = typeof_t<cartesian_product<T, U>>;

template <size_t N, typename... Args>
constexpr decltype(auto) next_iterator(std::tuple<Args...>& t, std::tuple<Args...>& b, std::tuple<Args...>& e)
{
auto& i = ++std::get<N>(t);

if constexpr(N != 0)
{
if (i == std::get<N>(e))
{
i = std::get<N>(b);
next_iterator<N - 1>(t, b, e);
}
}
}

template <typename F, typename... Args>
requires (sizeof...(Args) > 0)
constexpr decltype(auto) descartes_product(F&& f, Args&&... args)
{
constexpr auto N = sizeof...(Args);
auto reference = []<typename I>(I&& i) -> decltype(auto) { return *i; };

bool empty = false;
auto tuple = std::forward_as_tuple(std::forward<Args>(args)...);

tuple_for_each(tuple, [&]<typename T>(T&& t)
{
if (!empty && t.begin() == t.end())
empty = true;
});

if (!empty)
{
auto b = std::make_tuple(std::forward<Args>(args).begin()...);
auto e = std::make_tuple(std::forward<Args>(args).end()...);

for (auto t = b; std::get<0>(t) != std::get<0>(e); next_iterator<N - 1>(t, b, e))
std::apply(f, transform_as_tuple(reference, t));
}
}

template <typename T, typename U>
struct large_number_multiplier
{
Expand Down
2 changes: 1 addition & 1 deletion include/version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* time a set of code changes is merged to the master branch.
*/

#define MONSTER_VERSION_NUMBER 309
#define MONSTER_VERSION_NUMBER 310
#define MONSTER_VERSION_STRING "Monster/" MONSTER_STRINGIZE(MONSTER_VERSION_NUMBER)

#endif

0 comments on commit 19a1c2c

Please sign in to comment.