Select Git revision
ItemArray.hpp
Stéphane Del Pino authored
ItemArray.hpp 7.27 KiB
#ifndef ITEM_ARRAY_HPP
#define ITEM_ARRAY_HPP
#include <mesh/IConnectivity.hpp>
#include <mesh/ItemId.hpp>
#include <mesh/ItemType.hpp>
#include <utils/PugsAssert.hpp>
#include <utils/Table.hpp>
#include <memory>
template <typename DataType, ItemType item_type, typename ConnectivityPtr = std::shared_ptr<const IConnectivity>>
class ItemArray
{
public:
static constexpr ItemType item_t{item_type};
using data_type = DataType;
using ItemId = ItemIdT<item_type>;
using index_type = ItemId;
private:
using ConnectivitySharedPtr = std::shared_ptr<const IConnectivity>;
using ConnectivityWeakPtr = std::weak_ptr<const IConnectivity>;
static_assert(std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr> or
std::is_same_v<ConnectivityPtr, ConnectivityWeakPtr>);
ConnectivityPtr m_connectivity_ptr;
Table<DataType> m_values;
// Allow const std:shared_ptr version to access our data
friend ItemArray<std::add_const_t<DataType>, item_type, ConnectivitySharedPtr>;
// Allow const std:weak_ptr version to access our data
friend ItemArray<std::add_const_t<DataType>, item_type, ConnectivityWeakPtr>;
// Allow non-const std:shared_ptr version to access our data
friend ItemArray<std::remove_const_t<DataType>, item_type, ConnectivitySharedPtr>;
// Allow non-const std:weak_ptr version to access our data
friend ItemArray<std::remove_const_t<DataType>, item_type, ConnectivityWeakPtr>;
public:
friend PUGS_INLINE ItemArray<std::remove_const_t<DataType>, item_type, ConnectivityPtr>
copy(const ItemArray<DataType, item_type, ConnectivityPtr>& source)
{
ItemArray<std::remove_const_t<DataType>, item_type, ConnectivityPtr> image;
image.m_connectivity_ptr = source.m_connectivity_ptr;
image.m_values = copy(source.m_values);
return image;
}
template <typename ConnectivityPtr2>
friend PUGS_INLINE void copy_to(const ItemArray<std::add_const_t<DataType>, item_type, ConnectivityPtr>& source,
const ItemArray<DataType, item_type, ConnectivityPtr2>& destination);
template <typename ConnectivityPtr2>
friend PUGS_INLINE void
copy_to(const ItemArray<DataType, item_type, ConnectivityPtr>& source,
const ItemArray<std::remove_const_t<DataType>, item_type, ConnectivityPtr2>& destination)
{
Assert(destination.connectivity_ptr() == source.connectivity_ptr());
copy_to(source.m_values, destination.m_values);
}
PUGS_INLINE
bool
isBuilt() const noexcept
{
return m_connectivity_ptr.use_count() != 0;
}
PUGS_INLINE
std::shared_ptr<const IConnectivity>
connectivity_ptr() const noexcept
{
if constexpr (std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr>) {
return m_connectivity_ptr;
} else {
return m_connectivity_ptr.lock();
}
}
PUGS_INLINE
void
fill(const DataType& data) const noexcept
{
static_assert(not std::is_const_v<DataType>, "Cannot modify ItemArray of const");
m_values.fill(data);
}
// Following Kokkos logic, these classes are view and const view does allow
// changes in data
PUGS_FORCEINLINE
Array<DataType>
operator[](const ItemId& i) const noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
Assert(i < this->numberOfItems());
return m_values[i];
}
template <typename IndexType>
Array<DataType>
operator[](const IndexType&) const noexcept(NO_ASSERT)
{
static_assert(std::is_same_v<IndexType, ItemId>, "ItemArray must be indexed by ItemId");
}
PUGS_INLINE
size_t
numberOfItems() const noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
return m_values.numberOfRows();
}
PUGS_INLINE
size_t
sizeOfArrays() const
{
Assert(this->isBuilt());
return m_values.numberOfColumns();
}
template <typename DataType2>
PUGS_INLINE ItemArray&
operator=(const Table<DataType2>& table) noexcept(NO_ASSERT)
{
// ensures that DataType is the same as source DataType2
static_assert(std::is_same_v<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>,
"Cannot assign ItemArray of different type");
// ensures that const is not lost through copy
static_assert(((std::is_const_v<DataType2> and std::is_const_v<DataType>) or not std::is_const_v<DataType2>),
"Cannot assign ItemArray of const to ItemArray of non-const");
Assert((table.numberOfRows() * table.numberOfColumns() == 0) or this->isBuilt(),
"Cannot assign array of arrays to a non-built ItemArray\n");
Assert(this->numberOfItems() == table.numberOfRows(), "Cannot assign a table of a different dimensions\n");
Assert(this->sizeOfArrays() == table.numberOfColumns(), "Cannot assign a table of a different dimensions\n");
m_values = table;
return *this;
}
template <typename DataType2, typename ConnectivityPtr2>
PUGS_INLINE ItemArray&
operator=(const ItemArray<DataType2, item_type, ConnectivityPtr2>& array_per_item) noexcept
{
// ensures that DataType is the same as source DataType2
static_assert(std::is_same_v<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>,
"Cannot assign ItemArray of different type");
// ensures that const is not lost through copy
static_assert(((std::is_const_v<DataType2> and std::is_const_v<DataType>) or not std::is_const_v<DataType2>),
"Cannot assign ItemArray of const to ItemArray of non-const");
m_values = array_per_item.m_values;
if constexpr (std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr> and
std::is_same_v<ConnectivityPtr2, ConnectivityWeakPtr>) {
m_connectivity_ptr = array_per_item.m_connectivity_ptr.lock();
} else {
m_connectivity_ptr = array_per_item.m_connectivity_ptr;
}
return *this;
}
template <typename DataType2, typename ConnectivityPtr2>
PUGS_INLINE
ItemArray(const ItemArray<DataType2, item_type, ConnectivityPtr2>& array_per_item) noexcept
{
this->operator=(array_per_item);
}
PUGS_INLINE
ItemArray() = default;
PUGS_INLINE
ItemArray(const IConnectivity& connectivity, size_t size_of_array) noexcept
: m_connectivity_ptr{connectivity.shared_ptr()}, m_values{connectivity.numberOf<item_type>(), size_of_array}
{
static_assert(not std::is_const_v<DataType>, "Cannot allocate ItemArray of const data: only view is "
"supported");
}
PUGS_INLINE
~ItemArray() = default;
};
template <typename DataType>
using NodeArray = ItemArray<DataType, ItemType::node>;
template <typename DataType>
using EdgeArray = ItemArray<DataType, ItemType::edge>;
template <typename DataType>
using FaceArray = ItemArray<DataType, ItemType::face>;
template <typename DataType>
using CellArray = ItemArray<DataType, ItemType::cell>;
// Weak versions: should not be used outside of Connectivity
template <typename DataType, ItemType item_type>
using WeakItemArray = ItemArray<DataType, item_type, std::weak_ptr<const IConnectivity>>;
template <typename DataType>
using WeakNodeArray = WeakItemArray<DataType, ItemType::node>;
template <typename DataType>
using WeakEdgeArray = WeakItemArray<DataType, ItemType::edge>;
template <typename DataType>
using WeakFaceArray = WeakItemArray<DataType, ItemType::face>;
template <typename DataType>
using WeakCellArray = WeakItemArray<DataType, ItemType::cell>;
#endif // ITEM_ARRAY_HPP