Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions example/view/make.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/at.hpp>
#include <boost/hana/core/make.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/view.hpp>

#include <string>
namespace hana = boost::hana;


constexpr auto tuple = hana::make_tuple(1, 2.2, '3');
constexpr auto view = hana::make_view(tuple);

// Until an algorithm is applied to the view, it is basically a reference
// to the original object, unchanged.
static_assert(hana::at_c<0>(view) == 1, "");
static_assert(hana::at_c<1>(view) == 2.2, "");
static_assert(hana::at_c<2>(view) == '3', "");

int main() { }
41 changes: 41 additions & 0 deletions example/view/view.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/assert.hpp>
#include <boost/hana/at.hpp>
#include <boost/hana/core/is_a.hpp>
#include <boost/hana/remove_if.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/view.hpp>

#include <string>
namespace hana = boost::hana;
using namespace hana::literals;


struct Fish { std::string name; };
struct Cat { std::string name; };
struct Dog { std::string name; };

int main() {
hana::tuple<Fish, Cat, Dog> animals{{"Nemo"}, {"Garfield"}, {"Snoopy"}};

// Create a view of the tuple
auto view = hana::make_view(animals);

// Apply an algorithm to the view. No work is actually done here, this
// just returns a new filtered view.
auto mammals = hana::remove_if(view, [](auto const& a) {
return hana::is_a<Fish>(a);
});

// The work is done here, when accessing the elements of the view.
BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(mammals).name == "Garfield");
BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(mammals).name == "Snoopy");

// Views have reference semantics, so we can use them to modify the
// original containers (unless the view applies a transformation).
hana::at_c<1>(mammals).name = "Beethoven";
BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(animals).name == "Beethoven");
}
1 change: 1 addition & 0 deletions include/boost/hana.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ namespace boost {
#include <boost/hana/unpack.hpp>
#include <boost/hana/value.hpp>
#include <boost/hana/version.hpp>
#include <boost/hana/view.hpp>
#include <boost/hana/while.hpp>
#include <boost/hana/zero.hpp>
#include <boost/hana/zip.hpp>
Expand Down
73 changes: 64 additions & 9 deletions include/boost/hana/cartesian_product.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,31 +59,85 @@ BOOST_HANA_NAMESPACE_BEGIN
static constexpr std::size_t length = total_length();

static constexpr auto indices_of(std::size_t i) {
constexpr std::size_t lengths[sizeof...(Lengths)] = {Lengths...};
constexpr std::size_t n = sizeof...(Lengths);
constexpr std::size_t lengths[n] = {Lengths...};
detail::array<std::size_t, n> result{};
if (length == 0) {
return result;
}
for (std::size_t j = n; j--;) {
result[j] = i % lengths[j];
i /= lengths[j];
}
return result;
}

template <typename S, std::size_t n, std::size_t ...k, typename ...Xs>
template <std::size_t n, typename F, std::size_t ...k, typename ...Xs>
static constexpr auto
product_element(std::index_sequence<k...>, Xs&& ...xs) {
product_element(std::index_sequence<k...>, F&& f, Xs&& ...xs) {
constexpr auto indices = indices_of(n);
return hana::make<S>(hana::at_c<indices[k]>(xs)...);
return static_cast<F&&>(f)(hana::at_c<indices[k]>(xs)...);
}

template <typename S, std::size_t ...n, typename ...Xs>
template <std::size_t ...n, typename F, typename ...Xs>
static constexpr auto
create_product(std::index_sequence<n...>, Xs&& ...xs) {
return hana::make<S>(product_element<S, n>(
std::make_index_sequence<sizeof...(Xs)>{}, xs...
create_product(std::index_sequence<n...>, F&& f, Xs&& ...xs) {
return F{}(product_element<n>(
std::make_index_sequence<sizeof...(Xs)>{},
static_cast<F&&>(f), xs...
)...);
}
};

template <>
struct cartesian_product_indices<> {
static constexpr std::size_t total_length()
{ return 0; }

static constexpr std::size_t length = 0;
};

struct make_cartesian_product_indices_helper_t {
template <typename ...Xs>
constexpr auto operator()(Xs&& ...xs) const
-> detail::cartesian_product_indices<
decltype(hana::length(xs))::value...
>
{ return {}; }
};

struct make_cartesian_product_indices_t {
template <typename Xs>
constexpr auto operator()(Xs&& xs) const {
return hana::unpack(
static_cast<Xs&&>(xs),
make_cartesian_product_indices_helper_t{});
}
};

constexpr make_cartesian_product_indices_t make_cartesian_product_indices{};

template <typename F, std::size_t n>
struct make_cartesian_product_element_t {
F const& f;

constexpr auto operator()() const {
return f();
}

template <typename X1, typename ...Xs>
constexpr auto operator()(X1&& x1, Xs&& ...xs) const {
constexpr auto indices = detail::cartesian_product_indices<
decltype(hana::length(x1))::value,
decltype(hana::length(xs))::value...
>{};
return indices.template product_element<n>(
std::make_index_sequence<sizeof...(Xs) + 1>{}, f,
static_cast<X1&&>(x1),
static_cast<Xs&&>(xs)...
);
}
};
}

// Credits: implementation adapted from http://github.com/alexk7/hel.
Expand All @@ -99,8 +153,9 @@ BOOST_HANA_NAMESPACE_BEGIN
using indices = detail::cartesian_product_indices<
decltype(hana::length(xs))::value...
>;
return indices::template create_product<S>(
return indices::template create_product(
std::make_index_sequence<indices::length>{},
hana::make<S>,
static_cast<Xs&&>(xs)...);
}

Expand Down
Loading