#ifndef ITEM_VALUE_HPP #define ITEM_VALUE_HPP #include <PastisAssert.hpp> #include <Array.hpp> #include <ItemType.hpp> #include <ItemId.hpp> #include <IConnectivity.hpp> template <typename DataType, ItemType item_type> class ItemValue { public: static const ItemType item_t{item_type}; using data_type = DataType; using ItemId = ItemIdT<item_type>; using index_type = ItemId; private: bool m_is_built{false}; Array<DataType> m_values; // Allows const version to access our data friend ItemValue<std::add_const_t<DataType>, item_type>; public: PASTIS_FORCEINLINE const bool& isBuilt() const { return m_is_built; } PASTIS_INLINE size_t size() const { Assert(m_is_built); return m_values.size(); } // Following Kokkos logic, these classes are view and const view does allow // changes in data PASTIS_FORCEINLINE DataType& operator[](const ItemId& i) const { Assert(m_is_built); return m_values[i]; } template <typename IndexType> DataType& operator[](const IndexType& i) const { static_assert(std::is_same<IndexType,ItemId>(), "ItemValue must be indexed by ItemId"); return m_values[i]; } PASTIS_INLINE size_t numberOfItems() const { Assert(m_is_built); return m_values.size(); } template <typename DataType2> PASTIS_INLINE ItemValue& operator=(const ItemValue<DataType2, item_type>& value_per_item) { // ensures that DataType is the same as source DataType2 static_assert(std::is_same<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>(), "Cannot assign ItemValue of different type"); // ensures that const is not lost through copy static_assert(((std::is_const<DataType2>() and std::is_const<DataType>()) or not std::is_const<DataType2>()), "Cannot assign ItemValue of const to ItemValue of non-const"); m_values = value_per_item.m_values; m_is_built = value_per_item.m_is_built; return *this; } template <typename DataType2> PASTIS_INLINE ItemValue(const ItemValue<DataType2, item_type>& value_per_item) { this->operator=(value_per_item); } ItemValue() = default; ItemValue(const IConnectivity& connectivity) : m_is_built{true}, m_values(connectivity.numberOf<item_type>()) { static_assert(not std::is_const<DataType>(), "Cannot allocate ItemValue of const data: only view is supported"); ; } ~ItemValue() = default; }; template <typename DataType> using NodeValue = ItemValue<DataType, ItemType::node>; template <typename DataType> using EdgeValue = ItemValue<DataType, ItemType::edge>; template <typename DataType> using FaceValue = ItemValue<DataType, ItemType::face>; template <typename DataType> using CellValue = ItemValue<DataType, ItemType::cell>; #endif // ITEM_VALUE_HPP