FVariadicParticleContainer.hpp 4.92 KB
Newer Older
1 2 3
#ifndef FVARIADICPARTICLECONTAINER_H
#define FVARIADICPARTICLECONTAINER_H

4 5 6
#include "Utils/FGlobal.hpp"

#include "Utils/FPoint.hpp"
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#include "Utils/variadic_container.hpp"
#include "Utils/FAlignedAllocator.hpp"


namespace scalfmm {
    namespace details {
        template<typename Particle, class Allocator>
        struct FVariadicParticleContainerBase {

            template<typename... Types>
            static auto getTypes(std::tuple<Types...>)
                -> variadic_vector<Allocator, Types...>;

            using type = decltype(getTypes(std::declval<typename Particle::data_t>()));
        };
    }
}


template<typename Particle, class Allocator = FAlignedAllocator<128,char> >
class FVariadicParticleContainer
    : public scalfmm::details::FVariadicParticleContainerBase<Particle, Allocator>::type
{
30
    using FBase = typename scalfmm::details::FVariadicParticleContainerBase<Particle, Allocator>::type;
31 32 33 34 35 36

public:
    using value_type = Particle;
    using position_t = typename Particle::position_t;
    using FReal = typename position_t::FReal;

37 38
    using FBase::FBase;

39 40
    /**
     * \brief Get particle count in the container
41 42 43 44 45 46 47 48
     *
     * \return Particle count
     */
    FSize getNbParticles() const {
        return FSize(FBase::size());
    }

    //DELETE
49 50
    /**
     * \brief Clears the container
51
     */
52
    [[gnu::deprecated("Use clear() method instead")]]
53 54 55 56
    void resetNumberOfParticles() {
        FBase::clear();
    }

57 58
    /**
     * \brief Push a particle in the container
59 60 61
     *
     * \param particle Particle to push
     */
62 63 64 65
    void push(const Particle& particle) {
        this->push_back(static_cast<typename Particle::data_t>(particle));
    }

66 67
    /**
     * \brief Push a particle in the container
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
     *
     * \tparam Args Parameter pack of types convertible to the Attribute type.
     *
     * \note The pack size must be at most AttributeCount, if it is less,
     * the remaining attributes are zero constructed (i.e. `Attribute(0)`
     * is called to build them).
     *
     * \param position The particle position
     * \param args The particle attributes
     */
    template<typename... Args>
    void push(const FPoint<FReal>& position, Args... args) {
        this->push(Particle(position, args...));
    }

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
    /**
     * \brief Get size to send the container
     *
     * \return The size of the serialised particle container in bytes
     *
     * \note Implementation is #getSavedSize_impl
     */
    FSize getSavedSize() const {
        return this->getSavedSize_impl(this->data());
    }
private:
    /**
     * \brief Implementation of #getSavedSize
     *
     * \tparam Types The container types
     *
     * \return The size of the serialised particle container in bytes
     */
    template<class... Types>
    FSize getSavedSize_impl(std::tuple<Types*...>) const {
        FSize tmp = sizeof(this->size());
        // Sum, for T in Types, of (sizeof(T) * this->size())
        auto l = {(tmp += sizeof(Types) * this->size(), 0)..., 0};
        (void)l;
        return tmp;
    }

public:

    /**
     * \brief Serialize particle container to buffer
     *
     * \tparam BufferWriter Buffer class
     *
     * \param buffer Buffer in which to save the container
     *
     * \note Implementation is #save_impl
     */
    template<class BufferWriter>
    void save(BufferWriter& buffer) const {
        this->save_impl(buffer, FBase::indices);
    }
private:
    /**
     * \brief Implementation of #save
     *
     * \tparam BufferWriter Buffer class
     * \tparam Is Index pack for the container types
     *
     * \note Writes #getSavedSize bytes into the buffer
     */
    template<class BufferWriter, std::size_t ... Is>
    void save_impl(BufferWriter& buffer, inria::index_sequence<Is...>) const {
        buffer << this->size();
        // For each sub-array `s`, write `s` to the buffer
        auto l = {
            (buffer.write(std::get<Is>(this->data()), this->size()),0)...,
            0};
        (void)l;
    }

public:
    /** \brief Restore container content from a buffer
     *
     * \tparam BufferReader Buffer class
     *
     * \param buffer Buffer from which to restore the buffer
     *
     * \note Implementation is #restore_impl
     */
    template<class BufferReader>
    void restore(BufferReader& buffer) {
        this->restore_impl(buffer, FBase::indices);
156
    }
157 158 159 160 161 162 163 164 165 166 167 168 169
private:
    /**
     * \brief Implementation of #restore
     *
     * \tparam BufferReader Buffer class
     * \tparam Is Index pack for the container types
     *
     * \note Reads #getSavedSize bytes from the buffer
     */
    template<class BufferReader, std::size_t ... Is>
    void restore_impl(BufferReader& buffer, inria::index_sequence<Is...>) {
        FSize particle_count = 0;
        buffer >> particle_count;
170

171
        this->resize(particle_count);
172

173 174 175 176
        auto l = {
            (buffer.fillArray(std::get<Is>(this->data()), this->size()),0)...,
            0};
        (void)l;
177
    }
178

179 180 181 182

};

#endif /* FVARIADICPARTICLECONTAINER_H */