64#ifndef TPL_CA_MULTI_FIELD_LATTICE_H
65#define TPL_CA_MULTI_FIELD_LATTICE_H
97namespace ca_mf_detail {
100template <std::size_t...
I>
104template <std::size_t
Rank,
typename Boundary,
typename...
Fields>
105using soa_storages = std::tuple<Lattice<Dense_Cell_Storage<Fields, Rank>, Boundary>...>;
108template <
typename...
Fields>
112template <std::size_t
Rank,
typename Boundary,
typename...
Fields>
127template <
typename Layout,
typename Boundary, std::size_t
Rank,
typename...
Fields>
130 static_assert(
sizeof...(Fields) >= 1,
"Multi_Field_Lattice requires at least one field");
132 static_assert(std::is_same_v<Layout, Layout_AoS>
or std::is_same_v<Layout, Layout_SoA>,
133 "Layout must be Layout_AoS or Layout_SoA");
152 template <std::
size_t I>
169 template <std::size_t...
I>
175 template <std::size_t...
I>
177 const std::tuple<Fields...> &
init,
197 if constexpr (std::is_same_v<Layout, Layout_SoA>)
213 if constexpr (std::is_same_v<Layout, Layout_SoA>)
232 for (std::size_t d = 0; d <
Rank; ++d)
260 template <std::
size_t I>
263 static_assert(
I <
field_count,
"field index out of range");
264 if constexpr (std::is_same_v<Layout, Layout_SoA>)
265 return std::get<I>(
store_).at(c);
267 return std::get<I>(
store_.at(c));
275 template <std::
size_t I>
278 static_assert(
I <
field_count,
"field index out of range");
279 if constexpr (std::is_same_v<Layout, Layout_SoA>)
280 return std::get<I>(
store_).at_safe(c);
282 return std::get<I>(
store_.at_safe(c));
291 template <std::
size_t I,
typename V>
294 static_assert(
I <
field_count,
"field index out of range");
295 if constexpr (std::is_same_v<Layout, Layout_SoA>)
314 if constexpr (std::is_same_v<Layout, Layout_SoA>)
327 if constexpr (std::is_same_v<Layout, Layout_SoA>)
328 return at_cell_impl(c, std::index_sequence_for<Fields...>{});
348 template <std::
size_t I>
352 static_assert(
I <
field_count,
"field index out of range");
353 return std::get<I>(
store_);
360 template <std::
size_t I>
364 static_assert(
I <
field_count,
"field index out of range");
365 return std::get<I>(
store_);
377 if constexpr (std::is_same_v<Layout, Layout_SoA>)
399 template <std::
size_t I>
401 requires std::is_same_v<Layout, Layout_SoA>
403 static_assert(
I <
field_count,
"field index out of range");
410 template <std::size_t...
I>
412 const std::tuple<Fields...> &
cell,
415 ((std::get<I>(
store_).set(c, std::get<I>(
cell))), ...);
418 template <std::size_t...
I>
421 return std::tuple<
Fields...>{std::get<I>(
store_).at(c)...};
424 template <std::size_t...
I>
427 ((std::get<I>(
store_).fill(std::get<I>(
init))), ...);
432template <
typename Layout,
typename Boundary, std::size_t
Rank,
typename...
Fields>
449 typename L::coord_type;
450 typename L::extents_type;
451 { L::field_count } -> std::convertible_to<std::size_t>;
452 { L::rank } -> std::convertible_to<std::size_t>;
453}
and requires(
const L &
l, std::size_t d) {
454 {
l.dimension() } -> std::convertible_to<std::size_t>;
455 {
l.
size(d) } -> std::convertible_to<std::size_t>;
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
static int cell(const aleph_ca_engine_t *e, size_t r, size_t c)
Common typedefs and tag types for the Cellular Automata module.
Row-major dense storage for N-dimensional cellular automata.
Lattice that adds boundary-aware access on top of a storage.
Multi-field lattice with selectable storage layout.
std::tuple< Fields... > field_types
Compile-time tuple of field types.
Boundary boundary_type
Boundary policy.
ca_size_t size(const std::size_t d) const
Extent along axis d (d < Rank).
Coord_Vec< Rank > coord_type
Coordinate type.
static soa_storage_type make_soa(const extents_type &ext, ca_mf_detail::index_seq< I... >)
ca_mf_detail::soa_storages< Rank, Boundary, Fields... > soa_storage_type
void swap_field(Multi_Field_Lattice &other)
Swap a single field's buffer with another lattice.
void set_cell_impl(const coord_type &c, const std::tuple< Fields... > &cell, ca_mf_detail::index_seq< I... >)
field_type< I > at(const coord_type &c) const
Strict read access to field I.
void fill(const std::tuple< Fields... > &init)
Set every cell to the supplied per-field values.
std::tuple< Fields... > at_cell_impl(const coord_type &c, ca_mf_detail::index_seq< I... >) const
Multi_Field_Lattice(const extents_type &ext)
Build a multi-field lattice with the given extents.
field_type< I > at_safe(const coord_type &c) const
Boundary-aware read access to field I.
std::tuple_element_t< I, field_types > field_type
Field type at index I.
Multi_Field_Lattice(const extents_type &ext, const std::tuple< Fields... > &init)
Build a multi-field lattice with the given extents and per-field initial values.
const auto & field() const
Const reference to the underlying single-field lattice for field I (SoA only).
auto & field()
Mutable reference to the underlying single-field lattice for field I.
void swap(Multi_Field_Lattice &other) noexcept
O(1) swap with another lattice of the same type.
std::array< ca_size_t, Rank > extents_type
Per-axis extents type.
static constexpr std::size_t field_count
Number of fields.
static soa_storage_type make_soa_init(const extents_type &ext, const std::tuple< Fields... > &init, ca_mf_detail::index_seq< I... >)
Multi_Field_Lattice()=default
Build an empty multi-field lattice.
void set_cell(const coord_type &c, const std::tuple< Fields... > &cell)
Strict write of every field at coordinate c.
Layout layout_type
Layout tag (Layout_AoS or Layout_SoA).
ca_size_t size() const noexcept
Total cell count (product of extents).
const extents_type & extents() const noexcept
Per-axis extents.
std::tuple< Fields... > at_cell(const coord_type &c) const
Read every field at coordinate c as a tuple.
void set(const coord_type &c, const V &v)
Strict write access to field I.
static constexpr std::size_t dimension() noexcept
static constexpr std::size_t rank
Lattice dimension.
std::conditional_t< std::is_same_v< Layout, Layout_SoA >, soa_storage_type, aos_lattice_type > storage_type
void fill_impl(const std::tuple< Fields... > &init, ca_mf_detail::index_seq< I... >)
ca_mf_detail::aos_lattice< Rank, Boundary, Fields... > aos_lattice_type
size_t size() const noexcept
Count the number of elements of the list.
A type usable as the value stored inside a cell.
Concept: a lattice that exposes the multi-field interface.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
std::index_sequence< I... > index_seq
Index sequence helper.
std::tuple< Lattice< Dense_Cell_Storage< Fields, Rank >, Boundary >... > soa_storages
Per-field SoA storage tuple type.
std::tuple< Fields... > aos_cell
AoS cell type.
@ I
Infected (and infectious).
std::array< ca_index_t, N > Coord_Vec
Default coordinate vector.
void swap(Bit_Cell_Storage< N > &a, Bit_Cell_Storage< N > &b) noexcept
Free-function swap so the storage plays nicely with std::swap.
std::size_t ca_size_t
Unsigned size component used for extents and counts.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
static std::atomic< bool > init
Layout tag: each cell is a std::tuple<Fields...> inside a single contiguous storage.
Layout tag: one contiguous storage per field.
C++20 concepts for the Cellular Automata module.
Cellular automata lattice with pluggable boundary policies.
Dense, contiguous storage for cellular automata cells (1D/2D/3D).