86 static constexpr bool all_valid (std::initializer_list<FieldTypes> types)
89 if (t != field_type_)
return false;
93 template<
typename first_field,
typename... other_fields>
94 static constexpr bool first_field_is_coord ()
96 return first_field::coord;
99 static constexpr bool str_equ (
const char *str1,
const char *str2)
102 return *str1==*str2 && ( *str1==
'\0' || str_equ(str1+1, str2+1) );
105 template<
typename first_field>
106 static constexpr bool all_unequal ()
109 template<
typename first_field,
typename second_field,
typename... other_fields>
110 static constexpr bool all_unequal ()
112 constexpr bool first_two = !std::is_same_v<first_field,second_field>;
113 if constexpr ((bool)
sizeof...(other_fields))
115 && all_unequal<first_field, other_fields...>()
116 && all_unequal<second_field, other_fields...>();
121 template<
typename to_find,
typename first_field,
typename... other_fields>
122 static constexpr size_t find_idx (
size_t idx_of_first = 0UL)
124 if constexpr (std::is_same_v<to_find, first_field>)
128 static_assert(
sizeof...(other_fields),
129 "Requested index of field that is not contained in collection." );
130 return find_idx<to_find, other_fields...>(idx_of_first+1UL);
134 template<
typename first_field,
typename... other_fields>
135 struct extract_coord_type
137 using value_type =
typename first_field::value_type;
143 static constexpr const size_t Nfields =
sizeof...(Fields);
144 static constexpr const char *names[] = { Fields::name ... };
145 static constexpr const size_t sizes[] = { Fields::size ... };
146 static constexpr const size_t sizes_fcoord[]
147 = { Fields::size_fcoord ... };
148 static constexpr const size_t dims[] = { Fields::dim ... };
149 static constexpr const size_t strides[] = { Fields::stride ... };
150 static constexpr const size_t strides_fcoord[]
151 = { Fields::stride_fcoord ... };
154 using sim_coord_t =
typename extract_coord_type<Fields...>::value_type;
157 static constexpr const FieldTypes field_type = field_type_;
162 static constexpr size_t idx = find_idx<T, Fields...>();
164 static_assert( Nfields,
165 "empty field collection not allowed, need at least the "
166 "coordinate field" );
169 static_assert( all_valid({Fields::type...}),
170 "There is a Particle field in a Group type or vice versa." );
173 static_assert( first_field_is_coord<Fields...>(),
174 "The first field in one type is not a coordinate field.");
177 static_assert( all_unequal<Fields...>(),
178 "Duplicate field, this is likely not what you intended to do.");
183 convert_coords (
size_t Nitems,
void * &coords,
coord_t rescale=1)
185 if constexpr (!std::is_same_v<sim_coord_t, coord_t>)
187 if constexpr (
sizeof(
coord_t) <=
sizeof(sim_coord_t))
192 sim_coord_t *coords_sim_type = (sim_coord_t *)coords;
195 for (
size_t ii=0; ii != Nitems * dims[0]; ++ii)
196 coords_global_type[ii] = (
coord_t)(coords_sim_type[ii]);
199 coords = std::realloc(coords, Nitems * dims[0] *
sizeof(
coord_t));
205 coords = std::realloc(coords, Nitems * dims[0] *
sizeof(
coord_t));
209 sim_coord_t *coords_sim_type
210 = (sim_coord_t *)((
char *)coords + Nitems * dims[0]
211 * (
sizeof(
coord_t)-
sizeof(sim_coord_t)));
214 std::memmove(coords_sim_type, coords, Nitems * dims[0] *
sizeof(sim_coord_t));
217 for (
size_t ii=0; ii != Nitems * dims[0]; ++ii)
218 coords_global_type[ii] = (
coord_t)(coords_sim_type[ii]);
223 if (std::fabs(std::log(rescale)) > 1e-8) {
225 for (
size_t ii=0; ii != Nitems * dims[0]; ++ii)
253 using GroupFields = GroupFields_;
254 using ParticleFields = ParticleFields_;
257 "First template parameter for AllFields must be a GrpFields type" );
259 "Second template parameter for AllFields must be a PrtFields type" );
261 static void print_field_info ()
263 print_field_info_fct<GroupFields>(
"GroupFields");
264 print_field_info_fct<ParticleFields>(
"ParticleFields");
270 template<
typename Fields>
271 static void print_field_info_fct (
const char *FieldsName)
273 std::fprintf(stderr,
"In the FieldsCollection %s are contained :\n", FieldsName);
274 for (
size_t ii=0; ii != Fields::Nfields; ++ii)
275 std::fprintf(stderr,
"\t[%2lu] %-20s stride : %2lu byte\n",
276 ii, Fields::names[ii], Fields::strides[ii]);