#ifndef FBASIC_PARTICLE_HPP #define FBASIC_PARTICLE_HPP #include "Utils/FIntegerSequence.hpp" #include "Utils/FPoint.hpp" #include "Utils/FTypePack.hpp" template class FBasicParticle : public scalfmm::pack_expand_tuple< scalfmm::pack<_Dim, _FReal>, Types... >{ public: /// Storage class : std::tuple using data_t = scalfmm:: pack_expand_tuple< scalfmm::pack<_Dim, _FReal>, Types... >; using types_tuple_t = scalfmm:: pack_expand_tuple< Types... >; /// Space dimensions constexpr static std::size_t Dim = _Dim; /// Size of #data_t tuple constexpr static std::size_t NbAttributes = std::tuple_size::value - Dim; /// Floating point type using FReal = _FReal; /// #data_t alias, required by the FVariadicParticleContainer using attribute_tuple_t = data_t; /// Position type, required by the FVariadicParticleContainer using position_t = FPoint; /// Default constructor FBasicParticle() = default; /// Default copy constructor FBasicParticle(const FBasicParticle&) = default; /// Default copy operator FBasicParticle& operator=(const FBasicParticle&) = default; /// Default move constructor FBasicParticle(FBasicParticle&&) = default; /// Default move operator FBasicParticle& operator=(FBasicParticle&&) = default; /// Constructor from position and types template FBasicParticle(const position_t& pos, Ts&&... ts) : FBasicParticle(std::make_index_sequence(), std::make_index_sequence::value-sizeof...(ts)-Dim>(), pos, std::forward(ts)... ) {} /// Constructor from tuple equivalent to #data_t template FBasicParticle(const std::tuple& ts) : data_t(ts) {} /** \brief Position getter * * The position is stored in the #_data tuple, to extract it we need to * recreate a position_t object. This is done by the position_impl() method. * * \return A new position_t object */ position_t position() const { return position_impl(std::make_index_sequence()); } void setPosition(const position_t& pos) { return setPosition_impl(pos, std::make_index_sequence()); } types_tuple_t attributes() const { return attributes_impl( std::make_index_sequence::value>(), types_tuple_t() ); } data_t& data() { return *this; } const data_t& data() const { return *this; } template auto get() -> decltype(std::get(this->data())) { return std::get(this->data()); } template auto get() const -> decltype(std::get(this->data())) { return std::get(this->data()); } friend bool operator==(const FBasicParticle& lhs, const FBasicParticle& rhs) { return lhs.data() == rhs.data(); } private: template FBasicParticle(std::index_sequence, std::index_sequence, const FPoint& pos, Ts&&... ts) : data_t(pos[Is]..., std::forward(ts)..., typename std::tuple_element::type(0)...) { //static_assert(sizeof...(Ts) == NbAttributes, "Parameter count is incorrect"); } template position_t position_impl(std::index_sequence) const{ return position_t(std::get(this->data())...); } template void setPosition_impl(const position_t& pos, std::index_sequence) { auto l = {std::get(this->data()) = pos[Is] ...}; (void)l; } template std::tuple attributes_impl(std::index_sequence, std::tuple) const { return std::tuple(std::get(this->data())...); } }; template auto get(FBasicParticle& particle) -> decltype(particle.template get()) { auto& res = particle.template get(); return res; } template auto get(const FBasicParticle& particle) -> decltype(particle.template get()) { return particle.template get(); } #endif /* FBASIC_PARTICLE_HPP */