FBasicParticle.hpp 4.69 KB
Newer Older
Quentin Khan's avatar
Quentin Khan committed
1
2
3
4
5
6

#ifndef FBASIC_PARTICLE_HPP
#define FBASIC_PARTICLE_HPP

#include "Utils/FIntegerSequence.hpp"
#include "Utils/FPoint.hpp"
7
#include "Utils/FTypePack.hpp"
Quentin Khan's avatar
Quentin Khan committed
8
9
10


template<typename _FReal, std::size_t _Dim = 3, typename... Types>
11
class FBasicParticle : public scalfmm::pack_expand_tuple< scalfmm::pack<_Dim, _FReal>, Types... >{
Quentin Khan's avatar
Quentin Khan committed
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

public:
    /// Storage class : std::tuple<FReal,...(Dim times), Types...>
    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<data_t>::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<FReal, Dim>;

    /// 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<typename... Ts>
    FBasicParticle(const position_t& pos, Ts&&... ts) :
47
48
49
50
51
        FBasicParticle(std::make_index_sequence<Dim>(),
                       std::make_index_sequence<std::tuple_size<data_t>::value-sizeof...(ts)-Dim>(),
                       pos,
                       std::forward<Ts>(ts)...
            )
Quentin Khan's avatar
Quentin Khan committed
52
53
54
55
56
    {}

    /// Constructor from tuple equivalent to #data_t
    template<typename... Ts>
    FBasicParticle(const std::tuple<Ts...>& ts) :
57
        data_t(ts)
Quentin Khan's avatar
Quentin Khan committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    {}

    /** \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<Dim>());
    }

    void setPosition(const position_t& pos) {
        return setPosition_impl(pos, std::make_index_sequence<Dim>());
    }

    types_tuple_t attributes() const {
        return attributes_impl(
            std::make_index_sequence<std::tuple_size<types_tuple_t>::value>(),
            types_tuple_t()
            );
    }

    data_t& data() {
83
        return *this;
Quentin Khan's avatar
Quentin Khan committed
84
85
86
    }

    const data_t& data() const {
87
        return *this;
Quentin Khan's avatar
Quentin Khan committed
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    }

    template<std::size_t I>
    auto get() -> decltype(std::get<I>(this->data())) {
        return std::get<I>(this->data());
    }


    template<std::size_t I>
    auto get() const -> decltype(std::get<I>(this->data())) {
        return std::get<I>(this->data());
    }

    friend bool operator==(const FBasicParticle& lhs, const FBasicParticle& rhs) {
        return lhs.data() == rhs.data();
    }

private:
106
107
108
109
110
    template<typename... Ts, std::size_t... Is, std::size_t... Js>
    FBasicParticle(std::index_sequence<Is...>, std::index_sequence<Js...>,
                   const FPoint<FReal, Dim>& pos, Ts&&... ts) :
        data_t(pos[Is]..., std::forward<Ts>(ts)...,
               typename std::tuple_element<Dim+Js+sizeof...(ts), data_t>::type(0)...)
Quentin Khan's avatar
Quentin Khan committed
111
    {
112
        //static_assert(sizeof...(Ts) == NbAttributes, "Parameter count is incorrect");
Quentin Khan's avatar
Quentin Khan committed
113
    }
Quentin Khan's avatar
Quentin Khan committed
114
115
116

    template<std::size_t... Is>
    position_t position_impl(std::index_sequence<Is...>) const{
117
        return position_t(std::get<Is>(this->data())...);
Quentin Khan's avatar
Quentin Khan committed
118
119
120
    }

    template<std::size_t... Is>
121
122
    void setPosition_impl(const position_t& pos, std::index_sequence<Is...>) {
        auto l = {std::get<Is>(this->data()) = pos[Is] ...};
Quentin Khan's avatar
Quentin Khan committed
123
124
125
126
127
128
129
130
131
        (void)l;
    }


    template<std::size_t... Is, typename... Attributes>
    std::tuple<Attributes...> attributes_impl(std::index_sequence<Is...>,
                                         std::tuple<Attributes...>)
        const
    {
132
        return std::tuple<Attributes...>(std::get<Is+Dim>(this->data())...);
Quentin Khan's avatar
Quentin Khan committed
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
    }

};

template<std::size_t I, typename FReal, std::size_t Dim , typename... Types>
auto get(FBasicParticle<FReal, Dim, Types...>& particle)
    -> decltype(particle.template get<I>())
{
    auto& res = particle.template get<I>();
    return res;
}


template<std::size_t I, typename FReal, std::size_t Dim , typename... Types>
auto get(const FBasicParticle<FReal, Dim, Types...>& particle)
    -> decltype(particle.template get<I>())
{
    return particle.template get<I>();
}


#endif /* FBASIC_PARTICLE_HPP */