vecmem 1.14.0
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
host_traits.hpp
1/* VecMem project, part of the ACTS project (R&D line)
2 *
3 * (c) 2023 CERN for the benefit of the ACTS project
4 *
5 * Mozilla Public License Version 2.0
6 */
7#pragma once
8
9// Local include(s).
10#include "vecmem/containers/details/resize_jagged_vector.hpp"
11#include "vecmem/containers/jagged_vector.hpp"
12#include "vecmem/containers/vector.hpp"
13#include "vecmem/edm/details/schema_traits.hpp"
14#include "vecmem/edm/schema.hpp"
15#include "vecmem/memory/memory_resource.hpp"
16
17// System include(s).
18#include <stdexcept>
19#include <tuple>
20#include <type_traits>
21#include <utility>
22
23namespace vecmem::edm::details {
24
27
28template <typename TYPE>
29struct host_type;
30
31template <typename TYPE>
32struct host_type<type::scalar<TYPE>> {
33 using type = vector<TYPE>;
34 using return_type = std::add_lvalue_reference_t<TYPE>;
35 using const_return_type =
36 std::add_lvalue_reference_t<std::add_const_t<TYPE>>;
37}; // struct host_type
38
39template <typename TYPE>
40struct host_type<type::vector<TYPE>> {
41 using type = vector<TYPE>;
42 using return_type = std::add_lvalue_reference_t<type>;
43 using const_return_type =
44 std::add_lvalue_reference_t<std::add_const_t<type>>;
45}; // struct host_type
46
47template <typename TYPE>
48struct host_type<type::jagged_vector<TYPE>> {
49 using type = jagged_vector<TYPE>;
50 using return_type = std::add_lvalue_reference_t<type>;
51 using const_return_type =
52 std::add_lvalue_reference_t<std::add_const_t<type>>;
53}; // struct host_type
54
55template <std::size_t INDEX, typename... VARTYPES>
57 using type = typename host_type<typename std::tuple_element<
58 INDEX, std::tuple<VARTYPES...>>::type>::type;
59 using return_type = typename host_type<typename std::tuple_element<
60 INDEX, std::tuple<VARTYPES...>>::type>::return_type;
61 using const_return_type = typename host_type<typename std::tuple_element<
62 INDEX, std::tuple<VARTYPES...>>::type>::const_return_type;
63}; // struct host_type_at
64
66
69
70template <typename TYPE>
71struct host_alloc {
72 static typename host_type<TYPE>::type make(memory_resource& mr) {
73 return typename host_type<TYPE>::type{&mr};
74 }
75}; // struct host_alloc
76
77template <typename TYPE>
78struct host_alloc<type::scalar<TYPE>> {
79 static typename host_type<type::scalar<TYPE>>::type make(
80 memory_resource& mr) {
81 return typename host_type<type::scalar<TYPE>>::type{1, &mr};
82 }
83}; // struct host_alloc
84
86
93template <typename... VARTYPES, std::size_t INDEX, std::size_t... Is>
94std::size_t get_host_size(
95 const std::tuple<typename host_type<VARTYPES>::type...>& data,
96 std::index_sequence<INDEX, Is...>, std::size_t size = 0,
97 bool size_known = false) {
98
99 // Get the size of this variable.
100 std::size_t var_size = 0;
101 bool var_size_known = false;
102 if constexpr (type::details::is_vector<typename std::tuple_element<
103 INDEX, std::tuple<VARTYPES...>>::type>::value) {
104 var_size = std::get<INDEX>(data).size();
105 var_size_known = true;
106 } else {
107 var_size = size;
108 }
109 // Make sure that it's the same as what has been found before.
110 if (size_known && var_size_known && (var_size != size)) {
111 throw std::length_error(
112 "Inconsistent variable sizes in host container!");
113 }
114 // Terminate, or continue.
115 if constexpr (sizeof...(Is) == 0) {
116 if (!(size_known || var_size_known)) {
117 throw std::length_error(
118 "Could not determine the size of the host container?!?");
119 }
120 return var_size;
121 } else {
122 return get_host_size<VARTYPES...>(data, std::index_sequence<Is...>{},
123 var_size,
125 }
126}
127
134template <typename... VARTYPES, std::size_t INDEX, std::size_t... Is>
135void host_resize(std::tuple<typename host_type<VARTYPES>::type...>& data,
136 std::size_t size, std::index_sequence<INDEX, Is...>) {
137
138 // Resize this variable.
139 if constexpr (type::details::is_jagged_vector_v<typename std::tuple_element<
140 INDEX, std::tuple<VARTYPES...>>::type>) {
141 vecmem::details::resize_jagged_vector(std::get<INDEX>(data), size);
142 } else if constexpr (type::details::is_vector_v<typename std::tuple_element<
143 INDEX, std::tuple<VARTYPES...>>::type>) {
144 std::get<INDEX>(data).resize(size);
145 }
146 // Terminate, or continue.
147 if constexpr (sizeof...(Is) > 0) {
148 host_resize<VARTYPES...>(data, size, std::index_sequence<Is...>{});
149 }
150}
151
158template <typename... VARTYPES, std::size_t INDEX, std::size_t... Is>
159void host_reserve(std::tuple<typename host_type<VARTYPES>::type...>& data,
160 std::size_t size, std::index_sequence<INDEX, Is...>) {
161
162 // Resize this variable.
163 if constexpr (type::details::is_vector<typename std::tuple_element<
164 INDEX, std::tuple<VARTYPES...>>::type>::value) {
165 std::get<INDEX>(data).reserve(size);
166 }
167 // Terminate, or continue.
168 if constexpr (sizeof...(Is) > 0) {
169 host_reserve<VARTYPES...>(data, size, std::index_sequence<Is...>{});
170 }
171}
172
173} // namespace vecmem::edm::details
Technical base type for data<schema<VARTYPES...>>
Definition data.hpp:25
void resize_jagged_vector(std::vector< std::vector< T, ALLOC1 >, ALLOC2 > &vec, std::size_t size)
Resize a generic jagged vector.
Definition resize_jagged_vector.hpp:23
vector< vector< T > > jagged_vector
Alias type for jagged vectors with our polymorphic allocator.
Definition jagged_vector.hpp:30
std::vector< T, vecmem::polymorphic_allocator< T > > vector
Alias type for vectors with our polymorphic allocator.
Definition vector.hpp:35
Definition host_traits.hpp:71
Definition host_traits.hpp:56
Definition host_traits.hpp:29
Definition schema_traits.hpp:64